/* -*- 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // preview control for presentation layout #include #include #include #include #include #include #include #include #include #include #include namespace sd { namespace { class PresLayoutPreview : public weld::CustomWidgetController { private: SdPage* mpMaster; HeaderFooterSettings maSettings; Size maPageSize; ::tools::Rectangle maOutRect; private: void Paint(vcl::RenderContext& rRenderContext, SdrTextObj const * pObj, bool bVisible, bool bDotted = false); public: explicit PresLayoutPreview(); virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override; virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override; void init(SdPage* pMaster); void update(HeaderFooterSettings const & rSettings); }; } } // tab page for slide & header'n'notes namespace sd { const int nDateTimeFormatsCount = 12; namespace { struct DateAndTimeFormat { SvxDateFormat meDateFormat; SvxTimeFormat meTimeFormat; }; } DateAndTimeFormat const nDateTimeFormats[nDateTimeFormatsCount] = { { SvxDateFormat::A, SvxTimeFormat::AppDefault }, { SvxDateFormat::B, SvxTimeFormat::AppDefault }, { SvxDateFormat::C, SvxTimeFormat::AppDefault }, { SvxDateFormat::D, SvxTimeFormat::AppDefault }, { SvxDateFormat::E, SvxTimeFormat::AppDefault }, { SvxDateFormat::F, SvxTimeFormat::AppDefault }, { SvxDateFormat::A, SvxTimeFormat::HH24_MM }, { SvxDateFormat::A, SvxTimeFormat::HH12_MM }, { SvxDateFormat::AppDefault, SvxTimeFormat::HH24_MM }, { SvxDateFormat::AppDefault, SvxTimeFormat::HH24_MM_SS }, { SvxDateFormat::AppDefault, SvxTimeFormat::HH12_MM }, { SvxDateFormat::AppDefault, SvxTimeFormat::HH12_MM_SS }, }; class HeaderFooterTabPage { private: SdDrawDocument* mpDoc; LanguageType meOldLanguage; bool mbHandoutMode; std::unique_ptr mxBuilder; std::unique_ptr mxContainer; std::unique_ptr mxFTIncludeOn; std::unique_ptr mxCBHeader; std::unique_ptr mxHeaderBox; std::unique_ptr mxTBHeader; std::unique_ptr mxCBDateTime; std::unique_ptr mxRBDateTimeFixed; std::unique_ptr mxRBDateTimeAutomatic; std::unique_ptr mxTBDateTimeFixed; std::unique_ptr mxCBDateTimeFormat; std::unique_ptr mxFTDateTimeLanguage; std::unique_ptr mxCBDateTimeLanguage; std::unique_ptr mxCBFooter; std::unique_ptr mxFooterBox; std::unique_ptr mxTBFooter; std::unique_ptr mxCBSlideNumber; std::unique_ptr mxCBNotOnTitle; std::unique_ptr mxReplacementA; std::unique_ptr mxReplacementB; std::unique_ptr mxCTPreview; std::unique_ptr mxCTPreviewWin; DECL_LINK( UpdateOnToggleHdl, weld::Toggleable&, void ); DECL_LINK( LanguageChangeHdl, weld::ComboBox&, void ); void FillFormatList(sal_Int32 nSelectedPos); void GetOrSetDateTimeLanguage( LanguageType &rLanguage, bool bSet ); void GetOrSetDateTimeLanguage( LanguageType &rLanguage, bool bSet, SdPage* pPage ); public: HeaderFooterTabPage(weld::Container* pParent, SdDrawDocument* pDoc, SdPage* pActualPage, bool bHandoutMode ); void init( const HeaderFooterSettings& rSettings, bool bNotOnTitle ); void getData( HeaderFooterSettings& rSettings, bool& rNotOnTitle ); void update(); }; } using namespace ::sd; HeaderFooterDialog::HeaderFooterDialog(ViewShell* pViewShell, weld::Window* pParent, SdDrawDocument* pDoc, SdPage* pCurrentPage) : GenericDialogController(pParent, "modules/simpress/ui/headerfooterdialog.ui", "HeaderFooterDialog") , mpDoc( pDoc ) , mpCurrentPage( pCurrentPage ) , mpViewShell( pViewShell ) , mxTabCtrl(m_xBuilder->weld_notebook("tabcontrol")) , mxPBApplyToAll(m_xBuilder->weld_button("apply_all")) , mxPBApply(m_xBuilder->weld_button("apply")) , mxPBCancel(m_xBuilder->weld_button("cancel")) { SdPage* pSlide; SdPage* pNotes; if( pCurrentPage->GetPageKind() == PageKind::Standard ) { pSlide = pCurrentPage; pNotes = static_cast(pDoc->GetPage( pCurrentPage->GetPageNum() + 1 )); } else if( pCurrentPage->GetPageKind() == PageKind::Notes ) { pNotes = pCurrentPage; pSlide = static_cast(pDoc->GetPage( pCurrentPage->GetPageNum() -1 )); mpCurrentPage = pSlide; } else { // handout pSlide = pDoc->GetSdPage( 0, PageKind::Standard ); pNotes = pDoc->GetSdPage( 0, PageKind::Notes ); mpCurrentPage = nullptr; } mxSlideTabPage.reset(new HeaderFooterTabPage(mxTabCtrl->get_page("slides"), pDoc, pSlide, false)); mxNotesHandoutsTabPage.reset(new HeaderFooterTabPage(mxTabCtrl->get_page("notes"), pDoc, pNotes, true)); pDoc->StopWorkStartupDelay(); mxTabCtrl->show(); ActivatePageHdl(mxTabCtrl->get_current_page_ident()); mxTabCtrl->connect_enter_page( LINK( this, HeaderFooterDialog, ActivatePageHdl ) ); mxPBApplyToAll->connect_clicked( LINK( this, HeaderFooterDialog, ClickApplyToAllHdl ) ); mxPBApply->connect_clicked( LINK( this, HeaderFooterDialog, ClickApplyHdl ) ); mxPBCancel->connect_clicked( LINK( this, HeaderFooterDialog, ClickCancelHdl ) ); maSlideSettings = pSlide->getHeaderFooterSettings(); const HeaderFooterSettings& rTitleSettings = mpDoc->GetSdPage(0, PageKind::Standard)->getHeaderFooterSettings(); bool bNotOnTitle = !rTitleSettings.mbFooterVisible && !rTitleSettings.mbSlideNumberVisible && !rTitleSettings.mbDateTimeVisible; mxSlideTabPage->init( maSlideSettings, bNotOnTitle ); maNotesHandoutSettings = pNotes->getHeaderFooterSettings(); mxNotesHandoutsTabPage->init( maNotesHandoutSettings, false ); } HeaderFooterDialog::~HeaderFooterDialog() { } IMPL_LINK(HeaderFooterDialog, ActivatePageHdl, const OString&, rIdent, void) { mxPBApply->set_visible(rIdent == "slides"); mxPBApply->set_sensitive(mpCurrentPage != nullptr); } IMPL_LINK_NOARG(HeaderFooterDialog, ClickApplyToAllHdl, weld::Button&, void) { ApplyToAll(); } IMPL_LINK_NOARG(HeaderFooterDialog, ClickApplyHdl, weld::Button&, void) { Apply(); } IMPL_LINK_NOARG(HeaderFooterDialog, ClickCancelHdl, weld::Button&, void) { m_xDialog->response(RET_CANCEL); } short HeaderFooterDialog::run() { short nRet = GenericDialogController::run(); if (nRet) mpViewShell->GetDocSh()->SetModified(); return nRet; } void HeaderFooterDialog::ApplyToAll() { OString tabId = mxTabCtrl->get_current_page_ident(); apply(true, tabId == "slides"); m_xDialog->response(RET_OK); } void HeaderFooterDialog::Apply() { OString tabId = mxTabCtrl->get_current_page_ident(); apply(false, tabId == "slides"); m_xDialog->response(RET_OK); } void HeaderFooterDialog::apply( bool bToAll, bool bForceSlides ) { std::unique_ptr pUndoGroup(new SdUndoGroup(mpDoc)); OUString aComment( m_xDialog->get_title() ); pUndoGroup->SetComment( aComment ); HeaderFooterSettings aNewSettings; bool bNewNotOnTitle; // change slide settings first ... mxSlideTabPage->getData( aNewSettings, bNewNotOnTitle ); // only if we pressed apply or apply all on the slide tab page or if the slide settings // have been changed if( bForceSlides || !(aNewSettings == maSlideSettings) ) { // apply to all slides if( bToAll ) { int nPageCount = mpDoc->GetSdPageCount( PageKind::Standard ); int nPage; for( nPage = 0; nPage < nPageCount; nPage++ ) { SdPage* pPage = mpDoc->GetSdPage( static_cast(nPage), PageKind::Standard ); change( pUndoGroup.get(), pPage, aNewSettings ); } } else { // apply only to the current slide DBG_ASSERT( mpCurrentPage && mpCurrentPage->GetPageKind() == PageKind::Standard, "no current page to apply to!" ); if( mpCurrentPage && (mpCurrentPage->GetPageKind() == PageKind::Standard) ) { change( pUndoGroup.get(), mpCurrentPage, aNewSettings ); } } } // if we don't want to have header&footer on the first slide if( bNewNotOnTitle ) { // just hide them, plain simple UI feature HeaderFooterSettings aTempSettings = mpDoc->GetSdPage( 0, PageKind::Standard )->getHeaderFooterSettings(); aTempSettings.mbFooterVisible = false; aTempSettings.mbSlideNumberVisible = false; aTempSettings.mbDateTimeVisible = false; change( pUndoGroup.get(), mpDoc->GetSdPage( 0, PageKind::Standard ), aTempSettings ); } // now notes settings mxNotesHandoutsTabPage->getData( aNewSettings, bNewNotOnTitle ); // only if we pressed apply or apply all on the notes tab page or if the notes settings // have been changed if( !bForceSlides || !(aNewSettings == maNotesHandoutSettings) ) { // first set to all notes pages int nPageCount = mpDoc->GetSdPageCount( PageKind::Notes ); int nPage; for( nPage = 0; nPage < nPageCount; nPage++ ) { SdPage* pPage = mpDoc->GetSdPage( static_cast(nPage), PageKind::Notes ); change( pUndoGroup.get(), pPage, aNewSettings ); } // and last but not least to the handout page change( pUndoGroup.get(), mpDoc->GetMasterSdPage( 0, PageKind::Handout ), aNewSettings ); } // give the undo group to the undo manager mpViewShell->GetViewFrame()->GetObjectShell()->GetUndoManager()->AddUndoAction(std::move(pUndoGroup)); } void HeaderFooterDialog::change( SdUndoGroup* pUndoGroup, SdPage* pPage, const HeaderFooterSettings& rNewSettings ) { pUndoGroup->AddAction(new SdHeaderFooterUndoAction(mpDoc, pPage, rNewSettings )); pPage->setHeaderFooterSettings( rNewSettings ); } HeaderFooterTabPage::HeaderFooterTabPage(weld::Container* pParent, SdDrawDocument* pDoc, SdPage* pActualPage, bool bHandoutMode) : mpDoc(pDoc) , mbHandoutMode(bHandoutMode) , mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/headerfootertab.ui")) , mxContainer(mxBuilder->weld_container("HeaderFooterTab")) , mxFTIncludeOn(mxBuilder->weld_label("include_label")) , mxCBHeader(mxBuilder->weld_check_button("header_cb" )) , mxHeaderBox(mxBuilder->weld_widget("header_box")) , mxTBHeader(mxBuilder->weld_entry("header_text")) , mxCBDateTime(mxBuilder->weld_check_button("datetime_cb")) , mxRBDateTimeFixed(mxBuilder->weld_radio_button("rb_fixed")) , mxRBDateTimeAutomatic(mxBuilder->weld_radio_button("rb_auto")) , mxTBDateTimeFixed(mxBuilder->weld_entry("datetime_value")) , mxCBDateTimeFormat(mxBuilder->weld_combo_box("datetime_format_list")) , mxFTDateTimeLanguage(mxBuilder->weld_label("language_label")) , mxCBDateTimeLanguage(new SvxLanguageBox(mxBuilder->weld_combo_box("language_list"))) , mxCBFooter(mxBuilder->weld_check_button("footer_cb")) , mxFooterBox(mxBuilder->weld_widget("footer_box" )) , mxTBFooter(mxBuilder->weld_entry("footer_text")) , mxCBSlideNumber(mxBuilder->weld_check_button("slide_number")) , mxCBNotOnTitle(mxBuilder->weld_check_button("not_on_title")) , mxReplacementA(mxBuilder->weld_label("replacement_a")) , mxReplacementB(mxBuilder->weld_label("replacement_b")) , mxCTPreview(new PresLayoutPreview) , mxCTPreviewWin(new weld::CustomWeld(*mxBuilder, "preview", *mxCTPreview)) { mxCTPreview->init( pActualPage ? (pActualPage->IsMasterPage() ? pActualPage : static_cast(&(pActualPage->TRG_GetMasterPage()))) : (pDoc->GetMasterSdPage( 0, bHandoutMode ? PageKind::Notes : PageKind::Standard )) ); if( mbHandoutMode ) { OUString sPageNo = mxReplacementA->get_label(); mxCBSlideNumber->set_label( sPageNo ); OUString sFrameTitle = mxReplacementB->get_label(); mxFTIncludeOn->set_label( sFrameTitle ); } mxCBHeader->set_visible( mbHandoutMode ); mxHeaderBox->set_visible( mbHandoutMode ); mxCBNotOnTitle->set_visible( !mbHandoutMode ); mxCBDateTime->connect_toggled( LINK( this, HeaderFooterTabPage, UpdateOnToggleHdl ) ); mxRBDateTimeFixed->connect_toggled( LINK( this, HeaderFooterTabPage, UpdateOnToggleHdl ) ); mxRBDateTimeAutomatic->connect_toggled( LINK( this, HeaderFooterTabPage, UpdateOnToggleHdl ) ); mxCBFooter->connect_toggled( LINK( this, HeaderFooterTabPage, UpdateOnToggleHdl ) ); mxCBHeader->connect_toggled( LINK( this, HeaderFooterTabPage, UpdateOnToggleHdl ) ); mxCBSlideNumber->connect_toggled( LINK( this, HeaderFooterTabPage, UpdateOnToggleHdl ) ); mxCBDateTimeLanguage->SetLanguageList( SvxLanguageListFlags::ALL|SvxLanguageListFlags::ONLY_KNOWN, false, false ); mxCBDateTimeLanguage->connect_changed( LINK( this, HeaderFooterTabPage, LanguageChangeHdl ) ); GetOrSetDateTimeLanguage( meOldLanguage, false ); meOldLanguage = MsLangId::getRealLanguage( meOldLanguage ); mxCBDateTimeLanguage->set_active_id( meOldLanguage ); FillFormatList(0); } IMPL_LINK_NOARG(HeaderFooterTabPage, LanguageChangeHdl, weld::ComboBox&, void) { FillFormatList( mxCBDateTimeFormat->get_active() ); } void HeaderFooterTabPage::FillFormatList( sal_Int32 nSelectedPos ) { LanguageType eLanguage = mxCBDateTimeLanguage->get_active_id(); mxCBDateTimeFormat->clear(); DateTime aDateTime( DateTime::SYSTEM ); for (int nFormat = 0; nFormat < nDateTimeFormatsCount; ++nFormat) { OUString aStr( SvxDateTimeField::GetFormatted( aDateTime, aDateTime, nDateTimeFormats[nFormat].meDateFormat, nDateTimeFormats[nFormat].meTimeFormat, *(SD_MOD()->GetNumberFormatter()), eLanguage ) ); mxCBDateTimeFormat->append_text(aStr); if (nFormat == nSelectedPos) mxCBDateTimeFormat->set_active(nFormat); } } void HeaderFooterTabPage::init( const HeaderFooterSettings& rSettings, bool bNotOnTitle ) { mxCBDateTime->set_active( rSettings.mbDateTimeVisible ); mxRBDateTimeFixed->set_active( rSettings.mbDateTimeIsFixed ); mxRBDateTimeAutomatic->set_active( !rSettings.mbDateTimeIsFixed ); mxTBDateTimeFixed->set_text( rSettings.maDateTimeText ); mxCBHeader->set_active( rSettings.mbHeaderVisible ); mxTBHeader->set_text( rSettings.maHeaderText ); mxCBFooter->set_active( rSettings.mbFooterVisible ); mxTBFooter->set_text( rSettings.maFooterText ); mxCBSlideNumber->set_active( rSettings.mbSlideNumberVisible ); mxCBNotOnTitle->set_active( bNotOnTitle ); mxCBDateTimeLanguage->set_active_id( meOldLanguage ); for (sal_Int32 nPos = 0, nEntryCount = mxCBDateTimeFormat->get_count(); nPos < nEntryCount; ++nPos) { if( nDateTimeFormats[nPos].meDateFormat == rSettings.meDateFormat && nDateTimeFormats[nPos].meTimeFormat == rSettings.meTimeFormat ) { mxCBDateTimeFormat->set_active(nPos); break; } } update(); } void HeaderFooterTabPage::getData( HeaderFooterSettings& rSettings, bool& rNotOnTitle ) { rSettings.mbDateTimeVisible = mxCBDateTime->get_active(); rSettings.mbDateTimeIsFixed = mxRBDateTimeFixed->get_active(); rSettings.maDateTimeText = mxTBDateTimeFixed->get_text(); rSettings.mbFooterVisible = mxCBFooter->get_active(); rSettings.maFooterText = mxTBFooter->get_text(); rSettings.mbSlideNumberVisible = mxCBSlideNumber->get_active(); rSettings.mbHeaderVisible = mxCBHeader->get_active(); rSettings.maHeaderText = mxTBHeader->get_text(); int nPos = mxCBDateTimeFormat->get_active(); if (nPos != -1) { rSettings.meDateFormat = nDateTimeFormats[nPos].meDateFormat; rSettings.meTimeFormat = nDateTimeFormats[nPos].meTimeFormat; } LanguageType eLanguage = mxCBDateTimeLanguage->get_active_id(); if( eLanguage != meOldLanguage ) GetOrSetDateTimeLanguage( eLanguage, true ); rNotOnTitle = mxCBNotOnTitle->get_active(); } void HeaderFooterTabPage::update() { mxRBDateTimeFixed->set_sensitive( mxCBDateTime->get_active() ); mxTBDateTimeFixed->set_sensitive( mxRBDateTimeFixed->get_active() && mxCBDateTime->get_active() ); mxRBDateTimeAutomatic->set_sensitive( mxCBDateTime->get_active() ); mxCBDateTimeFormat->set_sensitive( mxCBDateTime->get_active() && mxRBDateTimeAutomatic->get_active() ); mxFTDateTimeLanguage->set_sensitive( mxCBDateTime->get_active() && mxRBDateTimeAutomatic->get_active() ); mxCBDateTimeLanguage->set_sensitive( mxCBDateTime->get_active() && mxRBDateTimeAutomatic->get_active() ); mxFooterBox->set_sensitive( mxCBFooter->get_active() ); mxHeaderBox->set_sensitive( mxCBHeader->get_active() ); HeaderFooterSettings aSettings; bool bNotOnTitle; getData( aSettings, bNotOnTitle ); mxCTPreview->update( aSettings ); } IMPL_LINK_NOARG(HeaderFooterTabPage, UpdateOnToggleHdl, weld::Toggleable&, void) { update(); } void HeaderFooterTabPage::GetOrSetDateTimeLanguage( LanguageType &rLanguage, bool bSet ) { if( mbHandoutMode ) { // if set, set it on all notes master pages if( bSet ) { sal_uInt16 nPageCount = mpDoc->GetMasterSdPageCount( PageKind::Notes ); sal_uInt16 nPage; for( nPage = 0; nPage < nPageCount; nPage++ ) { GetOrSetDateTimeLanguage( rLanguage, bSet, mpDoc->GetMasterSdPage( nPage, PageKind::Notes ) ); } } // #i119985# and set it, or just get it from the notes master page GetOrSetDateTimeLanguage( rLanguage, bSet, mpDoc->GetMasterSdPage( 0, PageKind::Notes ) ); } else { // get the language from the first master page // or set it to all master pages sal_uInt16 nPageCount = bSet ? mpDoc->GetMasterSdPageCount( PageKind::Notes ) : 1; sal_uInt16 nPage; for( nPage = 0; nPage < nPageCount; nPage++ ) { GetOrSetDateTimeLanguage( rLanguage, bSet, mpDoc->GetMasterSdPage( nPage, PageKind::Standard ) ); } } } void HeaderFooterTabPage::GetOrSetDateTimeLanguage( LanguageType &rLanguage, bool bSet, SdPage* pPage ) { if( !pPage ) return; SdrTextObj* pObj = static_cast(pPage->GetPresObj( PresObjKind::DateTime )); if( !pObj ) return; Outliner* pOutl = mpDoc->GetInternalOutliner(); pOutl->Init( OutlinerMode::TextObject ); OutlinerMode nOutlMode = pOutl->GetOutlinerMode(); EditEngine* pEdit = const_cast< EditEngine* >(&pOutl->GetEditEngine()); OutlinerParaObject* pOPO = pObj->GetOutlinerParaObject(); if( pOPO ) pOutl->SetText( *pOPO ); EPosition aDateFieldPosition; bool bHasDateFieldItem = false; sal_Int32 nParaCount = pEdit->GetParagraphCount(); for (sal_Int32 nPara = 0; (nPara < nParaCount) && !bHasDateFieldItem; ++nPara) { sal_uInt16 nFieldCount = pEdit->GetFieldCount(nPara); for (sal_uInt16 nField = 0; (nField < nFieldCount); ++nField) { EFieldInfo aFieldInfo = pEdit->GetFieldInfo(nPara, nField); if (aFieldInfo.pFieldItem) { const SvxFieldData* pFieldData = aFieldInfo.pFieldItem->GetField(); if (dynamic_cast(pFieldData) != nullptr || dynamic_cast(pFieldData) != nullptr) { bHasDateFieldItem = true; aDateFieldPosition = aFieldInfo.aPosition; break; } } } } if (bHasDateFieldItem) { if( bSet ) { SfxItemSet aSet(pEdit->GetAttribs(aDateFieldPosition.nPara, aDateFieldPosition.nIndex, aDateFieldPosition.nIndex+1, GetAttribsFlags::CHARATTRIBS)); SvxLanguageItem aItem( rLanguage, EE_CHAR_LANGUAGE ); aSet.Put( aItem ); SvxLanguageItem aItemCJK( rLanguage, EE_CHAR_LANGUAGE_CJK ); aSet.Put( aItemCJK ); SvxLanguageItem aItemCTL( rLanguage, EE_CHAR_LANGUAGE_CTL ); aSet.Put( aItemCTL ); ESelection aSel(aDateFieldPosition.nPara, aDateFieldPosition.nIndex, aDateFieldPosition.nPara, aDateFieldPosition.nIndex+1 ); pEdit->QuickSetAttribs( aSet, aSel ); pObj->SetOutlinerParaObject( pOutl->CreateParaObject() ); pOutl->UpdateFields(); } else { rLanguage = pOutl->GetLanguage(aDateFieldPosition.nPara, aDateFieldPosition.nIndex ); } } pOutl->Clear(); pOutl->Init( nOutlMode ); } PresLayoutPreview::PresLayoutPreview() : mpMaster(nullptr) { } void PresLayoutPreview::SetDrawingArea(weld::DrawingArea* pDrawingArea) { Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(80, 80), MapMode(MapUnit::MapAppFont))); pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); CustomWidgetController::SetDrawingArea(pDrawingArea); SetOutputSizePixel(aSize); } void PresLayoutPreview::init( SdPage *pMaster ) { mpMaster = pMaster; maPageSize = pMaster->GetSize(); } void PresLayoutPreview::update( HeaderFooterSettings const & rSettings ) { maSettings = rSettings; Invalidate(); } void PresLayoutPreview::Paint(vcl::RenderContext& rRenderContext, SdrTextObj const * pObj, bool bVisible, bool bDotted /* = false*/ ) { // get object transformation basegfx::B2DHomMatrix aObjectTransform; basegfx::B2DPolyPolygon aObjectPolyPolygon; pObj->TRGetBaseGeometry(aObjectTransform, aObjectPolyPolygon); // build complete transformation by adding view transformation from // logic page coordinates to local pixel coordinates const double fScaleX(static_cast(maOutRect.getWidth()) / static_cast(maPageSize.Width())); const double fScaleY(static_cast(maOutRect.getHeight()) / static_cast(maPageSize.Height())); aObjectTransform.scale(fScaleX, fScaleY); aObjectTransform.translate(maOutRect.Left(), maOutRect.Top()); // create geometry using unit range and object transform basegfx::B2DPolyPolygon aGeometry(basegfx::utils::createUnitPolygon()); aGeometry.transform(aObjectTransform); // apply line pattern if wanted if (bDotted) { static const double fFactor(1.0); std::vector aPattern { 3.0 * fFactor, 1.0 * fFactor }; basegfx::B2DPolyPolygon aDashed; basegfx::utils::applyLineDashing(aGeometry, aPattern, &aDashed); aGeometry = aDashed; } // determine line color svtools::ColorConfig aColorConfig; svtools::ColorConfigValue aColor( aColorConfig.GetColorValue( bVisible ? svtools::FONTCOLOR : svtools::OBJECTBOUNDARIES ) ); // paint at OutDev rRenderContext.SetLineColor(aColor.nColor); rRenderContext.SetFillColor(); for (sal_uInt32 a(0); a < aGeometry.count(); a++) { rRenderContext.DrawPolyLine(aGeometry.getB2DPolygon(a)); } } void PresLayoutPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) { rRenderContext.Push(); maOutRect = ::tools::Rectangle(Point(0,0), rRenderContext.GetOutputSize()); // calculate page size with correct aspect ratio int nWidth, nHeight; if( maPageSize.Width() > maPageSize.Height() ) { nWidth = maOutRect.GetWidth(); nHeight = maPageSize.Width() == 0 ? 0 : tools::Long( static_cast(nWidth * maPageSize.Height()) / static_cast(maPageSize.Width()) ); } else { nHeight = maOutRect.GetHeight(); nWidth = maPageSize.Height() == 0 ? 0 : tools::Long( static_cast(nHeight * maPageSize.Width()) / static_cast(maPageSize.Height()) ); } maOutRect.AdjustLeft((maOutRect.GetWidth() - nWidth) >> 1 ); maOutRect.SetRight( maOutRect.Left() + nWidth - 1 ); maOutRect.AdjustTop((maOutRect.GetHeight() - nHeight) >> 1 ); maOutRect.SetBottom( maOutRect.Top() + nHeight - 1 ); // draw decoration frame DecorationView aDecoView(&rRenderContext); maOutRect = aDecoView.DrawFrame(maOutRect, DrawFrameStyle::In); // draw page background rRenderContext.SetFillColor(COL_WHITE); rRenderContext.DrawRect(maOutRect); // paint presentation objects from masterpage if (nullptr != mpMaster) { SdrTextObj* pMasterTitle = static_cast(mpMaster->GetPresObj(PresObjKind::Title)); SdrTextObj* pMasterOutline = static_cast(mpMaster->GetPresObj(mpMaster->GetPageKind() == PageKind::Notes ? PresObjKind::Notes : PresObjKind::Outline)); SdrTextObj* pHeader = static_cast(mpMaster->GetPresObj(PresObjKind::Header)); SdrTextObj* pFooter = static_cast(mpMaster->GetPresObj(PresObjKind::Footer)); SdrTextObj* pDate = static_cast(mpMaster->GetPresObj(PresObjKind::DateTime)); SdrTextObj* pNumber = static_cast(mpMaster->GetPresObj(PresObjKind::SlideNumber)); if (pMasterTitle) Paint(rRenderContext, pMasterTitle, true, true); if (pMasterOutline) Paint(rRenderContext, pMasterOutline, true, true); if (pHeader) Paint(rRenderContext, pHeader, maSettings.mbHeaderVisible); if (pFooter) Paint(rRenderContext, pFooter, maSettings.mbFooterVisible); if (pDate) Paint(rRenderContext, pDate, maSettings.mbDateTimeVisible); if (pNumber) Paint(rRenderContext, pNumber, maSettings.mbSlideNumberVisible); } rRenderContext.Pop(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */