diff options
Diffstat (limited to 'sw/source/ui/uno/unotxdoc.cxx')
-rw-r--r-- | sw/source/ui/uno/unotxdoc.cxx | 887 |
1 files changed, 610 insertions, 277 deletions
diff --git a/sw/source/ui/uno/unotxdoc.cxx b/sw/source/ui/uno/unotxdoc.cxx index 8e233c537c..09785b273a 100644 --- a/sw/source/ui/uno/unotxdoc.cxx +++ b/sw/source/ui/uno/unotxdoc.cxx @@ -1,5 +1,5 @@ /************************************************************************* - * + * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. @@ -31,13 +31,17 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" -#include <cmdid.h> -#include <swtypes.hxx> +#include <vos/mutex.hxx> #include <vcl/image.hxx> #include <vcl/virdev.hxx> #include <vcl/svapp.hxx> +#include <vcl/print.hxx> #include <sfx2/viewfrm.hxx> +#include <sfx2/sfxbasecontroller.hxx> #include <toolkit/helper/vclunohelper.hxx> +#include <toolkit/awt/vclxdevice.hxx> +#include <cmdid.h> +#include <swtypes.hxx> #include <wdocsh.hxx> #include <wrtsh.hxx> #include <view.hxx> @@ -49,12 +53,14 @@ #include <svl/stritem.hxx> #include <unotxdoc.hxx> #include <svl/numuno.hxx> -#include <unoobj.hxx> +#include <fldbas.hxx> +#include <unotextbodyhf.hxx> +#include <unotextrange.hxx> +#include <unotextcursor.hxx> #include <unosett.hxx> #include <unocoll.hxx> #include <unoredlines.hxx> #include <unosrch.hxx> -#include <toolkit/awt/vclxdevice.hxx> #include <sfx2/dispatch.hxx> #include <sfx2/request.hxx> #include <sfx2/objsh.hxx> // SfxObjectShellRef <-> SV_DECL_REF(SfxObjectShell) @@ -68,6 +74,7 @@ #include <unofield.hxx> #include <unoidx.hxx> #include <unoflatpara.hxx> +#include <unotxvw.hxx> #include <poolfmt.hxx> #include <globdoc.hxx> #include <viewopt.hxx> @@ -75,6 +82,8 @@ #include <doc.hxx> #include <charatr.hxx> #include <svx/xmleohlp.hxx> +#include <globals.hrc> +#include <unomid.h> #include <com/sun/star/util/SearchOptions.hpp> #include <com/sun/star/lang/ServiceNotRegisteredException.hpp> @@ -131,11 +140,14 @@ #include <svl/stylepool.hxx> #include <swatrset.hxx> +#include <view.hxx> +#include <srcview.hxx> //#include <com/sun/star/i18n/ScriptType.hpp> #include <svtools/langtab.hxx> #include <map> #include <set> +#include <vector> #include <svx/eeitem.hxx> #include <svx/editeng.hxx> @@ -172,6 +184,32 @@ using ::osl::FileBase; /****************************************************************************** * ******************************************************************************/ + +extern bool lcl_GetPostIts( IDocumentFieldsAccess* pIDFA, _SetGetExpFlds * pSrtLst ); + +SwPrintUIOptions * lcl_GetPrintUIOptions( + SwDocShell * pDocShell, + const SfxViewShell * pView ) +{ + if (!pDocShell) + return NULL; + + const BOOL bWebDoc = NULL != dynamic_cast< const SwWebDocShell * >(pDocShell); + const bool bSwSrcView = NULL != dynamic_cast< const SwSrcView * >(pView); + const SwView * pSwView = dynamic_cast< const SwView * >(pView); + const bool bHasSelection = pSwView ? pSwView->HasSelection( sal_False ) : false; // check for any selection, not just text selection + const bool bHasPostIts = lcl_GetPostIts( pDocShell->GetDoc(), 0 ); + + // get default values to use in dialog from documents SwPrintData + const SwPrintData *pPrintData = pDocShell->GetDoc()->getPrintData(); + DBG_ASSERT( pPrintData, "failed to get SwPrintData from document" ); + + return new SwPrintUIOptions( bWebDoc, bSwSrcView, bHasSelection, bHasPostIts, *pPrintData ); +} + +//////////////////////////////////////////////////////////// + + SwTxtFmtColl *lcl_GetParaStyle(const String& rCollName, SwDoc* pDoc) { SwTxtFmtColl* pColl = pDoc->FindTxtFmtCollByName( rCollName ); @@ -366,7 +404,9 @@ SwXTextDocument::SwXTextDocument(SwDocShell* pShell) : pxXLineNumberingProperties(0), pxLinkTargetSupplier(0), pxXRedlines(0), - m_pHiddenViewFrame(0) + m_pHiddenViewFrame(0), + m_pPrintUIOptions( NULL ), + m_pRenderData( NULL ) { } /*-- 18.12.98 11:53:00--------------------------------------------------- @@ -381,6 +421,8 @@ SwXTextDocument::~SwXTextDocument() xNumFmtAgg->setDelegator(x0); xNumFmtAgg = 0; } + delete m_pPrintUIOptions; + delete m_pRenderData; } @@ -727,19 +769,12 @@ Reference< util::XReplaceDescriptor > SwXTextDocument::createReplaceDescriptor( SwUnoCrsr* SwXTextDocument::CreateCursorForSearch(Reference< XTextCursor > & xCrsr) { getText(); - XText* pText = xBodyText.get(); + XText *const pText = xBodyText.get(); SwXBodyText* pBText = (SwXBodyText*)pText; - xCrsr = pBText->CreateTextCursor(sal_True); + SwXTextCursor *const pXTextCursor = pBText->CreateTextCursor(true); + xCrsr.set( static_cast<text::XWordCursor*>(pXTextCursor) ); - Reference<XUnoTunnel> xRangeTunnel( xCrsr, UNO_QUERY); - SwXTextCursor* pxUnoCrsr = 0; - if(xRangeTunnel.is()) - { - pxUnoCrsr = reinterpret_cast<SwXTextCursor*>(xRangeTunnel->getSomething( - SwXTextCursor::getUnoTunnelId())); - } - - SwUnoCrsr* pUnoCrsr = pxUnoCrsr->GetCrsr(); + SwUnoCrsr *const pUnoCrsr = pXTextCursor->GetCursor(); pUnoCrsr->SetRemainInSection(sal_False); return pUnoCrsr; } @@ -970,10 +1005,7 @@ Reference< XIndexAccess > if(!pResultCrsr) throw RuntimeException(); Reference< XIndexAccess > xRet; - if(nResult) - xRet = new SwXTextRanges(pResultCrsr); - else - xRet = new SwXTextRanges(); + xRet = new SwXTextRanges( (nResult) ? pResultCrsr : 0 ); delete pResultCrsr; return xRet; } @@ -993,11 +1025,10 @@ Reference< XInterface > SwXTextDocument::findFirst(const Reference< util::XSear Reference< XInterface > xRet; if(nResult) { - Reference< XTextRange > xTempRange = SwXTextRange::CreateTextRangeFromPosition( - pDocShell->GetDoc(), - *pResultCrsr->GetPoint(), - pResultCrsr->GetMark()); - xRet = *new SwXTextCursor(xTempRange->getText(), pResultCrsr); + const uno::Reference< text::XText > xParent = + ::sw::CreateParentXText(*pDocShell->GetDoc(), + *pResultCrsr->GetPoint()); + xRet = *new SwXTextCursor(xParent, *pResultCrsr); delete pResultCrsr; } return xRet; @@ -1021,12 +1052,11 @@ Reference< XInterface > SwXTextDocument::findNext(const Reference< XInterface > Reference< XInterface > xRet; if(nResult) { - Reference< XTextRange > xTempRange = SwXTextRange::CreateTextRangeFromPosition( - pDocShell->GetDoc(), - *pResultCrsr->GetPoint(), - pResultCrsr->GetMark()); + const uno::Reference< text::XText > xParent = + ::sw::CreateParentXText(*pDocShell->GetDoc(), + *pResultCrsr->GetPoint()); - xRet = *new SwXTextCursor(xTempRange->getText(), pResultCrsr); + xRet = *new SwXTextCursor(xParent, *pResultCrsr); delete pResultCrsr; } return xRet; @@ -2455,100 +2485,74 @@ Any SAL_CALL SwXTextDocument::getPropertyDefault( const OUString& rPropertyName } return aAny; } -/*-- 06.01.2004 15:08:34--------------------------------------------------- - The class SwViewOptionAdjust_Impl is used to adjust the SwViewOption of - the current ViewShell so that fields are not printed as commands and - hidden text and hidden characters are always invisible. - After printing the view options are restored - -----------------------------------------------------------------------*/ -class SwViewOptionAdjust_Impl -{ - bool m_bSwitchOff_IsFldName; - bool m_bSwitchOff_PlaceHolderView; - bool m_bSwitchOff_HiddenChar; - bool m_bSwitchOff_HiddenParagraphs; - bool m_bSwitchOff_IsShowHiddenField; - - SwViewOption* m_pViewOption; - SwWrtShell& m_rShell; -public: - SwViewOptionAdjust_Impl(SwWrtShell& rSh); - ~SwViewOptionAdjust_Impl(); -}; -/*-- 06.01.2004 15:08:34--------------------------------------------------- - - -----------------------------------------------------------------------*/ -SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl(SwWrtShell& rSh) : - m_pViewOption(0), - m_rShell(rSh) -{ - const SwViewOption* pCurrentViewOptions = m_rShell.GetViewOptions(); - m_bSwitchOff_IsFldName = pCurrentViewOptions->IsFldName() && m_rShell.IsAnyFieldInDoc(); - bool bApplyViewOptions = m_bSwitchOff_IsFldName; - //switch off painting of placeholder fields - m_bSwitchOff_PlaceHolderView = pCurrentViewOptions->IsShowPlaceHolderFields(); - //switch off display of hidden characters if on and hidden characters are in use - m_bSwitchOff_HiddenChar = pCurrentViewOptions->IsShowHiddenChar() && m_rShell.GetDoc()->ContainsHiddenChars(); - //switch off display of hidden paragraphs if on and hidden paragraphs are in use - m_bSwitchOff_HiddenParagraphs = pCurrentViewOptions->IsShowHiddenPara(); - if(m_bSwitchOff_HiddenParagraphs) - { - const SwFieldType* pFldType = m_rShell.GetDoc()->GetSysFldType(RES_HIDDENPARAFLD); - if(!pFldType || !pFldType->GetDepends()) - m_bSwitchOff_HiddenParagraphs = false; - } - m_bSwitchOff_IsShowHiddenField = pCurrentViewOptions->IsShowHiddenField(); - if(m_bSwitchOff_IsShowHiddenField) - { - const SwFieldType* pFldType = m_rShell.GetDoc()->GetSysFldType(RES_HIDDENTXTFLD); - if( !pFldType || !pFldType->GetDepends()) - m_bSwitchOff_IsShowHiddenField = false; - } - - bApplyViewOptions |= m_bSwitchOff_PlaceHolderView; - bApplyViewOptions |= m_bSwitchOff_HiddenChar; - bApplyViewOptions |= m_bSwitchOff_HiddenParagraphs; - bApplyViewOptions |= m_bSwitchOff_IsShowHiddenField; - if(bApplyViewOptions) - { - m_pViewOption = new SwViewOption(*m_rShell.GetViewOptions()); - if(m_bSwitchOff_IsFldName) - m_pViewOption->SetFldName(FALSE); - if(m_bSwitchOff_PlaceHolderView) - m_pViewOption->SetShowPlaceHolderFields(FALSE); - if(m_bSwitchOff_HiddenChar) - m_pViewOption->SetShowHiddenChar(FALSE); - if(m_bSwitchOff_HiddenParagraphs) - m_pViewOption->SetShowHiddenPara(FALSE); - if(m_bSwitchOff_IsShowHiddenField) - m_pViewOption->SetShowHiddenField(FALSE); - SW_MOD()->ApplyUsrPref(*m_pViewOption, &m_rShell.GetView(), VIEWOPT_DEST_VIEW_ONLY ); - } -} -/*-- 06.01.2004 15:08:34--------------------------------------------------- - -----------------------------------------------------------------------*/ -SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl() +static OutputDevice * lcl_GetOutputDevice( const SwPrintUIOptions &rPrintUIOptions ) { - if(m_pViewOption) + OutputDevice *pOut = 0; + + uno::Any aAny( rPrintUIOptions.getValue( C2U( "RenderDevice" ) )); + uno::Reference< awt::XDevice > xRenderDevice; + aAny >>= xRenderDevice; + if (xRenderDevice.is()) { - if(m_bSwitchOff_IsFldName) - m_pViewOption->SetFldName(TRUE); - if(m_bSwitchOff_PlaceHolderView) - m_pViewOption->SetShowPlaceHolderFields(TRUE); - if(m_bSwitchOff_HiddenChar) - m_pViewOption->SetShowHiddenChar(TRUE); - if(m_bSwitchOff_HiddenParagraphs) - m_pViewOption->SetShowHiddenPara(TRUE); - if(m_bSwitchOff_IsShowHiddenField) - m_pViewOption->SetShowHiddenField(TRUE); - SW_MOD()->ApplyUsrPref(*m_pViewOption, &m_rShell.GetView(), VIEWOPT_DEST_VIEW_ONLY ); - delete m_pViewOption; + VCLXDevice* pDevice = VCLXDevice::GetImplementation( xRenderDevice ); + pOut = pDevice ? pDevice->GetOutputDevice() : 0; } -} -/* -----------------------------23.08.02 16:00-------------------------------- - ---------------------------------------------------------------------------*/ + return pOut; +} + + +static bool lcl_SeqHasProperty( + const uno::Sequence< beans::PropertyValue >& rOptions, + const sal_Char *pPropName ) +{ + bool bRes = false; + const sal_Int32 nLen = rOptions.getLength(); + const beans::PropertyValue *pProps = rOptions.getConstArray(); + for (sal_Int32 i = 0; i < nLen && !bRes; ++i) + { + if (pProps[i].Name.equalsAscii( pPropName )) + bRes = true; + } + return bRes; +} + + +SfxViewShell * SwXTextDocument::GetRenderView( + bool &rbIsSwSrcView, + const uno::Sequence< beans::PropertyValue >& rOptions, + bool bIsPDFExport ) +{ + // get view shell to use + SfxViewShell *pView = 0; + if (bIsPDFExport) + pView = GuessViewShell( rbIsSwSrcView ); + else + { + uno::Any aTmp; + const sal_Int32 nLen = rOptions.getLength(); + const beans::PropertyValue *pProps = rOptions.getConstArray(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + if (pProps[i].Name.equalsAscii( "View" )) + { + aTmp = pProps[i].Value; + break; + } + } + + uno::Reference< frame::XController > xController; + if (aTmp >>= xController) + { + DBG_ASSERT( xController.is(), "controller is empty!" ); + pView = GuessViewShell( rbIsSwSrcView, xController ); + } + } + return pView; +} + + /* * GetRenderDoc: * returns the document to be rendered, usually this will be the 'regular' @@ -2558,7 +2562,10 @@ SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl() * SfxViewShell. */ -SwDoc * SwXTextDocument::GetRenderDoc( SfxViewShell *&rpView, const uno::Any& rSelection ) +SwDoc * SwXTextDocument::GetRenderDoc( + SfxViewShell *&rpView, + const uno::Any& rSelection, + bool bIsPDFExport ) { SwDoc *pDoc = 0; @@ -2568,11 +2575,22 @@ SwDoc * SwXTextDocument::GetRenderDoc( SfxViewShell *&rpView, const uno::Any& rS pDoc = pDocShell->GetDoc(); else { - // used for PDF export of (multi-)selection + DBG_ASSERT( !xModel.is(), "unexpected model found" ); + if (rSelection.hasValue()) // is anything selected ? { + // this part should only be called when a temporary document needs to be created, + // for example for PDF export or printing of (multi-)selection only. + + bool bIsSwSrcView = false; if (!rpView) - rpView = GuessViewShell(); + { + (void) bIsPDFExport; + // aside from maybe PDF export the view should always have been provided! + DBG_ASSERT( bIsPDFExport, "view is missing, guessing one..." ); + + rpView = GuessViewShell( bIsSwSrcView ); + } DBG_ASSERT( rpView, "ViewShell missing" ); // the view shell should be SwView for documents PDF export. // for the page preview no selection should be possible @@ -2587,56 +2605,188 @@ SwDoc * SwXTextDocument::GetRenderDoc( SfxViewShell *&rpView, const uno::Any& rS rpView = pDoc->GetDocShell()->GetView(); } } - else { + else + { DBG_ERROR( "unexpected ViewShell" ); } } } return pDoc; } + /* -----------------------------23.08.02 16:00-------------------------------- ---------------------------------------------------------------------------*/ + +static void lcl_SavePrintUIOptionsToDocumentPrintData( + SwDoc &rDoc, + const SwPrintUIOptions &rPrintUIOptions, + bool bIsPDFEXport ) +{ + if (!rDoc.getPrintData()) + { + SwPrintData *pTmpData = new SwPrintData; + rDoc.setPrintData ( *pTmpData ); + delete pTmpData; // setPrintData does make its own copy! + } + + SwPrintData *pDocPrintData = rDoc.getPrintData(); + + pDocPrintData->SetPrintGraphic( rPrintUIOptions.IsPrintGraphics() ); + pDocPrintData->SetPrintTable( rPrintUIOptions.IsPrintTables() ); + pDocPrintData->SetPrintDraw( rPrintUIOptions.IsPrintDrawings() ); + pDocPrintData->SetPrintControl( rPrintUIOptions.IsPrintFormControls() ); + pDocPrintData->SetPrintLeftPage( rPrintUIOptions.IsPrintLeftPages() ); + pDocPrintData->SetPrintRightPage( rPrintUIOptions.IsPrintRightPages() ); + pDocPrintData->SetPrintReverse( rPrintUIOptions.IsPrintReverse() ); + pDocPrintData->SetPaperFromSetup( rPrintUIOptions.IsPaperFromSetup() ); + pDocPrintData->SetPrintEmptyPages( rPrintUIOptions.IsPrintEmptyPages( bIsPDFEXport ) ); + pDocPrintData->SetPrintPostIts( rPrintUIOptions.GetPrintPostItsType() ); + pDocPrintData->SetPrintProspect( rPrintUIOptions.IsPrintProspect() ); + pDocPrintData->SetPrintProspect_RTL( rPrintUIOptions.IsPrintProspectRTL() ); + pDocPrintData->SetPrintPageBackground( rPrintUIOptions.IsPrintPageBackground() ); + pDocPrintData->SetPrintBlackFont( rPrintUIOptions.IsPrintWithBlackTextColor() ); + // pDocPrintData->SetPrintSingleJobs( b ); handled by File/Print dialog itself + // pDocPrintData->SetFaxName( s ); n/a in File/Print dialog + pDocPrintData->SetPrintHiddenText( rPrintUIOptions.IsPrintHiddenText() ); + pDocPrintData->SetPrintTextPlaceholder( rPrintUIOptions.IsPrintTextPlaceholders() ); +} + + sal_Int32 SAL_CALL SwXTextDocument::getRendererCount( const uno::Any& rSelection, - const uno::Sequence< beans::PropertyValue >& /*rxOptions*/ ) + const uno::Sequence< beans::PropertyValue >& rxOptions ) throw (IllegalArgumentException, RuntimeException) { ::vos::OGuard aGuard(Application::GetSolarMutex()); if(!IsValid()) throw RuntimeException(); - SfxViewShell *pView = 0; - SwDoc *pDoc = GetRenderDoc( pView, rSelection ); - if (!pDoc) - throw RuntimeException(); - SwDocShell *pRenderDocShell = pDoc->GetDocShell(); - // #i38289 - if(pDoc->get(IDocumentSettingAccess::BROWSE_MODE)) - { - pRenderDocShell->ToggleBrowserMode(false,NULL); - } + const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ); + bool bIsSwSrcView = false; + SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport ); + + if (!bIsSwSrcView && !m_pRenderData) + m_pRenderData = new SwRenderData; + if (!m_pPrintUIOptions) + m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView ); + bool bFormat = m_pPrintUIOptions->processPropertiesAndCheckFormat( rxOptions ); + // const bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport ); + + SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport ); + DBG_ASSERT( pDoc && pView, "doc or view shell missing!" ); + if (!pDoc || !pView) + return 0; - SwWrtShell *pWrtShell = pRenderDocShell->GetWrtShell(); + // save current UI options from the print dialog for the next call to that dialog + lcl_SavePrintUIOptionsToDocumentPrintData( *pDoc, *m_pPrintUIOptions, bIsPDFExport ); sal_Int32 nRet = 0; - if( !pWrtShell ) + if (bIsSwSrcView) { - //create a hidden view to be able to export as PDF also in print preview - m_pHiddenViewFrame = SfxViewFrame::CreateViewFrame( *pRenderDocShell, 2, TRUE ); - SwView* pSwView = (SwView*) m_pHiddenViewFrame->GetViewShell(); - pWrtShell = pSwView->GetWrtShellPtr(); + SwSrcView *pSwSrcView = dynamic_cast< SwSrcView * >(pView); + OutputDevice *pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions ); + nRet = pSwSrcView->PrintSource( pOutDev, 1 /* dummy */, true /* get page count only */ ); } + else + { + SwDocShell *pRenderDocShell = pDoc->GetDocShell(); + SwWrtShell *pWrtShell = pRenderDocShell->GetWrtShell(); + if (bFormat) + { + // #i38289 + if(pDoc->get(IDocumentSettingAccess::BROWSE_MODE)) + { + pRenderDocShell->ToggleBrowserMode(false,NULL); + } + + if (!pWrtShell) + { + //create a hidden view to be able to export as PDF also in print preview + m_pHiddenViewFrame = SfxViewFrame::CreateViewFrame( *pRenderDocShell, 2, TRUE ); + SwView* pSwView = (SwView*) m_pHiddenViewFrame->GetViewShell(); + pWrtShell = pSwView->GetWrtShellPtr(); + } + + // reformating the document for printing will show the changes in the view + // which is likely to produce many unwanted and not nice to view actions. + // We don't want that! Thus we disable updating of the view. + pWrtShell->StartAction(); + + const TypeId aSwViewTypeId = TYPE(SwView); + if (pView->IsA(aSwViewTypeId)) + { + if (m_pRenderData && !m_pRenderData->IsViewOptionAdjust()) + m_pRenderData->ViewOptionAdjustStart( *pWrtShell, *pWrtShell->GetViewOptions() ); + } + + m_pRenderData->SetSwPrtOptions( new SwPrtOptions( C2U( bIsPDFExport ? "PDF export" : "Printing" ) ) ); + m_pRenderData->MakeSwPrtOptions( m_pRenderData->GetSwPrtOptionsRef(), pRenderDocShell, + m_pPrintUIOptions, m_pRenderData, bIsPDFExport ); + + if (pView->IsA(aSwViewTypeId)) + { + // PDF export should not make use of the SwPrtOptions + const SwPrtOptions *pPrtOptions = bIsPDFExport? NULL : m_pRenderData->GetSwPrtOptions(); + m_pRenderData->ViewOptionAdjust( pPrtOptions ); + } + + // since printing now also use the API for PDF export this option + // should be set for printing as well ... + pWrtShell->SetPDFExportOption( sal_True ); + + // --> FME 2005-05-23 #122919# Force field update before PDF export: + pWrtShell->ViewShell::UpdateFlds(TRUE); + // <-- + + // there is some redundancy between those two function calls, but right now + // there is no time to sort this out. + //TODO: check what exatly needs to be done and make just one function for that + pWrtShell->CalcLayout(); + pWrtShell->CalcPagesForPrint( pDoc->GetPageCount() ); + + pWrtShell->SetPDFExportOption( sal_False ); + + + // enable view again + pWrtShell->EndAction(); + } + + const sal_Int32 nPageCount = pDoc->GetPageCount(); + + // + // get number of pages to be rendered + // + const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect", false ); + if (bPrintProspect) + { + pDoc->CalculatePagePairsForProspectPrinting( *m_pRenderData, *m_pPrintUIOptions, nPageCount ); + nRet = m_pRenderData->GetPagePairsForProspectPrinting().size(); + } + else + { + const sal_Int16 nPostItMode = (sal_Int16) m_pPrintUIOptions->getIntValue( "PrintAnnotationMode", 0 ); + if (nPostItMode != POSTITS_NONE) + { + OutputDevice *pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions ); + m_pRenderData->CreatePostItData( pDoc, pWrtShell->GetViewOptions(), pOutDev ); + } - SwViewOptionAdjust_Impl aAdjust(*pWrtShell); - pWrtShell->SetPDFExportOption( sal_True ); - // --> FME 2005-05-23 #122919# Force field update before PDF export: - pWrtShell->ViewShell::UpdateFlds(TRUE); - // <-- - pWrtShell->CalcLayout(); - pWrtShell->SetPDFExportOption( sal_False ); - nRet = pDoc->GetPageCount(); + // get set of valid document pages (according to the current settings) + // and their start frames + pDoc->CalculatePagesForPrinting( *m_pRenderData, *m_pPrintUIOptions, bIsPDFExport, nPageCount ); + if (nPostItMode != POSTITS_NONE) + { + pDoc->UpdatePagesForPrintingWithPostItData( *m_pRenderData, + *m_pPrintUIOptions, bIsPDFExport, nPageCount ); + } + + nRet = m_pRenderData->GetPagesToPrint().size(); + } + } + DBG_ASSERT( nRet >= 0, "negative number of pages???" ); + return nRet; } /* -----------------------------23.08.02 16:00-------------------------------- @@ -2651,41 +2801,110 @@ uno::Sequence< beans::PropertyValue > SAL_CALL SwXTextDocument::getRenderer( ::vos::OGuard aGuard(Application::GetSolarMutex()); if(!IsValid()) throw RuntimeException(); - SfxViewShell *pView = 0; - SwDoc *pDoc = GetRenderDoc( pView, rSelection ); - if (!pDoc) - throw RuntimeException(); + + const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ); + bool bIsSwSrcView = false; + SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport ); + + // m_pRenderData should NOT be created here! + // That should only be done in getRendererCount. If this function is called before + // getRendererCount was called then the caller will probably just retrieve the extra UI options + // and is not interested in getting valid information about the other data that would + // otherwise be provided here! +// if( ! m_pRenderData ) +// m_pRenderData = new SwRenderData; + if (!m_pPrintUIOptions) + m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView ); + m_pPrintUIOptions->processProperties( rxOptions ); + const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect", false ); + const bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport ); + + SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport ); + DBG_ASSERT( pDoc && pView, "doc or view shell missing!" ); + if (!pDoc || !pView) + return uno::Sequence< beans::PropertyValue >(); // due to #110067# (document page count changes sometimes during // PDF export/printing) we can not check for the upper bound properly. // Thus instead of throwing the exception we silently return. - if (!(0 <= nRenderer /* && nRenderer < pDoc->GetPageCount()*/)) + if (0 > nRenderer) throw IllegalArgumentException(); - if (nRenderer >= pDoc->GetPageCount()) - return uno::Sequence< beans::PropertyValue >(); - - bool bSkipEmptyPages = false; - for( sal_Int32 nProperty = 0, nPropertyCount = rxOptions.getLength(); nProperty < nPropertyCount; ++nProperty ) + sal_Int32 nMaxRenderer = 0; + if (!bIsSwSrcView && m_pRenderData) { - if( rxOptions[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) ) ) - rxOptions[ nProperty].Value >>= bSkipEmptyPages; + DBG_ASSERT( m_pRenderData, "m_pRenderData missing!!" ); + nMaxRenderer = bPrintProspect? + m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 : + m_pRenderData->GetPagesToPrint().size() - 1; } + // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print + // we obmit checking of the upper bound in this case. + if (!bIsSwSrcView && m_pRenderData && nRenderer > nMaxRenderer) + return uno::Sequence< beans::PropertyValue >(); - Size aPgSize( pDoc->GetPageSize( sal_uInt16(nRenderer + 1), bSkipEmptyPages ) ); + uno::Sequence< beans::PropertyValue > aRenderer; + if (m_pRenderData) + { + awt::Size aPageSize; + Size aTmpSize; + if (bIsSwSrcView || bPrintProspect) + { + // for printing of HTML source code and prospect printing we should use + // the printers paper size since + // a) HTML source view has no page size + // b) prospect printing has a different page size from the documents page + // since two document pages will get rendered on one printer page + + // since PageIncludesNonprintableArea will be set to true we can return the + // printers paper size here. + // Sometimes 'getRenderer' is only called to get "ExtraPrintUIOptions", in this + // case we won't get an OutputDevice here, but then the caller also has no need + // for the correct PageSisze right now... + Printer *pPrinter = dynamic_cast< Printer * >(lcl_GetOutputDevice( *m_pPrintUIOptions )); + if (pPrinter) + { + if (bPrintProspect) + { + aTmpSize = pDoc->GetPageSize( USHORT(nRenderer + 1), bIsSkipEmptyPages ); + // we just state what output size we would need + // the rest is nowadays up to vcl + aPageSize = awt::Size ( TWIP_TO_MM100( 2 * aTmpSize.Width() ), + TWIP_TO_MM100( aTmpSize.Height() )); + } + else + { + // printing HTML source view + aTmpSize = pPrinter->GetPaperSize(); + aTmpSize = pPrinter->LogicToLogic( aTmpSize, + pPrinter->GetMapMode(), MapMode( MAP_100TH_MM )); + aPageSize = awt::Size( aTmpSize.Width(), aTmpSize.Height() ); + } + } + } + else + { + aTmpSize = pDoc->GetPageSize( USHORT(nRenderer + 1), bIsSkipEmptyPages ); + aPageSize = awt::Size ( TWIP_TO_MM100( aTmpSize.Width() ), + TWIP_TO_MM100( aTmpSize.Height() )); + } - awt::Size aPageSize( TWIP_TO_MM100( aPgSize.Width() ), - TWIP_TO_MM100( aPgSize.Height() )); - uno::Sequence< beans::PropertyValue > aRenderer(1); - PropertyValue &rValue = aRenderer.getArray()[0]; - rValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ); - rValue.Value <<= aPageSize; + aRenderer.realloc(2); + aRenderer[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ); + aRenderer[0].Value <<= aPageSize; + aRenderer[1].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PageIncludesNonprintableArea" ) ); + aRenderer[1].Value <<= sal_True; + } + m_pPrintUIOptions->appendPrintUIOptions( aRenderer ); + return aRenderer; } /* -----------------------------28.10.02 16:00-------------------------------- ---------------------------------------------------------------------------*/ -SfxViewShell * SwXTextDocument::GuessViewShell() +SfxViewShell * SwXTextDocument::GuessViewShell( + /* out */ bool &rbIsSwSrcView, + const uno::Reference< css::frame::XController > xController ) { // #130810# SfxViewShell::Current() / SfxViewShell::GetObjectShell() // must not be used (see comment from MBA) @@ -2693,24 +2912,39 @@ SfxViewShell * SwXTextDocument::GuessViewShell() SfxViewShell *pView = 0; SwView *pSwView = 0; SwPagePreView *pSwPagePreView = 0; + SwSrcView *pSwSrcView = 0; SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pDocShell, 0, sal_False ); + + // look for the view shell with the same controller in use, + // otherwise look for a suitable view, preferably a SwView, + // if that one is not found use a SwPagePreView if found. while (pFrame) { pView = pFrame->GetViewShell(); pSwView = dynamic_cast< SwView * >(pView); - if (pSwView) - break; + pSwSrcView = dynamic_cast< SwSrcView * >(pView); if (!pSwPagePreView) pSwPagePreView = dynamic_cast< SwPagePreView * >(pView); + if (xController.is()) + { + if (pView && pView->GetController() == xController) + break; + } + else if (pSwView || pSwSrcView) + break; pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell, 0, sal_False ); } - return pSwView ? pSwView : dynamic_cast< SwView * >(pSwPagePreView); + DBG_ASSERT( pSwView || pSwPagePreView || pSwSrcView, "failed to get view shell" ); + if (pView) + rbIsSwSrcView = pSwSrcView != 0; + return pView; +// return pSwView ? dynamic_cast< SfxViewShell * >(pSwView) : +// (pSwSrcView ? dynamic_cast< SfxViewShell * >(pSwSrcView) : +// dynamic_cast< SfxViewShell * >(pSwPagePreView) ); } -/* -----------------------------23.08.02 16:00-------------------------------- - ---------------------------------------------------------------------------*/ void SAL_CALL SwXTextDocument::render( sal_Int32 nRenderer, const uno::Any& rSelection, @@ -2720,121 +2954,143 @@ void SAL_CALL SwXTextDocument::render( ::vos::OGuard aGuard(Application::GetSolarMutex()); if(!IsValid()) throw RuntimeException(); - SfxViewShell *pView = GuessViewShell(); - SwDoc *pDoc = GetRenderDoc( pView, rSelection ); - if (!pDoc || !pView) - throw RuntimeException(); // due to #110067# (document page count changes sometimes during // PDF export/printing) we can not check for the upper bound properly. // Thus instead of throwing the exception we silently return. - if (!(0 <= nRenderer /* && nRenderer < pDoc->GetPageCount()*/)) + if (0 > nRenderer) throw IllegalArgumentException(); - if (nRenderer >= pDoc->GetPageCount()) - return; - - // the view shell should be SwView for documents PDF export - // or SwPagePreView for PDF export of the page preview - //!! (check for SwView first as in GuessViewShell) !! - const TypeId aSwViewTypeId = TYPE(SwView); - ViewShell* pVwSh = pView->IsA(aSwViewTypeId) ? - ((SwView*)pView)->GetWrtShellPtr() : - ((SwPagePreView*)pView)->GetViewShell(); - uno::Reference< awt::XDevice > xRenderDevice; - bool bFirstPage = false; - bool bLastPage = false; - rtl::OUString aPages; - bool bSkipEmptyPages = false; - - for( sal_Int32 nProperty = 0, nPropertyCount = rxOptions.getLength(); nProperty < nPropertyCount; ++nProperty ) - { - if( rxOptions[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "RenderDevice" ) ) ) - rxOptions[ nProperty].Value >>= xRenderDevice; - else if( rxOptions[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFirstPage" ) ) ) - rxOptions[ nProperty].Value >>= bFirstPage; - else if( rxOptions[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsLastPage" ) ) ) - rxOptions[ nProperty].Value >>= bLastPage; - else if( rxOptions[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ) ) - rxOptions[ nProperty].Value >>= aPages; - else if( rxOptions[ nProperty ].Name == OUString( RTL_CONSTASCII_USTRINGPARAM( "IsSkipEmptyPages" ) ) ) - rxOptions[ nProperty].Value >>= bSkipEmptyPages; - } - - OutputDevice* pOut = 0; - if (xRenderDevice.is()) - { - VCLXDevice* pDevice = VCLXDevice::GetImplementation( xRenderDevice ); - pOut = pDevice ? pDevice->GetOutputDevice() : 0; - } - - if(pVwSh && pOut) + const bool bIsPDFExport = !lcl_SeqHasProperty( rxOptions, "IsPrinter" ); + bool bIsSwSrcView = false; + SfxViewShell *pView = GetRenderView( bIsSwSrcView, rxOptions, bIsPDFExport ); + + DBG_ASSERT( m_pRenderData, "data should have been created already in getRendererCount..." ); + DBG_ASSERT( m_pPrintUIOptions, "data should have been created already in getRendererCount..." ); + if (!bIsSwSrcView && !m_pRenderData) + m_pRenderData = new SwRenderData; + if (!m_pPrintUIOptions) + m_pPrintUIOptions = lcl_GetPrintUIOptions( pDocShell, pView ); + m_pPrintUIOptions->processProperties( rxOptions ); + const bool bPrintProspect = m_pPrintUIOptions->getBoolValue( "PrintProspect", false ); + const bool bLastPage = m_pPrintUIOptions->getBoolValue( "IsLastPage", sal_False ); + + SwDoc *pDoc = GetRenderDoc( pView, rSelection, bIsPDFExport ); + DBG_ASSERT( pDoc && pView, "doc or view shell missing!" ); + if (pDoc && pView) { - SwPrtOptions aOptions( C2U("PDF export") ); - - const TypeId aSwWebDocShellTypeId = TYPE(SwWebDocShell); - BOOL bWeb = pDocShell->IsA( aSwWebDocShellTypeId ); - SwView::MakeOptions( NULL, aOptions, NULL, NULL, bWeb, NULL, NULL ); - - Range aPageRange( nRenderer+1, nRenderer+1 ); - MultiSelection aPage( aPageRange ); - aPage.SetTotalRange( Range( 0, RANGE_MAX ) ); - aPage.Select( aPageRange ); - aOptions.aMulti = aPage; - - //! Note: Since for PDF export of (multi-)selection a temporary - //! document is created that contains only the selects parts, - //! and thus that document is to printed in whole the, - //! aOptions.bPrintSelection parameter will be false. - aOptions.bPrintSelection = FALSE; - - SwViewOptionAdjust_Impl* pViewOptionAdjust = pView->IsA(aSwViewTypeId) ? - new SwViewOptionAdjust_Impl(*((SwView*)pView)->GetWrtShellPtr()) : 0; - - - pVwSh->SetPDFExportOption( sal_True ); - - // --> FME 2004-06-08 #i12836# enhanced pdf export - // - // First, we have to export hyperlinks, notes, and outline to pdf. - // During this process, additional information required for tagging - // the pdf file are collected, which are evaulated during painting. - // - SwWrtShell* pWrtShell = pView->IsA(aSwViewTypeId) ? - ((SwView*)pView)->GetWrtShellPtr() : - 0; - - if ( bFirstPage && pWrtShell ) + sal_Int32 nMaxRenderer = 0; + if (!bIsSwSrcView) { - SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPages, bSkipEmptyPages, sal_False ); + DBG_ASSERT( m_pRenderData, "m_pRenderData missing!!" ); + nMaxRenderer = bPrintProspect? + m_pRenderData->GetPagePairsForProspectPrinting().size() - 1 : + m_pRenderData->GetPagesToPrint().size() - 1; } - // <-- - - pVwSh->Prt( aOptions, 0, pOut ); - - // --> FME 2004-10-08 #i35176# - // - // After printing the last page, we take care for the links coming - // from the EditEngine. The links are generated during the painting - // process, but the destinations are still missing. - // - if ( bLastPage && pWrtShell ) - { - SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPages, bSkipEmptyPages, sal_True ); - } - // <-- - - pVwSh->SetPDFExportOption( sal_False ); - // #i96167# haggai: delete pViewOptionsAdjust here because it makes use - // of the shell, which might get destroyed in lcl_DisposeView! - delete pViewOptionAdjust; - - if( bLastPage && m_pHiddenViewFrame) + // since SwSrcView::PrintSource is a poor implementation to get the number of pages to print + // we obmit checking of the upper bound in this case. + if (bIsSwSrcView || nRenderer <= nMaxRenderer) { - lcl_DisposeView( m_pHiddenViewFrame, pDocShell ); - m_pHiddenViewFrame = 0; + if (bIsSwSrcView) + { + SwSrcView *pSwSrcView = dynamic_cast< SwSrcView * >(pView); + OutputDevice *pOutDev = lcl_GetOutputDevice( *m_pPrintUIOptions ); + pSwSrcView->PrintSource( pOutDev, nRenderer + 1, false ); + } + else + { + // the view shell should be SwView for documents PDF export + // or SwPagePreView for PDF export of the page preview + //!! (check for SwView first as in GuessViewShell) !! + DBG_ASSERT( pView, "!! view missing !!" ); + const TypeId aSwViewTypeId = TYPE(SwView); + ViewShell* pVwSh = 0; + if (pView) + { + pVwSh = pView->IsA(aSwViewTypeId) ? + ((SwView*)pView)->GetWrtShellPtr() : + ((SwPagePreView*)pView)->GetViewShell(); + } + + // get output device to use + OutputDevice * pOut = lcl_GetOutputDevice( *m_pPrintUIOptions ); + + if(pVwSh && pOut && m_pRenderData->HasSwPrtOptions()) + { + const rtl::OUString aPageRange = m_pPrintUIOptions->getStringValue( "PageRange", OUString() ); + const bool bFirstPage = m_pPrintUIOptions->getBoolValue( "IsFirstPage", sal_False ); + bool bIsSkipEmptyPages = !m_pPrintUIOptions->IsPrintEmptyPages( bIsPDFExport ); + + DBG_ASSERT(( pView->IsA(aSwViewTypeId) && m_pRenderData->IsViewOptionAdjust()) + || (!pView->IsA(aSwViewTypeId) && !m_pRenderData->IsViewOptionAdjust()), + "SwView / SwViewOptionAdjust_Impl availability mismatch" ); + + // since printing now also use the API for PDF export this option + // should be set for printing as well ... + pVwSh->SetPDFExportOption( sal_True ); + + // --> FME 2004-06-08 #i12836# enhanced pdf export + // + // First, we have to export hyperlinks, notes, and outline to pdf. + // During this process, additional information required for tagging + // the pdf file are collected, which are evaulated during painting. + // + SwWrtShell* pWrtShell = pView->IsA(aSwViewTypeId) ? + ((SwView*)pView)->GetWrtShellPtr() : + 0; + + if (bIsPDFExport && bFirstPage && pWrtShell) + { + SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, sal_False ); + } + // <-- + + const SwPrtOptions &rSwPrtOptions = *m_pRenderData->GetSwPrtOptions(); + if (bPrintProspect) + pVwSh->PrintProspect( pOut, rSwPrtOptions, nRenderer ); + else // normal printing and PDF export + pVwSh->PrintOrPDFExport( pOut, rSwPrtOptions, nRenderer ); + + // --> FME 2004-10-08 #i35176# + // + // After printing the last page, we take care for the links coming + // from the EditEngine. The links are generated during the painting + // process, but the destinations are still missing. + // + if (bIsPDFExport && bLastPage && pWrtShell) + { + SwEnhancedPDFExportHelper aHelper( *pWrtShell, *pOut, aPageRange, bIsSkipEmptyPages, sal_True ); + } + // <-- + + pVwSh->SetPDFExportOption( sal_False ); + + // last page to be rendered? (not necessarily the last page of the document) + // -> do clean-up of data + if (bLastPage) + { + // #i96167# haggai: delete ViewOptionsAdjust here because it makes use + // of the shell, which might get destroyed in lcl_DisposeView! + if (m_pRenderData && m_pRenderData->IsViewOptionAdjust()) + m_pRenderData->ViewOptionAdjustStop(); + + if (m_pRenderData && m_pRenderData->HasPostItData()) + m_pRenderData->DeletePostItData(); + if (m_pHiddenViewFrame) + { + lcl_DisposeView( m_pHiddenViewFrame, pDocShell ); + m_pHiddenViewFrame = 0; + } + } + } + } } } + if( bLastPage ) + { + delete m_pRenderData; m_pRenderData = NULL; + delete m_pPrintUIOptions; m_pPrintUIOptions = NULL; + } } /* -----------------------------03.10.04 ------------------------------------- @@ -3789,3 +4045,80 @@ void SwXDocumentPropertyHelper::onChange() if(m_pDoc) m_pDoc->SetModified(); } + + +/*****************************************************************************/ + +SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl( SwWrtShell& rSh, const SwViewOption &rViewOptions ) : + m_rShell( rSh ), + m_aOldViewOptions( rViewOptions ) +{ +} + + +SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl() +{ + m_rShell.ApplyViewOptions( m_aOldViewOptions ); +} + + +void SwViewOptionAdjust_Impl::AdjustViewOptions( + const SwPrtOptions *pPrtOptions ) +{ + // to avoid unnecessary reformatting the view options related to the content + // below should only change if necessary, that is if respective content is present + const bool bContainsHiddenChars = m_rShell.GetDoc()->ContainsHiddenChars(); + const SwFieldType* pFldType = m_rShell.GetDoc()->GetSysFldType( RES_HIDDENTXTFLD ); + const bool bContainsHiddenFields = pFldType && pFldType->GetDepends(); + pFldType = m_rShell.GetDoc()->GetSysFldType( RES_HIDDENPARAFLD ); + const bool bContainsHiddenParagraphs = pFldType && pFldType->GetDepends(); + pFldType = m_rShell.GetDoc()->GetSysFldType( RES_JUMPEDITFLD ); + const bool bContainsPlaceHolders = pFldType && pFldType->GetDepends(); + const bool bContainsFields = m_rShell.IsAnyFieldInDoc(); + + SwViewOption aRenderViewOptions( m_aOldViewOptions ); + + // disable anything in the view that should not be printed (or exported to PDF) by default + // (see also dialog "Tools/Options - StarOffice Writer - Formatting Aids" + // in section "Display of ...") + aRenderViewOptions.SetParagraph( FALSE ); // paragraph end + aRenderViewOptions.SetSoftHyph( FALSE ); // aka custom hyphens + aRenderViewOptions.SetBlank( FALSE ); // spaces + aRenderViewOptions.SetHardBlank( FALSE ); // non-breaking spaces + aRenderViewOptions.SetTab( FALSE ); // tabs + aRenderViewOptions.SetLineBreak( FALSE ); // breaks (type 1) + aRenderViewOptions.SetPageBreak( FALSE ); // breaks (type 2) + aRenderViewOptions.SetColumnBreak( FALSE ); // breaks (type 3) + BOOL bVal = pPrtOptions? pPrtOptions->bPrintHiddenText : FALSE; + if (bContainsHiddenChars) + aRenderViewOptions.SetShowHiddenChar( bVal ); // hidden text + if (bContainsHiddenFields) + aRenderViewOptions.SetShowHiddenField( bVal ); + if (bContainsHiddenParagraphs) + aRenderViewOptions.SetShowHiddenPara( bVal ); + + if (bContainsPlaceHolders) + { + // should always be printed in PDF export! + bVal = pPrtOptions ? pPrtOptions->bPrintTextPlaceholder : TRUE; + aRenderViewOptions.SetShowPlaceHolderFields( bVal ); + } + + if (bContainsFields) + aRenderViewOptions.SetFldName( FALSE ); + + // we need to set this flag in order to get to see the visible effect of + // some of the above settings (needed for correct rendering) + aRenderViewOptions.SetViewMetaChars( TRUE ); + + if (m_aOldViewOptions != aRenderViewOptions) // check if reformatting is necessary + { + aRenderViewOptions.SetPrinting( pPrtOptions != NULL ); + m_rShell.ApplyViewOptions( aRenderViewOptions ); + } +} + + +/*****************************************************************************/ + + |