/**************************************************************
 * 
 * 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_sd.hxx"

#include "DrawDocShell.hxx"
#include <tools/pstm.hxx>
#include <vcl/svapp.hxx>

#include <sfx2/docfac.hxx>
#include <sfx2/objface.hxx>

#ifndef _SVXIDS_HRC
#include <svx/svxids.hrc>
#endif
#include <svl/srchitem.hxx>
#include <svx/srchdlg.hxx>
#include <editeng/flstitem.hxx>
#include <svl/eitem.hxx>
#include <svl/intitem.hxx>
#include <sfx2/printer.hxx>
#ifndef _SFX_DOCFILE_HXX //autogen
#include <sfx2/docfile.hxx>
#endif
#include <svx/drawitem.hxx>
#include <editeng/flstitem.hxx>
#include <svx/drawitem.hxx>
#include <svx/srchdlg.hxx>
#include <sfx2/dispatch.hxx>
#include <svl/whiter.hxx>
#include <svl/itempool.hxx>
#include <svtools/ctrltool.hxx>
#include <svtools/filter.hxx>
#ifndef _SO_CLSIDS_HXX
#include <sot/clsids.hxx>
#endif
#include <svl/cjkoptions.hxx>
#include <svl/visitem.hxx>

#include <svx/svdoutl.hxx>

#include <sfx2/fcontnr.hxx>

#include "app.hrc"
#include "app.hxx"
#include "strmname.h"
#include "stlpool.hxx"
#include "strings.hrc"
#include "View.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include "glob.hrc"
#include "res_bmp.hrc"
#include "fupoor.hxx"
#include "fusearch.hxx"
#include "ViewShell.hxx"
#include "sdresid.hxx"
#ifndef SD_FU_SLIDE_SHOW_DLG_HXX
#include "slideshow.hxx"
#endif
#include "drawview.hxx"
#ifndef SD_FRAMW_VIEW_HXX
#include "FrameView.hxx"
#endif
#include "unomodel.hxx"
#include "undo/undomanager.hxx"
#include "undo/undofactory.hxx"
#include "OutlineView.hxx"
#include "ViewShellBase.hxx"

using namespace sd;
#define DrawDocShell
#include "sdslots.hxx"

SFX_IMPL_INTERFACE(DrawDocShell, SfxObjectShell, SdResId(0))
{
	SFX_CHILDWINDOW_REGISTRATION(SvxSearchDialogWrapper::GetChildWindowId());
        SFX_CHILDWINDOW_REGISTRATION(SID_HYPERLINK_INSERT);
}


namespace sd {

#define POOL_BUFFER_SIZE				(sal_uInt16)32768
#define BASIC_BUFFER_SIZE				(sal_uInt16)8192
#define DOCUMENT_BUFFER_SIZE            (sal_uInt16)32768


GraphicFilter* GetGrfFilter();

/*************************************************************************
|*
|* SFX-Slotmaps und -Definitionen
|*
\************************************************************************/
TYPEINIT1( DrawDocShell, SfxObjectShell );

SFX_IMPL_OBJECTFACTORY(
    DrawDocShell,
    SvGlobalName(SO3_SIMPRESS_CLASSID),
    SFXOBJECTSHELL_STD_NORMAL,
    "simpress" )

/*************************************************************************
|*
|* Construct
|*
\************************************************************************/

void DrawDocShell::Construct( bool bClipboard )
{
	mbInDestruction = sal_False;
	SetSlotFilter();     // setzt Filter zurueck

	mbOwnDocument = mpDoc == 0;
	if( mbOwnDocument )
		mpDoc = new SdDrawDocument(meDocType, this);

    // The document has been created so we can call UpdateRefDevice() to set
    // the document's ref device.
    UpdateRefDevice();

	SetBaseModel( new SdXImpressDocument( this, bClipboard ) );
	SetPool( &mpDoc->GetItemPool() );
	mpUndoManager = new sd::UndoManager;
	mpDoc->SetSdrUndoManager( mpUndoManager );
	mpDoc->SetSdrUndoFactory( new sd::UndoFactory );
	UpdateTablePointers();
	SetStyleFamily(5);       //CL: eigentlich SFX_STYLE_FAMILY_PSEUDO
}

/*************************************************************************
|*
|* Konstruktor 1
|*
\************************************************************************/

