diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx index c7149b0ca534..c4e133297e95 100644 --- a/filter/source/pdf/impdialog.cxx +++ b/filter/source/pdf/impdialog.cxx @@ -108,8 +108,10 @@ ImpPDFTabDialog::ImpPDFTabDialog(weld::Window* pParent, const Sequence< Property mbCanCopyOrExtract( false ), mbCanExtractForAccessibility( true ), - mbIsRangeChecked( false ), + mbIsPageRangeChecked( false ), msPageRange( ' ' ), + mbIsSheetRangeChecked( false ), + msSheetRange( ' ' ), mbSelectionIsChecked( false ), mbExportRelativeFsysLinks( false ), @@ -506,8 +508,10 @@ Sequence< PropertyValue > ImpPDFTabDialog::GetFilterData() comphelper::makePropertyValue("RestrictPermissions", mbRestrictPermissions), comphelper::makePropertyValue("PreparedPermissionPassword", maPreparedOwnerPassword) }; - if( mbIsRangeChecked ) + if( mbIsPageRangeChecked ) aRet.push_back(comphelper::makePropertyValue("PageRange", msPageRange)); + if( mbIsSheetRangeChecked ) + aRet.push_back(comphelper::makePropertyValue("SheetRange", msSheetRange)); else if( mbSelectionIsChecked ) aRet.push_back(comphelper::makePropertyValue("Selection", maSelection)); @@ -531,9 +535,11 @@ ImpPDFTabGeneralPage::ImpPDFTabGeneralPage(weld::Container* pPage, weld::DialogC , mbIsWriter(false) , mpParent(nullptr) , mxRbAll(m_xBuilder->weld_radio_button("all")) - , mxRbRange(m_xBuilder->weld_radio_button("range")) + , mxRbPageRange(m_xBuilder->weld_radio_button("pagerange")) + , mxRbSheetRange(m_xBuilder->weld_radio_button("sheetrange")) , mxRbSelection(m_xBuilder->weld_radio_button("selection")) , mxEdPages(m_xBuilder->weld_entry("pages")) + , mxEdSheets(m_xBuilder->weld_entry("sheets")) , mxRbLosslessCompression(m_xBuilder->weld_radio_button("losslesscompress")) , mxRbJPEGCompression(m_xBuilder->weld_radio_button("jpegcompress")) , mxQualityFrame(m_xBuilder->weld_widget("qualityframe")) @@ -564,7 +570,7 @@ ImpPDFTabGeneralPage::ImpPDFTabGeneralPage(weld::Container* pPage, weld::DialogC , mxFtWatermark(m_xBuilder->weld_label("watermarklabel")) , mxEdWatermark(m_xBuilder->weld_entry("watermarkentry")) , mxSlidesFt(m_xBuilder->weld_label("slides")) - , mxSheetsFt(m_xBuilder->weld_label("selectedsheets")) + , mxSheetsSelectionFt(m_xBuilder->weld_label("selectedsheets")) { } @@ -579,11 +585,13 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) mpParent = pParent; // init this class data - mxRbRange->connect_toggled( LINK( this, ImpPDFTabGeneralPage, TogglePagesHdl ) ); + mxRbPageRange->connect_toggled( LINK( this, ImpPDFTabGeneralPage, TogglePagesHdl ) ); + mxRbSheetRange->connect_toggled( LINK( this, ImpPDFTabGeneralPage, ToggleSheetsHdl ) ); mxRbAll->set_active(true); mxRbAll->connect_toggled( LINK( this, ImpPDFTabGeneralPage, ToggleAllHdl ) ); TogglePagesHdl(); + ToggleSheetsHdl(); mxRbSelection->set_sensitive( pParent->mbSelectionPresent ); if ( pParent->mbSelectionPresent ) @@ -687,7 +695,7 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) if ( mbIsPresentation ) { - mxRbRange->set_label(mxSlidesFt->get_label()); + mxRbPageRange->set_label(mxSlidesFt->get_label()); mxCbExportNotesPages->show(); mxCbExportNotesPages->set_active(pParent->mbExportNotesPages); mxCbExportNotesPages->connect_toggled( LINK(this, ImpPDFTabGeneralPage, ToggleExportNotesPagesHdl ) ); @@ -714,10 +722,13 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) if( mbIsSpreadsheet ) { - mxRbSelection->set_label(mxSheetsFt->get_label()); + mxRbSelection->set_label(mxSheetsSelectionFt->get_label()); // tdf#105965 Make Selection/Selected sheets the default PDF export range setting for spreadsheets mxRbSelection->set_active(true); + mxRbSheetRange->show(); + mxEdSheets->show(); + mxCbSinglePageSheets->show(); mxCbSinglePageSheets->set_active(pParent->mbSinglePageSheets); mxCbSinglePageSheets->set_sensitive(!pParent->maConfigItem.IsReadOnly("SinglePageSheets")); @@ -726,6 +737,9 @@ void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent) { mxCbSinglePageSheets->hide(); mxCbSinglePageSheets->set_active(false); + mxRbSheetRange->hide(); + mxRbSheetRange->set_active(false); + mxEdSheets->hide(); } mxCbExportEmptyPages->set_active(!pParent->mbIsSkipEmptyPages); @@ -773,12 +787,17 @@ void ImpPDFTabGeneralPage::GetFilterConfigItem( ImpPDFTabDialog* pParent ) pParent->mbIsExportPlaceholders = mxCbExportPlaceholders->get_active(); pParent->mbAddStream = mxCbAddStream->get_visible() && mxCbAddStream->get_active(); - pParent->mbIsRangeChecked = false; - if( mxRbRange->get_active() ) + pParent->mbIsPageRangeChecked = false; + if( mxRbPageRange->get_active() ) { - pParent->mbIsRangeChecked = true; + pParent->mbIsPageRangeChecked = true; pParent->msPageRange = mxEdPages->get_text(); //FIXME all right on other languages ? } + else if ( mxRbSheetRange->get_active() ) + { + pParent->mbIsSheetRangeChecked = true; + pParent->msSheetRange = mxEdSheets->get_text(); + } else if( mxRbSelection->get_active() ) { pParent->mbSelectionIsChecked = mxRbSelection->get_active(); @@ -841,6 +860,12 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, TogglePagesHdl, weld::Toggleable&, void) EnableExportNotesPages(); } +IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleSheetsHdl, weld::Toggleable&, void) +{ + ToggleSheetsHdl(); + EnableExportNotesPages(); +} + IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleSelectionHdl, weld::Toggleable&, void) { EnableExportNotesPages(); @@ -848,11 +873,18 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleSelectionHdl, weld::Toggleable&, voi void ImpPDFTabGeneralPage::TogglePagesHdl() { - mxEdPages->set_sensitive( mxRbRange->get_active() ); - if (mxRbRange->get_active()) + mxEdPages->set_sensitive( mxRbPageRange->get_active() ); + if (mxRbPageRange->get_active()) mxEdPages->grab_focus(); } +void ImpPDFTabGeneralPage::ToggleSheetsHdl() +{ + mxEdSheets->set_sensitive( mxRbSheetRange->get_active() ); + if (mxRbSheetRange->get_active()) + mxEdSheets->grab_focus(); +} + void ImpPDFTabGeneralPage::EnableExportNotesPages() { if ( mbIsPresentation ) @@ -915,7 +947,8 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleAddStreamHdl, weld::Toggleable&, voi if( mxCbAddStream->get_active() ) { mxRbAll->set_active(true); - mxRbRange->set_sensitive( false ); + mxRbPageRange->set_sensitive( false ); + mxRbSheetRange->set_sensitive( false ); mxRbSelection->set_sensitive( false ); mxEdPages->set_sensitive( false ); mxRbAll->set_sensitive( false ); @@ -923,7 +956,8 @@ IMPL_LINK_NOARG(ImpPDFTabGeneralPage, ToggleAddStreamHdl, weld::Toggleable&, voi else { mxRbAll->set_sensitive(true); - mxRbRange->set_sensitive(true); + mxRbPageRange->set_sensitive(true); + mxRbSheetRange->set_sensitive(true); mxRbSelection->set_sensitive(true); } } diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx index 8cbfc0af987f..95d25f99d705 100644 --- a/filter/source/pdf/impdialog.hxx +++ b/filter/source/pdf/impdialog.hxx @@ -128,8 +128,10 @@ class ImpPDFTabDialog final : public SfxTabDialogController bool mbCanExtractForAccessibility; css::uno::Reference< css::beans::XMaterialHolder > mxPreparedPasswords; - bool mbIsRangeChecked; + bool mbIsPageRangeChecked; OUString msPageRange; + bool mbIsSheetRangeChecked; + OUString msSheetRange; bool mbSelectionIsChecked; bool mbExportRelativeFsysLinks; @@ -184,9 +186,11 @@ class ImpPDFTabGeneralPage : public SfxTabPage ImpPDFTabDialog* mpParent; std::unique_ptr mxRbAll; - std::unique_ptr mxRbRange; + std::unique_ptr mxRbPageRange; + std::unique_ptr mxRbSheetRange; std::unique_ptr mxRbSelection; std::unique_ptr mxEdPages; + std::unique_ptr mxEdSheets; std::unique_ptr mxRbLosslessCompression; std::unique_ptr mxRbJPEGCompression; std::unique_ptr mxQualityFrame; @@ -217,10 +221,11 @@ class ImpPDFTabGeneralPage : public SfxTabPage std::unique_ptr mxFtWatermark; std::unique_ptr mxEdWatermark; std::unique_ptr mxSlidesFt; - std::unique_ptr mxSheetsFt; + std::unique_ptr mxSheetsSelectionFt; DECL_LINK(ToggleAllHdl, weld::Toggleable&, void); DECL_LINK(TogglePagesHdl, weld::Toggleable&, void); + DECL_LINK(ToggleSheetsHdl, weld::Toggleable&, void); DECL_LINK(ToggleSelectionHdl, weld::Toggleable&, void); DECL_LINK(ToggleCompressionHdl, weld::Toggleable&, void); DECL_LINK(ToggleReduceImageResolutionHdl, weld::Toggleable&, void); @@ -230,6 +235,7 @@ class ImpPDFTabGeneralPage : public SfxTabPage DECL_LINK(ToggleExportNotesPagesHdl, weld::Toggleable&, void); void TogglePagesHdl(); + void ToggleSheetsHdl(); void EnableExportNotesPages(); DECL_LINK(TogglePDFVersionOrUniversalAccessibilityHandle, weld::Toggleable&, void); diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index 7d07f8182bdc..1459590b2f23 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -518,6 +519,14 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& { if ( rProp.Name == "PageRange" ) rProp.Value >>= aPageRange; + else if ( rProp.Name == "SheetRange" ) + { + Reference< frame::XController > xController( Reference< frame::XModel >( mxSrcDoc, UNO_QUERY_THROW )->getCurrentController() ); + Reference< sheet::XSheetRange > xView( xController, UNO_QUERY); + OUString aSheetRange; + rProp.Value >>= aSheetRange; + aSelection = xView->getSelectionFromString(aSheetRange); + } else if ( rProp.Name == "Selection" ) aSelection = rProp.Value; else if ( rProp.Name == "UseLosslessCompression" ) diff --git a/filter/uiconfig/ui/pdfgeneralpage.ui b/filter/uiconfig/ui/pdfgeneralpage.ui index 40c5fc4eb47d..f09113793d07 100644 --- a/filter/uiconfig/ui/pdfgeneralpage.ui +++ b/filter/uiconfig/ui/pdfgeneralpage.ui @@ -60,8 +60,8 @@ - - _Pages: + + _Pages: True True False @@ -74,8 +74,8 @@ - - Exports the pages you type in the box. + + Exports the pages you type in the box. @@ -84,6 +84,31 @@ 1 + + + _Sheets: + True + True + False + start + center + True + True + all + + + + + + Exports the sheets you type in the box. + + + + + 0 + 2 + + _Selection @@ -114,7 +139,7 @@ 5 True - + @@ -127,12 +152,33 @@ 1 + + + True + True + True + 5 + True + + + + + + Exports the sheets you type in the box. + + + + + 1 + 2 + + False True start - Slides: + _Slides: 0 @@ -1040,7 +1086,8 @@ - + + @@ -1051,6 +1098,7 @@ + diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 186c68d500fb..5399c70482e9 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -3555,6 +3555,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/sheet,\ XScenarios \ XScenariosSupplier \ XSelectedSheetsSupplier \ + XSheetRange \ XSheetAnnotation \ XSheetAnnotationAnchor \ XSheetAnnotationShapeSupplier \ diff --git a/offapi/com/sun/star/sheet/XSheetRange.idl b/offapi/com/sun/star/sheet/XSheetRange.idl new file mode 100644 index 000000000000..6a8070ae1e15 --- /dev/null +++ b/offapi/com/sun/star/sheet/XSheetRange.idl @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + + +module com { module sun { module star { module sheet { + + +/** + @since LibreOffice 24.2 + */ +interface XSheetRange: com::sun::star::uno::XInterface +{ + /** @returns + selection from given string range + +

Example: '2-5,7' returns selection of pages/sheets/slides 2,3,4,5,7 + + */ + any getSelectionFromString( [in] string aStrRange ); + +}; + + +}; }; }; }; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/viewuno.hxx b/sc/inc/viewuno.hxx index 027b4753a944..483f9631551f 100644 --- a/sc/inc/viewuno.hxx +++ b/sc/inc/viewuno.hxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -136,6 +137,7 @@ class ScTabViewObj final : public ScViewPaneBase, public css::sheet::XViewSplitable, public css::sheet::XViewFreezable, public css::sheet::XRangeSelection, + public css::sheet::XSheetRange, public css::datatransfer::XTransferableSupplier, public css::sheet::XSelectedSheetsSupplier { @@ -196,6 +198,9 @@ public: virtual void SAL_CALL addSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener >& xListener ) override; virtual void SAL_CALL removeSelectionChangeListener( const css::uno::Reference< css::view::XSelectionChangeListener >& xListener ) override; + // XSheetRange + virtual css::uno::Any SAL_CALL getSelectionFromString( const OUString& aStrRange ) override; + //! XPrintable? // XPropertySet diff --git a/sc/qa/uitest/calc_tests4/exportToPDF.py b/sc/qa/uitest/calc_tests4/exportToPDF.py index a635ee60a5d0..777d9899e421 100644 --- a/sc/qa/uitest/calc_tests4/exportToPDF.py +++ b/sc/qa/uitest/calc_tests4/exportToPDF.py @@ -53,7 +53,7 @@ class exportToPDF(UITestCase): self.assertEqual("true", get_state_as_dict(xDialog.getChild(child))['Checked']) nonCheckedChildren = ['all', 'changecomment', 'changeform', 'changeinsdel', 'changenone', 'contfacinglayout', 'contlayout', 'fitvis', 'fitwidth', - 'fitwin', 'fitzoom', 'losslesscompress', 'openinternet', 'openpdf', 'pageonly', 'printlow', 'printnone', 'range', + 'fitwin', 'fitzoom', 'losslesscompress', 'openinternet', 'openpdf', 'pageonly', 'printlow', 'printnone', 'pagerange', 'sheetrange', 'singlelayout', 'thumbs', 'visiblebookmark'] for child in nonCheckedChildren: diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index c906f39336f5..257002fb704b 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -2141,7 +2141,18 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec if (bSinglePageSheets) nTotalPages = pDocShell->GetDocument().GetTableCount(); - sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages ); + // if no pages counted then user must be trying to print sheet/selection without any content (i.e empty) + if (nTotalPages == 0) + { + ScPrintOptions aNewOptions = aStatus.GetOptions(); + aNewOptions.SetSkipEmpty(false); + aStatus.SetOptions(aNewOptions); + + pPrintFuncCache.reset(new ScPrintFuncCache( pDocShell, aMark, aStatus )); + nTotalPages = pPrintFuncCache->GetPageCount(); + } + + sal_Int32 nRenderer = lcl_GetRendererNum( nSelRenderer, aPagesStr, nTotalPages ); // 0, "", 0 if ( nRenderer < 0 ) throw lang::IllegalArgumentException(); diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index 2d066bcfc26b..51a931650686 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -485,6 +486,7 @@ uno::Any SAL_CALL ScTabViewObj::queryInterface( const uno::Type& rType ) static_cast(this), static_cast(this), static_cast(this), + static_cast(this), static_cast(this), static_cast(this)); if ( aReturn.hasValue() ) @@ -594,6 +596,7 @@ uno::Sequence SAL_CALL ScTabViewObj::getTypes() cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get(), + cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get(), @@ -950,6 +953,35 @@ uno::Any SAL_CALL ScTabViewObj::getSelection() return uno::Any(uno::Reference(cppu::getXWeak(pObj.get()))); } +uno::Any SAL_CALL ScTabViewObj::getSelectionFromString( const OUString& aStrRange ) +{ + ScDocShell* pDocSh = GetViewShell()->GetViewData().GetDocShell(); + const sal_Int16 nTabCount = pDocSh->GetDocument().GetTableCount(); + + StringRangeEnumerator aRangeEnum(aStrRange , 0, nTabCount-1); + + // iterate through sheet range + + StringRangeEnumerator::Iterator aIter = aRangeEnum.begin(); + StringRangeEnumerator::Iterator aEnd = aRangeEnum.end(); + + ScRangeListRef aRangeList = new ScRangeList; + + while ( aIter != aEnd ) + { + ScRange currentTab(SCCOL(0), SCROW(0), SCTAB(*aIter)); + aRangeList->push_back(currentTab); + ++aIter; + } + + rtl::Reference pObj = new ScCellRangesObj(pDocSh, *aRangeList); + + // SetCursorOnly tells the range the specific cells selected are irelevant - maybe could rename? + pObj->SetCursorOnly(true); + + return uno::Any(uno::Reference(static_cast(pObj.get()))); +} + // XEnumerationAccess uno::Reference SAL_CALL ScTabViewObj::createEnumeration() diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx index a61520875238..697a03f8a315 100644 --- a/sc/source/ui/view/printfun.cxx +++ b/sc/source/ui/view/printfun.cxx @@ -713,7 +713,7 @@ bool ScPrintFunc::AdjustPrintArea( bool bNew ) { nStartCol = 0; nStartRow = 0; - if (!rDoc.GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes )) + if (!rDoc.GetPrintArea( nPrintTab, nEndCol, nEndRow, bNotes ) && aTableParam.bSkipEmpty) return false; // nothing bPrintAreaValid = true; } diff --git a/sd/qa/uitest/impress_tests/exportToPDF.py b/sd/qa/uitest/impress_tests/exportToPDF.py index 429e28df4f0d..e654f608947b 100644 --- a/sd/qa/uitest/impress_tests/exportToPDF.py +++ b/sd/qa/uitest/impress_tests/exportToPDF.py @@ -55,7 +55,7 @@ class exportToPDF(UITestCase): self.assertEqual("true", get_state_as_dict(xDialog.getChild(child))['Checked']) nonCheckedChildren = ['changecomment', 'changeform', 'changeinsdel', 'changenone', 'contfacinglayout', 'contlayout', 'fitvis', - 'fitwidth', 'fitwin', 'fitzoom', 'losslesscompress', 'openinternet', 'openpdf', 'pageonly', 'printlow', 'printnone', 'range', + 'fitwidth', 'fitwin', 'fitzoom', 'losslesscompress', 'openinternet', 'openpdf', 'pageonly', 'printlow', 'printnone', 'pagerange', 'selection', 'singlelayout', 'thumbs', 'visiblebookmark'] for child in nonCheckedChildren: diff --git a/sw/qa/uitest/writer_tests4/exportToPDF.py b/sw/qa/uitest/writer_tests4/exportToPDF.py index ef628d4eea68..a075e6a4c773 100644 --- a/sw/qa/uitest/writer_tests4/exportToPDF.py +++ b/sw/qa/uitest/writer_tests4/exportToPDF.py @@ -51,7 +51,7 @@ class exportToPDF(UITestCase): self.assertEqual("true", get_state_as_dict(xDialog.getChild(child))['Checked']) nonCheckedChildren = ['changecomment', 'changeform', 'changeinsdel', 'changenone', 'contfacinglayout', 'contlayout', 'fitvis', - 'fitwidth', 'fitwin', 'fitzoom', 'losslesscompress', 'openinternet', 'openpdf', 'pageonly', 'printlow', 'printnone', 'range', + 'fitwidth', 'fitwin', 'fitzoom', 'losslesscompress', 'openinternet', 'openpdf', 'pageonly', 'printlow', 'printnone', 'pagerange', 'selection', 'singlelayout', 'thumbs', 'visiblebookmark'] for child in nonCheckedChildren: