summaryrefslogtreecommitdiff
path: root/sc/source/ui/unoobj/docuno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/unoobj/docuno.cxx')
-rw-r--r--sc/source/ui/unoobj/docuno.cxx322
1 files changed, 305 insertions, 17 deletions
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 5f4f1a7aa93f..71f4706085d8 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -43,12 +43,14 @@
#include <svl/numuno.hxx>
#include <svl/smplhint.hxx>
#include <unotools/undoopt.hxx>
+#include <unotools/moduleoptions.hxx>
#include <sfx2/printer.hxx>
#include <sfx2/bindings.hxx>
#include <vcl/pdfextoutdevdata.hxx>
#include <vcl/waitobj.hxx>
#include <unotools/charclass.hxx>
#include <tools/multisel.hxx>
+#include <tools/resary.hxx>
#include <toolkit/awt/vclxdevice.hxx>
#include <ctype.h>
#include <float.h> // DBL_MAX
@@ -90,11 +92,15 @@
#include "unoguard.hxx"
#include "unonames.hxx"
#include "shapeuno.hxx"
+#include "viewuno.hxx"
+#include "tabvwsh.hxx"
#include "printfun.hxx"
#include "pfuncache.hxx"
#include "scmod.hxx"
#include "rangeutl.hxx"
#include "ViewSettingsSequenceDefines.hxx"
+#include "sc.hrc"
+#include "scresid.hxx"
#ifndef _SVX_UNOSHAPE_HXX
#include <svx/unoshape.hxx>
@@ -209,6 +215,147 @@ SC_SIMPLE_SERVICE_INFO( ScTableSheetsObj, "ScTableSheetsObj", "com.sun.star.shee
//------------------------------------------------------------------------
+class ScPrintUIOptions : public vcl::PrinterOptionsHelper
+{
+public:
+ ScPrintUIOptions();
+ void SetDefaults();
+};
+
+ScPrintUIOptions::ScPrintUIOptions()
+{
+ const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
+ sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
+ sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();
+
+ ResStringArray aStrings( ScResId( SCSTR_PRINT_OPTIONS ) );
+ DBG_ASSERT( aStrings.Count() >= 19, "resource incomplete" );
+ if( aStrings.Count() < 19 ) // bad resource ?
+ return;
+
+ m_aUIProperties.realloc( 8 );
+
+ // create Section for spreadsheet (results in an extra tab page in dialog)
+ SvtModuleOptions aOpt;
+ String aAppGroupname( aStrings.GetString( 18 ) );
+ aAppGroupname.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ),
+ aOpt.GetModuleName( SvtModuleOptions::E_SCALC ) );
+ m_aUIProperties[0].Value = getGroupControlOpt( aAppGroupname, rtl::OUString() );
+
+ // create subgroup for pages
+ m_aUIProperties[1].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 0 ) ), rtl::OUString() );
+
+ // create a bool option for empty pages
+ m_aUIProperties[2].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 1 ) ),
+ rtl::OUString( aStrings.GetString( 2 ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsIncludeEmptyPages" ) ),
+ ! bSuppress
+ );
+ // create Subgroup for print content
+ vcl::PrinterOptionsHelper::UIControlOptions aPrintRangeOpt;
+ aPrintRangeOpt.maGroupHint = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
+ m_aUIProperties[3].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 6 ) ),
+ rtl::OUString(),
+ aPrintRangeOpt
+ );
+
+ // create a choice for the content to create
+ uno::Sequence< rtl::OUString > aChoices( 3 ), aHelpTexts( 3 );
+ aChoices[0] = aStrings.GetString( 7 );
+ aHelpTexts[0] = aStrings.GetString( 8 );
+ aChoices[1] = aStrings.GetString( 9 );
+ aHelpTexts[1] = aStrings.GetString( 10 );
+ aChoices[2] = aStrings.GetString( 11 );
+ aHelpTexts[2] = aStrings.GetString( 12 );
+ m_aUIProperties[4].Value = getChoiceControlOpt( rtl::OUString(),
+ aHelpTexts,
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintContent" ) ),
+ aChoices,
+ nContent );
+
+ // create Subgroup for print range
+ aPrintRangeOpt.mbInternalOnly = sal_True;
+ m_aUIProperties[5].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 13 ) ),
+ rtl::OUString(),
+ aPrintRangeOpt
+ );
+
+ // create a choice for the range to print
+ rtl::OUString aPrintRangeName( RTL_CONSTASCII_USTRINGPARAM( "PrintRange" ) );
+ aChoices.realloc( 2 );
+ aHelpTexts.realloc( 2 );
+ aChoices[0] = aStrings.GetString( 14 );
+ aHelpTexts[0] = aStrings.GetString( 15 );
+ aChoices[1] = aStrings.GetString( 16 );
+ aHelpTexts[1] = aStrings.GetString( 17 );
+ m_aUIProperties[6].Value = getChoiceControlOpt( rtl::OUString(),
+ aHelpTexts,
+ aPrintRangeName,
+ aChoices,
+ 0 );
+
+ // create a an Edit dependent on "Pages" selected
+ vcl::PrinterOptionsHelper::UIControlOptions aPageRangeOpt( aPrintRangeName, 1, sal_True );
+ m_aUIProperties[7].Value = getEditControlOpt( rtl::OUString(),
+ rtl::OUString(),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PageRange" ) ),
+ rtl::OUString(),
+ aPageRangeOpt
+ );
+
+ // "Print only selected sheets" isn't needed because of the "Selected Sheets" choice in "Print content"
+#if 0
+ // create subgroup for sheets
+ m_aUIProperties[8].Value = getSubgroupControlOpt( rtl::OUString( aStrings.GetString( 3 ) ), rtl::OUString() );
+
+ // create a bool option for selected pages only
+ m_aUIProperties[9].Value = getBoolControlOpt( rtl::OUString( aStrings.GetString( 4 ) ),
+ rtl::OUString( aStrings.GetString( 5 ) ),
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsOnlySelectedSheets" ) ),
+ i_bSelectedOnly
+ );
+#endif
+}
+
+void ScPrintUIOptions::SetDefaults()
+{
+ // re-initialize the default values from print options
+
+ const ScPrintOptions& rPrintOpt = SC_MOD()->GetPrintOptions();
+ sal_Int32 nContent = rPrintOpt.GetAllSheets() ? 0 : 1;
+ sal_Bool bSuppress = rPrintOpt.GetSkipEmpty();
+
+ for (sal_Int32 nUIPos=0; nUIPos<m_aUIProperties.getLength(); ++nUIPos)
+ {
+ uno::Sequence<beans::PropertyValue> aUIProp;
+ if ( m_aUIProperties[nUIPos].Value >>= aUIProp )
+ {
+ for (sal_Int32 nPropPos=0; nPropPos<aUIProp.getLength(); ++nPropPos)
+ {
+ rtl::OUString aName = aUIProp[nPropPos].Name;
+ if ( aName.equalsAscii("Property") )
+ {
+ beans::PropertyValue aPropertyValue;
+ if ( aUIProp[nPropPos].Value >>= aPropertyValue )
+ {
+ if ( aPropertyValue.Name.equalsAscii( "PrintContent" ) )
+ {
+ aPropertyValue.Value <<= nContent;
+ aUIProp[nPropPos].Value <<= aPropertyValue;
+ }
+ else if ( aPropertyValue.Name.equalsAscii( "IsIncludeEmptyPages" ) )
+ {
+ ScUnoHelpFunctions::SetBoolInAny( aPropertyValue.Value, ! bSuppress );
+ aUIProp[nPropPos].Value <<= aPropertyValue;
+ }
+ }
+ }
+ }
+ m_aUIProperties[nUIPos].Value <<= aUIProp;
+ }
+ }
+}
+
// static
void ScModelObj::CreateAndSet(ScDocShell* pDocSh)
{
@@ -221,6 +368,7 @@ ScModelObj::ScModelObj( ScDocShell* pDocSh ) :
aPropSet( lcl_GetDocOptPropertyMap() ),
pDocShell( pDocSh ),
pPrintFuncCache( NULL ),
+ pPrinterOptions( NULL ),
maChangesListeners( m_aMutex ),
mnXlsWriteProtPass( 0 )
{
@@ -240,6 +388,7 @@ ScModelObj::~ScModelObj()
xNumberAgg->setDelegator(uno::Reference<uno::XInterface>());
delete pPrintFuncCache;
+ delete pPrinterOptions;
}
uno::Reference< uno::XAggregation> ScModelObj::GetFormatter()
@@ -599,20 +748,65 @@ bool lcl_ParseTarget( const String& rTarget, ScRange& rTargetRange, Rectangle& r
return bRangeValid;
}
-BOOL ScModelObj::FillRenderMarkData( const uno::Any& aSelection, ScMarkData& rMark,
- ScPrintSelectionStatus& rStatus ) const
+BOOL ScModelObj::FillRenderMarkData( const uno::Any& aSelection,
+ const uno::Sequence< beans::PropertyValue >& rOptions,
+ ScMarkData& rMark,
+ ScPrintSelectionStatus& rStatus, String& rPagesStr ) const
{
DBG_ASSERT( !rMark.IsMarked() && !rMark.IsMultiMarked(), "FillRenderMarkData: MarkData must be empty" );
DBG_ASSERT( pDocShell, "FillRenderMarkData: DocShell must be set" );
BOOL bDone = FALSE;
+ uno::Reference<frame::XController> xView;
+
+ // defaults when no options are passed: all sheets, include empty pages
+ sal_Bool bSelectedSheetsOnly = sal_False;
+ sal_Bool bIncludeEmptyPages = sal_True;
+
+ bool bHasPrintContent = false;
+ sal_Int32 nPrintContent = 0; // all sheets / selected sheets / selected cells
+ sal_Int32 nPrintRange = 0; // all pages / pages
+ rtl::OUString aPageRange; // "pages" edit value
+
+ for( sal_Int32 i = 0, nLen = rOptions.getLength(); i < nLen; i++ )
+ {
+ if( rOptions[i].Name.equalsAscii( "IsOnlySelectedSheets" ) )
+ {
+ rOptions[i].Value >>= bSelectedSheetsOnly;
+ }
+ else if( rOptions[i].Name.equalsAscii( "IsIncludeEmptyPages" ) )
+ {
+ rOptions[i].Value >>= bIncludeEmptyPages;
+ }
+ else if( rOptions[i].Name.equalsAscii( "PageRange" ) )
+ {
+ rOptions[i].Value >>= aPageRange;
+ }
+ else if( rOptions[i].Name.equalsAscii( "PrintRange" ) )
+ {
+ rOptions[i].Value >>= nPrintRange;
+ }
+ else if( rOptions[i].Name.equalsAscii( "PrintContent" ) )
+ {
+ bHasPrintContent = true;
+ rOptions[i].Value >>= nPrintContent;
+ }
+ else if( rOptions[i].Name.equalsAscii( "View" ) )
+ {
+ rOptions[i].Value >>= xView;
+ }
+ }
+
+ // "Print Content" selection wins over "Selected Sheets" option
+ if ( bHasPrintContent )
+ bSelectedSheetsOnly = ( nPrintContent != 0 );
+
uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
if ( xInterface.is() )
{
ScCellRangesBase* pSelObj = ScCellRangesBase::getImplementation( xInterface );
uno::Reference< drawing::XShapes > xShapes( xInterface, uno::UNO_QUERY );
-
if ( pSelObj && pSelObj->GetDocShell() == pDocShell )
{
BOOL bSheet = ( ScTableSheetObj::getImplementation( xInterface ) != NULL );
@@ -685,12 +879,41 @@ BOOL ScModelObj::FillRenderMarkData( const uno::Any& aSelection, ScMarkData& rMa
// other selection types aren't supported
}
+ // restrict to selected sheets if a view is available
+ if ( bSelectedSheetsOnly && xView.is() )
+ {
+ ScTabViewObj* pViewObj = ScTabViewObj::getImplementation( xView );
+ if (pViewObj)
+ {
+ ScTabViewShell* pViewSh = pViewObj->GetViewShell();
+ if (pViewSh)
+ {
+ const ScMarkData& rViewMark = pViewSh->GetViewData()->GetMarkData();
+ SCTAB nTabCount = pDocShell->GetDocument()->GetTableCount();
+ for (SCTAB nTab = 0; nTab < nTabCount; nTab++)
+ if (!rViewMark.GetTableSelect(nTab))
+ rMark.SelectTable( nTab, FALSE );
+ }
+ }
+ }
+
+ ScPrintOptions aNewOptions;
+ aNewOptions.SetSkipEmpty( !bIncludeEmptyPages );
+ aNewOptions.SetAllSheets( !bSelectedSheetsOnly );
+ rStatus.SetOptions( aNewOptions );
+
+ // "PrintRange" enables (1) or disables (0) the "PageRange" edit
+ if ( nPrintRange == 1 )
+ rPagesStr = aPageRange;
+ else
+ rPagesStr.Erase();
+
return bDone;
}
sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection,
- const uno::Sequence<beans::PropertyValue>& /* xOptions */ )
+ const uno::Sequence<beans::PropertyValue>& rOptions )
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
ScUnoGuard aGuard;
@@ -699,7 +922,8 @@ sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection,
ScMarkData aMark;
ScPrintSelectionStatus aStatus;
- if ( !FillRenderMarkData( aSelection, aMark, aStatus ) )
+ String aPagesStr;
+ if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
return 0;
// The same ScPrintFuncCache object in pPrintFuncCache is used as long as
@@ -711,11 +935,37 @@ sal_Int32 SAL_CALL ScModelObj::getRendererCount( const uno::Any& aSelection,
delete pPrintFuncCache;
pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
}
- return pPrintFuncCache->GetPageCount();
+ sal_Int32 nPages = pPrintFuncCache->GetPageCount();
+
+ sal_Int32 nSelectCount = nPages;
+ if ( aPagesStr.Len() )
+ {
+ MultiSelection aPageRanges( aPagesStr );
+ aPageRanges.SetTotalRange( Range( 1, nPages ) );
+ nSelectCount = aPageRanges.GetSelectCount();
+ }
+ return nSelectCount;
}
-uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 nRenderer,
- const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& /* xOptions */ )
+sal_Int32 lcl_GetRendererNum( sal_Int32 nSelRenderer, const String& rPagesStr, sal_Int32 nTotalPages )
+{
+ if ( !rPagesStr.Len() )
+ return nSelRenderer;
+
+ MultiSelection aPageRanges( rPagesStr );
+ aPageRanges.SetTotalRange( Range( 1, nTotalPages ) );
+
+ sal_Int32 nSelected = aPageRanges.FirstSelected();
+ while ( nSelRenderer > 0 )
+ {
+ nSelected = aPageRanges.NextSelected();
+ --nSelRenderer;
+ }
+ return nSelected - 1; // selection is 1-based
+}
+
+uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 nSelRenderer,
+ const uno::Any& aSelection, const uno::Sequence<beans::PropertyValue>& rOptions )
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
ScUnoGuard aGuard;
@@ -724,7 +974,8 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32
ScMarkData aMark;
ScPrintSelectionStatus aStatus;
- if ( !FillRenderMarkData( aSelection, aMark, aStatus ) )
+ String aPagesStr;
+ if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
throw lang::IllegalArgumentException();
if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
@@ -733,8 +984,33 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32
pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
}
long nTotalPages = pPrintFuncCache->GetPageCount();
+ sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
if ( nRenderer >= nTotalPages )
- throw lang::IllegalArgumentException();
+ {
+ if ( nSelRenderer == 0 )
+ {
+ // getRenderer(0) is used to query the settings, so it must always return something
+
+ SCTAB nCurTab = 0; //! use current sheet from view?
+ ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab );
+ Size aTwips = aDefaultFunc.GetPageSize();
+ awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) );
+
+ uno::Sequence<beans::PropertyValue> aSequence(1);
+ beans::PropertyValue* pArray = aSequence.getArray();
+ pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE );
+ pArray[0].Value <<= aPageSize;
+
+ if( ! pPrinterOptions )
+ pPrinterOptions = new ScPrintUIOptions;
+ else
+ pPrinterOptions->SetDefaults();
+ pPrinterOptions->appendPrintUIOptions( aSequence );
+ return aSequence;
+ }
+ else
+ throw lang::IllegalArgumentException();
+ }
// printer is used as device (just for page layout), draw view is not needed
@@ -748,7 +1024,7 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32
pSelRange = &aRange;
}
ScPrintFunc aFunc( pDocShell, pDocShell->GetPrinter(), nTab,
- pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange );
+ pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
aFunc.SetRenderFlag( TRUE );
Range aPageRange( nRenderer+1, nRenderer+1 );
@@ -779,10 +1055,21 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32
pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_SOURCERANGE );
pArray[1].Value <<= aRangeAddress;
}
+
+ #if 0
+ const ScPrintOptions& rPrintOpt =
+ #endif
+ // FIXME: is this for side effects ?
+ SC_MOD()->GetPrintOptions();
+ if( ! pPrinterOptions )
+ pPrinterOptions = new ScPrintUIOptions;
+ else
+ pPrinterOptions->SetDefaults();
+ pPrinterOptions->appendPrintUIOptions( aSequence );
return aSequence;
}
-void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelection,
+void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelection,
const uno::Sequence<beans::PropertyValue>& rOptions )
throw(lang::IllegalArgumentException, uno::RuntimeException)
{
@@ -792,7 +1079,8 @@ void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelectio
ScMarkData aMark;
ScPrintSelectionStatus aStatus;
- if ( !FillRenderMarkData( aSelection, aMark, aStatus ) )
+ String aPagesStr;
+ if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) )
throw lang::IllegalArgumentException();
if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) )
@@ -801,6 +1089,7 @@ void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelectio
pPrintFuncCache = new ScPrintFuncCache( pDocShell, aMark, aStatus );
}
long nTotalPages = pPrintFuncCache->GetPageCount();
+ sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages );
if ( nRenderer >= nTotalPages )
throw lang::IllegalArgumentException();
@@ -835,7 +1124,7 @@ void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelectio
// to increase performance, ScPrintState might be used here for subsequent
// pages of the same sheet
- ScPrintFunc aFunc( pDev, pDocShell, nTab, pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange );
+ ScPrintFunc aFunc( pDev, pDocShell, nTab, pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() );
aFunc.SetDrawView( pDrawView );
aFunc.SetRenderFlag( TRUE );
if( aStatus.GetMode() == SC_PRINTSEL_RANGE_EXCLUSIVELY_OLE_AND_DRAW_OBJECTS )
@@ -849,11 +1138,11 @@ void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelectio
long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab );
long nTabStart = pPrintFuncCache->GetTabStart( nTab );
+ vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
if ( nRenderer == nTabStart )
{
// first page of a sheet: add outline item for the sheet name
- vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
if ( pPDFData && pPDFData->GetIsExportBookmarks() )
{
// the sheet starts at the top of the page
@@ -866,7 +1155,7 @@ void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelectio
}
//--->i56629
// add the named destination stuff
- if( pPDFData->GetIsExportNamedDestinations() )
+ if( pPDFData && pPDFData->GetIsExportNamedDestinations() )
{
Rectangle aArea( pDev->PixelToLogic( Rectangle( 0,0,0,0 ) ) );
String aTabName;
@@ -881,7 +1170,6 @@ void SAL_CALL ScModelObj::render( sal_Int32 nRenderer, const uno::Any& aSelectio
// resolve the hyperlinks for PDF export
- vcl::PDFExtOutDevData* pPDFData = PTR_CAST( vcl::PDFExtOutDevData, pDev->GetExtOutDevData() );
if ( pPDFData )
{
// iterate over the hyperlinks that were output for this page