DrawDocShell::DrawDocShell(SfxObjectCreateMode eMode,
							   sal_Bool bDataObject,
							   DocumentType eDocumentType) :
    SfxObjectShell( eMode == SFX_CREATE_MODE_INTERNAL ?  SFX_CREATE_MODE_EMBEDDED : eMode),
	mpDoc(NULL),
	mpUndoManager(NULL),
	mpPrinter(NULL),
	mpViewShell(NULL),
	mpFontList(NULL),
	meDocType(eDocumentType),
	mpFilterSIDs(0),
	mbSdDataObj(bDataObject),
	mbOwnPrinter(sal_False),
    mbNewDocument( sal_True )
{
	Construct( eMode == SFX_CREATE_MODE_INTERNAL );
}

/*************************************************************************
|*
|* Konstruktor 2
|*
\************************************************************************/

DrawDocShell::DrawDocShell( const sal_uInt64 nModelCreationFlags, sal_Bool bDataObject, DocumentType eDocumentType ) :
    SfxObjectShell( nModelCreationFlags ),
	mpDoc(NULL),
	mpUndoManager(NULL),
	mpPrinter(NULL),
	mpViewShell(NULL),
	mpFontList(NULL),
	meDocType(eDocumentType),
	mpFilterSIDs(0),
	mbSdDataObj(bDataObject),
	mbOwnPrinter(sal_False),
    mbNewDocument( sal_True )
{
	Construct( sal_False );
}

/*************************************************************************
|*
|* Konstruktor 3
|*
\************************************************************************/

DrawDocShell::DrawDocShell(SdDrawDocument* pDoc, SfxObjectCreateMode eMode,
							   sal_Bool bDataObject,
							   DocumentType eDocumentType) :
	SfxObjectShell(eMode == SFX_CREATE_MODE_INTERNAL ?  SFX_CREATE_MODE_EMBEDDED : eMode),
	mpDoc(pDoc),
	mpUndoManager(NULL),
	mpPrinter(NULL),
	mpViewShell(NULL),
	mpFontList(NULL),
	meDocType(eDocumentType),
	mpFilterSIDs(0),
	mbSdDataObj(bDataObject),
	mbOwnPrinter(sal_False),
    mbNewDocument( sal_True )
{
	Construct( eMode == SFX_CREATE_MODE_INTERNAL );
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

DrawDocShell::~DrawDocShell()
{
    // Tell all listeners that the doc shell is about to be
    // destroyed.  This has been introduced for the PreviewRenderer to
    // free its view (that uses the item poll of the doc shell) but
    // may be useful in other places as well.
	Broadcast(SfxSimpleHint(SFX_HINT_DYING));

	mbInDestruction = sal_True;

	SetDocShellFunction(0);

	delete mpFontList;

	if( mpDoc )
		mpDoc->SetSdrUndoManager( 0 );
	delete mpUndoManager;

	if (mbOwnPrinter)
		delete mpPrinter;

	if( mbOwnDocument )
		delete mpDoc;

	// damit der Navigator das Verschwinden des Dokuments mitbekommt
	SfxBoolItem		aItem(SID_NAVIGATOR_INIT, sal_True);
	SfxViewFrame*	pFrame = mpViewShell ? mpViewShell->GetFrame() : GetFrame();

	if( !pFrame )
		pFrame = SfxViewFrame::GetFirst( this );

	if( pFrame )
		pFrame->GetDispatcher()->Execute(
			SID_NAVIGATOR_INIT, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L);
}

/*************************************************************************
|*
|* Slot-Stati setzen
|*
\************************************************************************/

void DrawDocShell::GetState(SfxItemSet &rSet)
{

	SfxWhichIter aIter( rSet );
	sal_uInt16 nWhich = aIter.FirstWhich();

	while ( nWhich )
	{
		sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich)
			? GetPool().GetSlotId(nWhich)
			: nWhich;

		switch ( nSlotId )
		{
			case SID_SEARCH_ITEM:
			{
				rSet.Put( *SD_MOD()->GetSearchItem() );
			}
			break;

			case SID_CLOSEDOC:
			{
				sal_Bool bDisabled = sal_False;
				if (bDisabled)
				{
					rSet.DisableItem(SID_CLOSEDOC);
				}
				else
				{
					GetSlotState(SID_CLOSEDOC, SfxObjectShell::GetInterface(), &rSet);
				}
			}
			break;

			case SID_SEARCH_OPTIONS:
			{
				sal_uInt16 nOpt = SEARCH_OPTIONS_SEARCH 	 |
							  SEARCH_OPTIONS_WHOLE_WORDS |
							  SEARCH_OPTIONS_BACKWARDS	 |
							  SEARCH_OPTIONS_REG_EXP	 |
							  SEARCH_OPTIONS_EXACT		 |
							  SEARCH_OPTIONS_SIMILARITY  |
							  SEARCH_OPTIONS_SELECTION;

				if (!IsReadOnly())
				{
					nOpt |= SEARCH_OPTIONS_REPLACE;
					nOpt |= SEARCH_OPTIONS_REPLACE_ALL;
				}

				rSet.Put(SfxUInt16Item(nWhich, nOpt));
			}
			break;

			case SID_VERSION:
			{
				GetSlotState( SID_VERSION, SfxObjectShell::GetInterface(), &rSet );
			}
			break;

            case SID_CHINESE_CONVERSION:
			case SID_HANGUL_HANJA_CONVERSION:
			{
                rSet.Put(SfxVisibilityItem(nWhich, SvtCJKOptions().IsAnyEnabled()));
			}
			break;

			default:
			break;
		}
		nWhich = aIter.NextWhich();
	}

    SfxViewFrame* pFrame = SfxViewFrame::Current();

	if (pFrame)
	{
		if (rSet.GetItemState(SID_RELOAD) != SFX_ITEM_UNKNOWN)
		{
			pFrame->GetSlotState(SID_RELOAD,
								 pFrame->GetInterface(), &rSet);
		}
	}
}

void DrawDocShell::InPlaceActivate( sal_Bool bActive )
{
	if( !bActive )
	{
		FrameView* pFrameView = NULL;
		List* pFrameViewList = mpDoc->GetFrameViewList();

		DBG_ASSERT( pFrameViewList, "No FrameViewList?" );
		if( pFrameViewList )
		{
			sal_uInt32 i;
			for ( i = 0; i < pFrameViewList->Count(); i++)
			{
				// Ggf. FrameViews loeschen
				pFrameView = (FrameView*) pFrameViewList->GetObject(i);

				if (pFrameView)
					delete pFrameView;
			}

			pFrameViewList->Clear();

			ViewShell* pViewSh = NULL;
			SfxViewShell* pSfxViewSh = NULL;
			SfxViewFrame* pSfxViewFrame = SfxViewFrame::GetFirst(this, false);

			while (pSfxViewFrame)
			{
				// Anzahl FrameViews ermitteln
				pSfxViewSh = pSfxViewFrame->GetViewShell();
				pViewSh = PTR_CAST( ViewShell, pSfxViewSh );

				if ( pViewSh && pViewSh->GetFrameView() )
				{
					pViewSh->WriteFrameViewData();
					pFrameViewList->Insert( new FrameView( mpDoc, pViewSh->GetFrameView() ) );
				}

				pSfxViewFrame = SfxViewFrame::GetNext(*pSfxViewFrame, this, false);
			}
		}
	}

    SfxObjectShell::InPlaceActivate( bActive );

	if( bActive )
	{
		List* pFrameViewList = mpDoc->GetFrameViewList();

		DBG_ASSERT( pFrameViewList, "No FrameViewList?" );
		if( pFrameViewList )
		{
			ViewShell* pViewSh = NULL;
			SfxViewShell* pSfxViewSh = NULL;
			SfxViewFrame* pSfxViewFrame = SfxViewFrame::GetFirst(this, false);

			sal_uInt32 i;
			for( i = 0; pSfxViewFrame && (i < pFrameViewList->Count()); i++ )
			{
				// Anzahl FrameViews ermitteln
				pSfxViewSh = pSfxViewFrame->GetViewShell();
				pViewSh = PTR_CAST( ViewShell, pSfxViewSh );

				if ( pViewSh )
				{
					pViewSh->ReadFrameViewData( (FrameView*)pFrameViewList->GetObject(i) );
				}

				pSfxViewFrame = SfxViewFrame::GetNext(*pSfxViewFrame, this, false);
			}
		}
	}
}

/*************************************************************************
|*
|* SFX-Aktivierung
|*
\************************************************************************/

void DrawDocShell::Activate( sal_Bool bMDI)
{
	if (bMDI)
	{
		ApplySlotFilter();
		mpDoc->StartOnlineSpelling();
	}
}

/*************************************************************************
|*
|* SFX-Deaktivierung
|*
\************************************************************************/

void DrawDocShell::Deactivate( sal_Bool )
{
}

/*************************************************************************
|*
|* SFX-Undomanager zurueckgeben
|*
\************************************************************************/

::svl::IUndoManager* DrawDocShell::GetUndoManager()
{
	return mpUndoManager;
}



/*************************************************************************
|*
|* Tabellenzeiger auffrischen
|*
\************************************************************************/

void DrawDocShell::UpdateTablePointers()
{
    PutItem( SvxColorTableItem( mpDoc->GetColorTableFromSdrModel(), SID_COLOR_TABLE ) );
    PutItem( SvxGradientListItem( mpDoc->GetGradientListFromSdrModel(), SID_GRADIENT_LIST ) );
    PutItem( SvxHatchListItem( mpDoc->GetHatchListFromSdrModel(), SID_HATCH_LIST ) );
    PutItem( SvxBitmapListItem( mpDoc->GetBitmapListFromSdrModel(), SID_BITMAP_LIST ) );
    PutItem( SvxDashListItem( mpDoc->GetDashListFromSdrModel(), SID_DASH_LIST ) );
    PutItem( SvxLineEndListItem( mpDoc->GetLineEndListFromSdrModel(), SID_LINEEND_LIST ) );

	UpdateFontList();
}

/*************************************************************************
|*
|*
|*
\************************************************************************/

void DrawDocShell::CancelSearching()
{
	if( dynamic_cast<FuSearch*>( mxDocShellFunction.get() ) )
	{
		SetDocShellFunction(0);
	}
}

/*************************************************************************
|*
|*  den eingestellten SlotFilter anwenden
|*
\************************************************************************/

void DrawDocShell::ApplySlotFilter() const
{
    SfxViewShell* pTestViewShell = SfxViewShell::GetFirst();

    while( pTestViewShell )
    {
        if( pTestViewShell->GetObjectShell()
            == const_cast<DrawDocShell*>( this )
            && pTestViewShell->GetViewFrame()
            && pTestViewShell->GetViewFrame()->GetDispatcher() )
        {
	        SfxDispatcher* pDispatcher = pTestViewShell->GetViewFrame()->GetDispatcher();

	        if( mpFilterSIDs )
		        pDispatcher->SetSlotFilter( mbFilterEnable, mnFilterCount, mpFilterSIDs );
	        else
		        pDispatcher->SetSlotFilter();

            if( pDispatcher->GetBindings() )
                pDispatcher->GetBindings()->InvalidateAll( sal_True );
        }

        pTestViewShell = SfxViewShell::GetNext( *pTestViewShell );
    }
}

void DrawDocShell::SetModified( sal_Bool bSet /* = sal_True */ )
{
    SfxObjectShell::SetModified( bSet );

    // #100237# change model state, too
    // #103182# only set the changed state if modification is enabled
    if( IsEnableSetModified() )
	{
		if ( mpDoc )
        	mpDoc->NbcSetChanged( bSet );

		Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) );
	}
}

/*************************************************************************
|*
|* Callback fuer ExecuteSpellPopup()
|*
\************************************************************************/

// #91457# ExecuteSpellPopup now handled by DrawDocShell. This is necessary
// to get hands on the outliner and the text object.
IMPL_LINK(DrawDocShell, OnlineSpellCallback, SpellCallbackInfo*, pInfo)
{
	SdrObject* pObj = NULL;
	SdrOutliner* pOutl = NULL;

	if(GetViewShell())
	{
		pOutl = GetViewShell()->GetView()->GetTextEditOutliner();
		pObj = GetViewShell()->GetView()->GetTextEditObject();
	}

	mpDoc->ImpOnlineSpellCallback(pInfo, pObj, pOutl);
	return(0);
}

void DrawDocShell::ClearUndoBuffer()
{
	// clear possible undo buffers of outliners
	SfxViewFrame* pSfxViewFrame = SfxViewFrame::GetFirst(this, false);
	while(pSfxViewFrame)
	{
		ViewShellBase* pViewShellBase = dynamic_cast< ViewShellBase* >( pSfxViewFrame->GetViewShell() );
		if( pViewShellBase )
		{
			::boost::shared_ptr<ViewShell> pViewSh( pViewShellBase->GetMainViewShell() );
			if( pViewSh.get() )
			{
				::sd::View* pView = pViewSh->GetView();
				if( pView )
				{
					pView->SdrEndTextEdit();
					sd::OutlineView* pOutlView = dynamic_cast< sd::OutlineView* >( pView );
					if( pOutlView )
					{
						SdrOutliner* pOutliner = pOutlView->GetOutliner();
						if( pOutliner )
							pOutliner->GetUndoManager().Clear();
					}
				}
			}
		}
		pSfxViewFrame = SfxViewFrame::GetNext(*pSfxViewFrame, this, false);
	}
	
	::svl::IUndoManager* pUndoManager = GetUndoManager();
    if(pUndoManager && pUndoManager->GetUndoActionCount())
        pUndoManager->Clear();
}

} // end of namespace sd
