diff options
Diffstat (limited to '')
51 files changed, 15591 insertions, 0 deletions
diff --git a/sd/source/ui/dlg/AnimationChildWindow.cxx b/sd/source/ui/dlg/AnimationChildWindow.cxx new file mode 100644 index 000000000..2f221fc9e --- /dev/null +++ b/sd/source/ui/dlg/AnimationChildWindow.cxx @@ -0,0 +1,50 @@ +/* -*- 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 <AnimationChildWindow.hxx> + +#include <app.hrc> +#include <animobjs.hxx> +#include <sfx2/childwin.hxx> + +namespace sd { + +SFX_IMPL_DOCKINGWINDOW_WITHID(AnimationChildWindow, SID_ANIMATION_OBJECTS) + +/** + * Derivative from SfxChildWindow as "container" for animator + */ +AnimationChildWindow::AnimationChildWindow( + vcl::Window* _pParent, + sal_uInt16 nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo ) + : SfxChildWindow( _pParent, nId ) +{ + VclPtr<AnimationWindow> pAnimWin = VclPtr<AnimationWindow>::Create(pBindings, this, _pParent); + SetWindow(pAnimWin); + + pAnimWin->Initialize( pInfo ); + + SetHideNotDelete( true ); +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/BulletAndPositionDlg.cxx b/sd/source/ui/dlg/BulletAndPositionDlg.cxx new file mode 100644 index 000000000..384b477e4 --- /dev/null +++ b/sd/source/ui/dlg/BulletAndPositionDlg.cxx @@ -0,0 +1,1293 @@ +/* -*- 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 <tools/mapunit.hxx> +#include <tools/urlobj.hxx> +#include <editeng/numitem.hxx> +#include <svl/eitem.hxx> +#include <svl/itempool.hxx> +#include <svx/colorbox.hxx> +#include <svx/strarray.hxx> +#include <svx/gallery.hxx> +#include <editeng/brushitem.hxx> +#include <svl/intitem.hxx> +#include <vcl/graph.hxx> +#include <svtools/unitconv.hxx> +#include <svx/svxids.hrc> + +#include <algorithm> +#include <memory> +#include <vector> +#include <sfx2/opengrf.hxx> + +#include <strings.hrc> +#include <svl/stritem.hxx> +#include <sal/log.hxx> +#include <vcl/virdev.hxx> +#include <svx/SvxNumOptionsTabPageHelper.hxx> +#include <View.hxx> +#include <drawdoc.hxx> +#include <cui/cuicharmap.hxx> +#include <BulletAndPositionDlg.hxx> +#include <sdresid.hxx> +#include <DrawViewShell.hxx> + +#define SHOW_NUMBERING 0 +#define SHOW_BULLET 1 +#define SHOW_BITMAP 2 + +#define MAX_BMP_WIDTH 16 +#define MAX_BMP_HEIGHT 16 + +static bool bLastRelative = false; + +static const vcl::Font& lcl_GetDefaultBulletFont() +{ + static vcl::Font aDefBulletFont = []() { + vcl::Font tmp("OpenSymbol", "", Size(0, 14)); + tmp.SetCharSet(RTL_TEXTENCODING_SYMBOL); + tmp.SetFamily(FAMILY_DONTKNOW); + tmp.SetPitch(PITCH_DONTKNOW); + tmp.SetWeight(WEIGHT_DONTKNOW); + tmp.SetTransparent(true); + return tmp; + }(); + return aDefBulletFont; +} + +class SdDrawDocument; + +SvxBulletAndPositionDlg::SvxBulletAndPositionDlg(weld::Window* pWindow, const SfxItemSet& rSet, + const ::sd::View* pView) + : GenericDialogController(pWindow, "cui/ui/bulletandposition.ui", "BulletAndPosition") + , aInvalidateTimer("sd SvxBulletAndPositionDlg aInvalidateTimer") + , rFirstStateSet(rSet) + , bLastWidthModified(false) + , bModified(false) + , bInInitControl(false) + , bLabelAlignmentPosAndSpaceModeActive(false) + , bApplyToMaster(false) + , nBullet(0xff) + , nActNumLvl(1) + , p_Window(pWindow) + , nNumItemId(SID_ATTR_NUMBERING_RULE) + , m_xGrid(m_xBuilder->weld_widget("grid2")) + , m_xLevelLB(m_xBuilder->weld_tree_view("levellb")) + , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb")) + , m_xPrefixFT(m_xBuilder->weld_label("prefixft")) + , m_xPrefixED(m_xBuilder->weld_entry("prefix")) + , m_xSuffixFT(m_xBuilder->weld_label("suffixft")) + , m_xSuffixED(m_xBuilder->weld_entry("suffix")) + , m_xBeforeAfter(m_xBuilder->weld_frame("beforeafter")) + , m_xBulColorFT(m_xBuilder->weld_label("colorft")) + , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"), + [this] { return m_xDialog.get(); })) + , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft")) + , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT)) + , m_xStartFT(m_xBuilder->weld_label("startatft")) + , m_xStartED(m_xBuilder->weld_spin_button("startat")) + , m_xBulletFT(m_xBuilder->weld_label("bulletft")) + , m_xBulletPB(m_xBuilder->weld_button("bullet")) + , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap")) + , m_xWidthFT(m_xBuilder->weld_label("widthft")) + , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM)) + , m_xHeightFT(m_xBuilder->weld_label("heightft")) + , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM)) + , m_xRatioCB(m_xBuilder->weld_check_button("keepratio")) + , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN)) + , m_xDistBorderFT(m_xBuilder->weld_label("indent")) + , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM)) + , m_xRelativeCB(m_xBuilder->weld_check_button("relative")) + , m_xIndentFT(m_xBuilder->weld_label("numberingwidth")) + , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM)) + , m_xLeftTB(m_xBuilder->weld_toggle_button("left")) + , m_xCenterTB(m_xBuilder->weld_toggle_button("center")) + , m_xRightTB(m_xBuilder->weld_toggle_button("right")) + , m_xSlideRB(m_xBuilder->weld_radio_button("sliderb")) + , m_xSelectionRB(m_xBuilder->weld_radio_button("selectionrb")) + , m_xApplyToMaster(m_xBuilder->weld_toggle_button("applytomaster")) + , m_xReset(m_xBuilder->weld_button("reset")) +{ + m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR); + m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT); + m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT); + aActBulletFont = lcl_GetDefaultBulletFont(); + + m_xBulletPB->connect_clicked(LINK(this, SvxBulletAndPositionDlg, BulletHdl_Impl)); + m_xFmtLB->connect_changed(LINK(this, SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl)); + m_xBitmapMB->connect_selected(LINK(this, SvxBulletAndPositionDlg, GraphicHdl_Impl)); + m_xBitmapMB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, PopupActivateHdl_Impl)); + m_xLevelLB->set_selection_mode(SelectionMode::Multiple); + m_xLevelLB->connect_changed(LINK(this, SvxBulletAndPositionDlg, LevelHdl_Impl)); + m_xWidthMF->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, SizeHdl_Impl)); + m_xHeightMF->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, SizeHdl_Impl)); + m_xRatioCB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, RatioHdl_Impl)); + m_xStartED->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, SpinModifyHdl_Impl)); + m_xPrefixED->connect_changed(LINK(this, SvxBulletAndPositionDlg, EditModifyHdl_Impl)); + m_xSuffixED->connect_changed(LINK(this, SvxBulletAndPositionDlg, EditModifyHdl_Impl)); + m_xBulRelSizeMF->connect_value_changed(LINK(this, SvxBulletAndPositionDlg, BulRelSizeHdl_Impl)); + m_xBulColLB->SetSelectHdl(LINK(this, SvxBulletAndPositionDlg, BulColorHdl_Impl)); + m_xLeftTB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, SelectLeftAlignmentHdl_Impl)); + m_xCenterTB->connect_toggled( + LINK(this, SvxBulletAndPositionDlg, SelectCenterAlignmentHdl_Impl)); + m_xRightTB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, SelectRightAlignmentHdl_Impl)); + m_xApplyToMaster->connect_toggled(LINK(this, SvxBulletAndPositionDlg, ApplyToMasterHdl_Impl)); + m_xReset->connect_clicked(LINK(this, SvxBulletAndPositionDlg, ResetHdl_Impl)); + + aInvalidateTimer.SetInvokeHandler( + LINK(this, SvxBulletAndPositionDlg, PreviewInvalidateHdl_Impl)); + aInvalidateTimer.SetTimeout(50); + + eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE)); + + // Fill ListBox with predefined / translated numbering types. + sal_uInt32 nCount = SvxNumberingTypeTable::Count(); + for (sal_uInt32 i = 0; i < nCount; ++i) + { + m_xFmtLB->append(OUString::number(SvxNumberingTypeTable::GetValue(i)), + SvxNumberingTypeTable::GetString(i)); + } + + // Get advanced numbering types from the component. + // Watch out for the ugly + // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN + // to not remove that. + SvxNumOptionsTabPageHelper::GetI18nNumbering(*m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN)); + + m_xFmtLB->set_active(0); + m_xRelativeCB->set_active(true); + + Link<weld::MetricSpinButton&, void> aLk3 + = LINK(this, SvxBulletAndPositionDlg, DistanceHdl_Impl); + m_xDistBorderMF->connect_value_changed(aLk3); + m_xIndentMF->connect_value_changed(aLk3); + + m_xRelativeCB->connect_toggled(LINK(this, SvxBulletAndPositionDlg, RelativeHdl_Impl)); + m_xRelativeCB->set_active(bLastRelative); + + Size aSize(m_xGrid->get_preferred_size()); + m_xGrid->set_size_request(aSize.Width(), -1); + + // PageCreated + FieldUnit eMetric = pView->GetDoc().GetUIUnit(); + SfxAllItemSet aSet(*(rSet.GetPool())); + aSet.Put(SfxUInt16Item(SID_METRIC_ITEM, static_cast<sal_uInt16>(eMetric))); + + const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false); + const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false); + + if (pNumCharFmt) + SetCharFmt(pNumCharFmt->GetValue()); + + if (pMetricItem) + SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue())); + + // tdf#130526: Hide "Apply To Master"-button in Draw and rename "Slide" to "Page" + DocumentType aDocumentType = pView->GetDoc().GetDocumentType(); + if (aDocumentType == DocumentType::Draw) + { + m_xApplyToMaster->hide(); + m_xSlideRB->set_label(SdResId(STR_PAGE_NAME)); + } + // tdf#137406: Crash when clicking "Apply to Master" in Slide Master mode on Bullets and Numbering dialog + EditMode aEditmode = static_cast<::sd::DrawViewShell*>(pView->GetViewShell())->GetEditMode(); + if (aDocumentType == DocumentType::Impress && aEditmode == EditMode::MasterPage) + m_xApplyToMaster->hide(); + + // End PageCreated + + Reset(&rSet); + + // ActivatePage part + + const SfxItemSet* pExampleSet = &rSet; + sal_uInt16 nTmpNumLvl = 1; + bool bPreset = false; + if (pExampleSet) + { + if (const SfxBoolItem* pItem = pExampleSet->GetItemIfSet(SID_PARAM_NUM_PRESET, false)) + bPreset = pItem->GetValue(); + if (const SfxUInt16Item* pItem = pExampleSet->GetItemIfSet(SID_PARAM_CUR_NUM_LEVEL, false)) + nTmpNumLvl = pItem->GetValue(); + } + if (const SvxNumBulletItem* pItem = rSet.GetItemIfSet(nNumItemId, false)) + { + pSaveNum.reset(new SvxNumRule(pItem->GetNumRule())); + } + + bModified = (!pActNum->Get(0) || bPreset); + if (*pActNum != *pSaveNum || nActNumLvl != nTmpNumLvl) + { + nActNumLvl = nTmpNumLvl; + sal_uInt16 nMask = 1; + if (nActNumLvl == SAL_MAX_UINT16) + m_xLevelLB->select(pActNum->GetLevelCount()); + if (nActNumLvl != SAL_MAX_UINT16) + { + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + m_xLevelLB->select(i); + nMask <<= 1; + } + } + *pActNum = *pSaveNum; + + m_xRelativeCB->set_sensitive(nActNumLvl != 1); + + InitPosAndSpaceMode(); + InitControls(); + } + + m_aPreviewWIN.SetLevel(nActNumLvl); + m_aPreviewWIN.Invalidate(); + + // End of the ActivatePage part +} + +SvxBulletAndPositionDlg::~SvxBulletAndPositionDlg() {} + +void SvxBulletAndPositionDlg::SetMetric(FieldUnit eMetric) +{ + if (eMetric == FieldUnit::MM) + { + m_xWidthMF->set_digits(1); + m_xHeightMF->set_digits(1); + m_xDistBorderMF->set_digits(1); + m_xIndentMF->set_digits(1); + } + m_xWidthMF->set_unit(eMetric); + m_xHeightMF->set_unit(eMetric); + m_xDistBorderMF->set_unit(eMetric); + m_xIndentMF->set_unit(eMetric); +} + +SfxItemSet* SvxBulletAndPositionDlg::GetOutputItemSet(SfxItemSet* pSet) +{ + pSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl)); + if (bModified && pActNum) + { + *pSaveNum = *pActNum; + pSet->Put(SvxNumBulletItem(*pSaveNum, nNumItemId)); + pSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false)); + } + return pSet; +}; + +bool SvxBulletAndPositionDlg::IsApplyToMaster() const { return bApplyToMaster; } +bool SvxBulletAndPositionDlg::IsSlideScope() const { return m_xSlideRB->get_active(); } + +void SvxBulletAndPositionDlg::Reset(const SfxItemSet* rSet) +{ + const SvxNumBulletItem* pItem = rSet->GetItemIfSet(SID_ATTR_NUMBERING_RULE, false); + // in Draw the item exists as WhichId, in Writer only as SlotId + if (!pItem) + { + nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE); + pItem = rSet->GetItemIfSet(nNumItemId, false); + + if (!pItem) + { + pItem = &rSet->Get(nNumItemId); + } + } + DBG_ASSERT(pItem, "no item found!"); + pSaveNum.reset(new SvxNumRule(pItem->GetNumRule())); + + // insert levels + if (!m_xLevelLB->n_children()) + { + for (sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++) + m_xLevelLB->append_text(OUString::number(i)); + if (pSaveNum->GetLevelCount() > 1) + { + OUString sEntry = "1 - " + OUString::number(pSaveNum->GetLevelCount()); + m_xLevelLB->append_text(sEntry); + m_xLevelLB->select_text(sEntry); + } + else + m_xLevelLB->select(0); + } + else + m_xLevelLB->select(m_xLevelLB->n_children() - 1); + + sal_uInt16 nMask = 1; + m_xLevelLB->unselect_all(); + if (nActNumLvl == SAL_MAX_UINT16) + { + m_xLevelLB->select(pSaveNum->GetLevelCount()); + } + else + { + for (sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + m_xLevelLB->select(i); + nMask <<= 1; + } + } + + if (!pActNum) + pActNum.reset(new SvxNumRule(*pSaveNum)); + else if (*pSaveNum != *pActNum) + *pActNum = *pSaveNum; + m_aPreviewWIN.SetNumRule(pActNum.get()); + + bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS); + + // again misusage: in Draw there is numeration only until the bitmap + // without SVX_NUM_NUMBER_NONE + //remove types that are unsupported by Draw/Impress + if (!bContinuous) + { + sal_Int32 nFmtCount = m_xFmtLB->get_count(); + for (sal_Int32 i = nFmtCount; i; i--) + { + sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32(); + if (/*SVX_NUM_NUMBER_NONE == nEntryData ||*/ + (SVX_NUM_BITMAP | LINK_TOKEN) == nEntryData) + m_xFmtLB->remove(i - 1); + } + } + //one must be enabled + if (!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP)) + { + auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP | LINK_TOKEN)); + if (nPos != -1) + m_xFmtLB->remove(nPos); + } + else if (!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP)) + { + auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP)); + if (nPos != -1) + m_xFmtLB->remove(nPos); + } + + // MegaHack: because of a not-fixable 'design mistake/error' in Impress + // delete all kinds of numeric enumerations + if (pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS)) + { + sal_Int32 nFmtCount = m_xFmtLB->get_count(); + for (sal_Int32 i = nFmtCount; i; i--) + { + sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32(); + if (/*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE) + m_xFmtLB->remove(i - 1); + } + } + + InitPosAndSpaceMode(); + + InitControls(); + bModified = false; +} + +void SvxBulletAndPositionDlg::InitControls() +{ + bInInitControl = true; + + const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive && m_xRelativeCB->get_sensitive() + && m_xRelativeCB->get_active(); + const bool bSingleSelection + = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl; + + m_xDistBorderMF->set_sensitive(!bLabelAlignmentPosAndSpaceModeActive + && (bSingleSelection || bRelative)); + m_xDistBorderFT->set_sensitive(!bLabelAlignmentPosAndSpaceModeActive + && (bSingleSelection || bRelative)); + + bool bShowBullet = true; + bool bShowBitmap = true; + bool bSameType = true; + bool bSameStart = true; + bool bSamePrefix = true; + bool bSameSuffix = true; + bool bSameSize = true; + bool bSameBulColor = true; + bool bSameBulRelSize = true; + bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive; + bool bSetDistEmpty = false; + bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive; + + const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM]; + SvxAdjust eFirstAdjust = SvxAdjust::Left; + Size aFirstSize(0, 0); + sal_uInt16 nMask = 1; + sal_uInt16 nLvl = SAL_MAX_UINT16; + + bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR); + bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE); + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + aNumFmtArr[i] = &pActNum->GetLevel(i); + + if (nActNumLvl & nMask) + { + bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL; + bShowBitmap &= (aNumFmtArr[i]->GetNumberingType() & (~LINK_TOKEN)) == SVX_NUM_BITMAP; + eFirstAdjust = aNumFmtArr[i]->GetNumAdjust(); + if (SAL_MAX_UINT16 == nLvl) + { + nLvl = i; + if (bShowBitmap) + aFirstSize = aNumFmtArr[i]->GetGraphicSize(); + } + if (i > nLvl) + { + bSameType + &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType(); + bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart(); + + bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix(); + bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix(); + //bSameAdjust &= eFirstAdjust == aNumFmtArr[i]->GetNumAdjust(); + if (bShowBitmap && bSameSize) + bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize; + bSameBulColor + &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor(); + bSameBulRelSize + &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize(); + bSameIndent //? + &= aNumFmtArr[i]->GetFirstLineOffset() + == aNumFmtArr[nLvl]->GetFirstLineOffset(); + } + } + + nMask <<= 1; + } + SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0); + + sal_uInt16 nNumberingType; + if (nLvl != SAL_MAX_UINT16) + nNumberingType = aNumFmtArr[nLvl]->GetNumberingType(); + else + { + nNumberingType = SVX_NUM_NUMBER_NONE; + bSameDistBorderNum = false; + bSameIndent = false; + bSameBulRelSize = false; + bSameBulColor = false; + bSameStart = false; + bSamePrefix = false; + bSameSuffix = false; + } + + CheckForStartValue_Impl(nNumberingType); + + if (bShowBitmap) + { + if (bSameSize) + { + SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit); + SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit); + } + else + { + m_xHeightMF->set_text(""); + m_xWidthMF->set_text(""); + } + } + + if (bSameType) + { + sal_uInt16 nLBData = nNumberingType; + m_xFmtLB->set_active_id(OUString::number(nLBData)); + } + else + m_xFmtLB->set_active(-1); + + if (bBullRelSize) + { + if (bSameBulRelSize) + m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT); + else + m_xBulRelSizeMF->set_text(""); + } + if (bBullColor) + { + if (bSameBulColor) + m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor()); + else + m_xBulColLB->SetNoSelection(); + } + switch (nBullet) + { + case SHOW_NUMBERING: + if (bSameStart) + { + m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart()); + } + else + m_xStartED->set_text(""); + break; + case SHOW_BULLET: + break; + case SHOW_BITMAP: + break; + } + + switch (eFirstAdjust) + { + case SvxAdjust::Left: + m_xLeftTB->set_active(true); + m_xCenterTB->set_active(false); + m_xRightTB->set_active(false); + break; + case SvxAdjust::Center: + m_xLeftTB->set_active(false); + m_xCenterTB->set_active(true); + m_xRightTB->set_active(false); + break; + case SvxAdjust::Right: + m_xLeftTB->set_active(false); + m_xCenterTB->set_active(false); + m_xRightTB->set_active(true); + break; + default: + break; + } + + if (bSamePrefix) + m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix()); + else + m_xPrefixED->set_text(""); + if (bSameSuffix) + m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix()); + else + m_xSuffixED->set_text(""); + + if (bSameDistBorderNum) + { + tools::Long nDistBorderNum; + if (bRelative) + { + nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace()) + + aNumFmtArr[nLvl]->GetFirstLineOffset(); + if (nLvl) + nDistBorderNum -= static_cast<tools::Long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace()) + + aNumFmtArr[nLvl - 1]->GetFirstLineOffset(); + } + else + { + nDistBorderNum = static_cast<tools::Long>(aNumFmtArr[nLvl]->GetAbsLSpace()) + + aNumFmtArr[nLvl]->GetFirstLineOffset(); + } + SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit); + } + else + bSetDistEmpty = true; + + if (bSetDistEmpty) + m_xDistBorderMF->set_text(""); + + if (bSameIndent) + SetMetricValue(*m_xIndentMF, -aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit); + else + m_xIndentMF->set_text(""); + + m_xSelectionRB->set_active(true); + + m_aPreviewWIN.SetLevel(nActNumLvl); + m_aPreviewWIN.Invalidate(); + bInInitControl = false; +} + +// 0 - Number; 1 - Bullet; 2 - Bitmap +void SvxBulletAndPositionDlg::SwitchNumberType(sal_uInt8 nType) +{ + if (nBullet == nType) + return; + nBullet = nType; + bool bBullet = (nType == SHOW_BULLET); + bool bBitmap = (nType == SHOW_BITMAP); + bool bEnableBitmap = (nType == SHOW_BITMAP); + bool bNumeric = !(bBitmap || bBullet); + m_xPrefixFT->set_visible(bNumeric); + m_xPrefixED->set_visible(bNumeric); + m_xSuffixFT->set_visible(bNumeric); + m_xSuffixED->set_visible(bNumeric); + m_xBeforeAfter->set_visible(bNumeric); + + m_xStartFT->set_visible(!(bBullet || bBitmap)); + m_xStartED->set_visible(!(bBullet || bBitmap)); + + m_xBulletFT->set_visible(bBullet); + m_xBulletPB->set_visible(bBullet); + bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR); + m_xBulColorFT->set_visible(!bBitmap && bBullColor); + m_xBulColLB->set_visible(!bBitmap && bBullColor); + bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE); + m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize); + m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize); + + m_xBitmapMB->set_visible(bBitmap); + + m_xWidthFT->set_visible(bBitmap); + m_xWidthMF->set_visible(bBitmap); + m_xHeightFT->set_visible(bBitmap); + m_xHeightMF->set_visible(bBitmap); + m_xRatioCB->set_visible(bBitmap); + + m_xWidthFT->set_sensitive(bEnableBitmap); + m_xWidthMF->set_sensitive(bEnableBitmap); + m_xHeightFT->set_sensitive(bEnableBitmap); + m_xHeightMF->set_sensitive(bEnableBitmap); + m_xRatioCB->set_sensitive(bEnableBitmap); +} + +void SvxBulletAndPositionDlg::CheckForStartValue_Impl(sal_uInt16 nNumberingType) +{ + bool bIsNull = m_xStartED->get_value() == 0; + bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC + || SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType + || SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType; + m_xStartED->set_min(bNoZeroAllowed ? 1 : 0); + if (bIsNull && bNoZeroAllowed) + SpinModifyHdl_Impl(*m_xStartED); +} + +IMPL_LINK(SvxBulletAndPositionDlg, LevelHdl_Impl, weld::TreeView&, rBox, void) +{ + sal_uInt16 nSaveNumLvl = nActNumLvl; + nActNumLvl = 0; + auto aSelectedRows = rBox.get_selected_rows(); + if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) + != aSelectedRows.end() + && (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff)) + { + nActNumLvl = 0xFFFF; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + rBox.unselect(i); + } + else if (!aSelectedRows.empty()) + { + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end()) + nActNumLvl |= nMask; + nMask <<= 1; + } + rBox.unselect(pActNum->GetLevelCount()); + } + else + nActNumLvl = nSaveNumLvl; + + InitControls(); +} + +IMPL_LINK_NOARG(SvxBulletAndPositionDlg, PreviewInvalidateHdl_Impl, Timer*, void) +{ + m_aPreviewWIN.Invalidate(); +} + +IMPL_LINK(SvxBulletAndPositionDlg, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void) +{ + bool bBmp = false; + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + // PAGEDESC does not exist + SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32()); + aNumFmt.SetNumberingType(nNumType); + sal_uInt16 nNumberingType = aNumFmt.GetNumberingType(); + if (SVX_NUM_BITMAP == (nNumberingType & (~LINK_TOKEN))) + { + bBmp |= nullptr != aNumFmt.GetBrush(); + aNumFmt.SetIncludeUpperLevels(0); + aNumFmt.SetListFormat("", "", i); + if (!bBmp) + aNumFmt.SetGraphic(""); + pActNum->SetLevel(i, aNumFmt); + SwitchNumberType(SHOW_BITMAP); + } + else if (SVX_NUM_CHAR_SPECIAL == nNumberingType) + { + aNumFmt.SetIncludeUpperLevels(0); + aNumFmt.SetListFormat("", "", i); + if (!aNumFmt.GetBulletFont()) + aNumFmt.SetBulletFont(&aActBulletFont); + if (!aNumFmt.GetBulletChar()) + aNumFmt.SetBulletChar(SVX_DEF_BULLET); + pActNum->SetLevel(i, aNumFmt); + SwitchNumberType(SHOW_BULLET); + // allocation of the drawing pattern is automatic + } + else + { + aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i); + SwitchNumberType(SHOW_NUMBERING); + pActNum->SetLevel(i, aNumFmt); + CheckForStartValue_Impl(nNumberingType); + + // allocation of the drawing pattern is automatic + } + } + nMask <<= 1; + } + + SetModified(); +} + +IMPL_LINK(SvxBulletAndPositionDlg, BulColorHdl_Impl, ColorListBox&, rColorBox, void) +{ + Color nSetColor = rColorBox.GetSelectEntryColor(); + + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + aNumFmt.SetBulletColor(nSetColor); + pActNum->SetLevel(i, aNumFmt); + } + nMask <<= 1; + } + SetModified(); +} + +IMPL_LINK(SvxBulletAndPositionDlg, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void) +{ + sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT); + + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + aNumFmt.SetBulletRelSize(nRelSize); + pActNum->SetLevel(i, aNumFmt); + } + nMask <<= 1; + } + SetModified(); +} + +IMPL_LINK(SvxBulletAndPositionDlg, GraphicHdl_Impl, const OString&, rIdent, void) +{ + OUString aGrfName; + Size aSize; + bool bSucc(false); + SvxOpenGraphicDialog aGrfDlg(SdResId(RID_SVXSTR_EDIT_GRAPHIC), p_Window); + + OString sNumber; + if (rIdent.startsWith("gallery", &sNumber)) + { + auto idx = sNumber.toUInt32(); + if (idx < aGrfNames.size()) + { + aGrfName = aGrfNames[idx]; + Graphic aGraphic; + if (GalleryExplorer::GetGraphicObj(GALLERY_THEME_BULLETS, idx, &aGraphic)) + { + aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic); + bSucc = true; + } + } + } + else if (rIdent == "fromfile") + { + aGrfDlg.EnableLink(false); + aGrfDlg.AsLink(false); + if (!aGrfDlg.Execute()) + { + // memorize selected filter + aGrfName = aGrfDlg.GetPath(); + + Graphic aGraphic; + if (!aGrfDlg.GetGraphic(aGraphic)) + { + aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic); + bSucc = true; + } + } + } + if (!bSucc) + return; + + aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit)); + + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + aNumFmt.SetCharFormatName(m_sNumCharFmtName); + aNumFmt.SetGraphic(aGrfName); + + // set size for a later comparison + const SvxBrushItem* pBrushItem = aNumFmt.GetBrush(); + // initiate asynchronous loading + sal_Int16 eOrient = aNumFmt.GetVertOrient(); + aNumFmt.SetGraphicBrush(pBrushItem, &aSize, &eOrient); + aInitSize[i] = aNumFmt.GetGraphicSize(); + + pActNum->SetLevel(i, aNumFmt); + } + nMask <<= 1; + } + m_xRatioCB->set_sensitive(true); + m_xWidthFT->set_sensitive(true); + m_xHeightFT->set_sensitive(true); + m_xWidthMF->set_sensitive(true); + m_xHeightMF->set_sensitive(true); + SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit); + SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit); + + SetModified(); + //needed due to asynchronous loading of graphics in the SvxBrushItem + aInvalidateTimer.Start(); +} + +IMPL_LINK_NOARG(SvxBulletAndPositionDlg, PopupActivateHdl_Impl, weld::Toggleable&, void) +{ + if (m_xGalleryMenu) + return; + + m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu"); + weld::WaitObject aWait(p_Window); + + if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames)) + return; + + GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS); + + Graphic aGraphic; + OUString sGrfName; + ScopedVclPtrInstance<VirtualDevice> pVD; + size_t i = 0; + for (const auto& grfName : aGrfNames) + { + sGrfName = grfName; + OUString sItemId = "gallery" + OUString::number(i); + INetURLObject aObj(sGrfName); + if (aObj.GetProtocol() == INetProtocol::File) + sGrfName = aObj.PathToFileName(); + if (GalleryExplorer::GetGraphicObj(GALLERY_THEME_BULLETS, i, &aGraphic)) + { + BitmapEx aBitmap(aGraphic.GetBitmapEx()); + Size aSize(aBitmap.GetSizePixel()); + if (aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT) + { + bool bWidth = aSize.Width() > aSize.Height(); + double nScale = bWidth + ? double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()) + : double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height()); + aBitmap.Scale(nScale, nScale); + } + pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false); + pVD->DrawBitmapEx(Point(), aBitmap); + + // We want to show only icon names not full path. + aObj.removeExtension(); + OUString sIconName = aObj.GetLastName(INetURLObject::DecodeMechanism::WithCharset); + + m_xGalleryMenu->append(sItemId, sIconName, *pVD); + } + else + { + m_xGalleryMenu->append(sItemId, sGrfName); + } + ++i; + } + GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS); +} + +IMPL_LINK_NOARG(SvxBulletAndPositionDlg, BulletHdl_Impl, weld::Button&, void) +{ + SvxCharacterMap aMap(p_Window, nullptr, nullptr); + + sal_uInt16 nMask = 1; + std::optional<vcl::Font> pFmtFont; + bool bSameBullet = true; + sal_UCS4 cBullet = 0; + bool bFirst = true; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i); + if (bFirst) + { + cBullet = rCurFmt.GetBulletChar(); + } + else if (rCurFmt.GetBulletChar() != cBullet) + { + bSameBullet = false; + break; + } + if (!pFmtFont) + pFmtFont = rCurFmt.GetBulletFont(); + bFirst = false; + } + nMask <<= 1; + } + + if (pFmtFont) + aMap.SetCharFont(*pFmtFont); + else + aMap.SetCharFont(aActBulletFont); + if (bSameBullet) + aMap.SetChar(cBullet); + if (aMap.run() != RET_OK) + return; + + // change Font Numrules + aActBulletFont = aMap.GetCharFont(); + + sal_uInt16 _nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & _nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + aNumFmt.SetBulletFont(&aActBulletFont); + aNumFmt.SetBulletChar(aMap.GetChar()); + pActNum->SetLevel(i, aNumFmt); + } + _nMask <<= 1; + } + + SetModified(); +} + +IMPL_LINK(SvxBulletAndPositionDlg, SizeHdl_Impl, weld::MetricSpinButton&, rField, void) +{ + bool bWidth = &rField == m_xWidthMF.get(); + bLastWidthModified = bWidth; + bool bRatio = m_xRatioCB->get_active(); + tools::Long nWidthVal = static_cast<tools::Long>( + m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH))); + tools::Long nHeightVal = static_cast<tools::Long>( + m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH))); + nWidthVal = OutputDevice::LogicToLogic(nWidthVal, MapUnit::Map100thMM, eCoreUnit); + nHeightVal = OutputDevice::LogicToLogic(nHeightVal, MapUnit::Map100thMM, eCoreUnit); + double fSizeRatio; + + bool bRepaint = false; + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + if (SVX_NUM_BITMAP == (aNumFmt.GetNumberingType() & (~LINK_TOKEN))) + { + Size aSize(aNumFmt.GetGraphicSize()); + Size aSaveSize(aSize); + + if (aInitSize[i].Height()) + fSizeRatio = static_cast<double>(aInitSize[i].Width()) + / static_cast<double>(aInitSize[i].Height()); + else + fSizeRatio = double(1); + + if (bWidth) + { + tools::Long nDelta = nWidthVal - aInitSize[i].Width(); + aSize.setWidth(nWidthVal); + if (bRatio) + { + aSize.setHeight( + aInitSize[i].Height() + + static_cast<tools::Long>(static_cast<double>(nDelta) / fSizeRatio)); + m_xHeightMF->set_value(m_xHeightMF->normalize(OutputDevice::LogicToLogic( + aSize.Height(), eCoreUnit, MapUnit::Map100thMM)), + FieldUnit::MM_100TH); + } + } + else + { + tools::Long nDelta = nHeightVal - aInitSize[i].Height(); + aSize.setHeight(nHeightVal); + if (bRatio) + { + aSize.setWidth( + aInitSize[i].Width() + + static_cast<tools::Long>(static_cast<double>(nDelta) * fSizeRatio)); + m_xWidthMF->set_value(m_xWidthMF->normalize(OutputDevice::LogicToLogic( + aSize.Width(), eCoreUnit, MapUnit::Map100thMM)), + FieldUnit::MM_100TH); + } + } + const SvxBrushItem* pBrushItem = aNumFmt.GetBrush(); + sal_Int16 eOrient = aNumFmt.GetVertOrient(); + if (aSize != aSaveSize) + bRepaint = true; + aNumFmt.SetGraphicBrush(pBrushItem, &aSize, &eOrient); + pActNum->SetLevel(i, aNumFmt); + } + } + nMask <<= 1; + } + SetModified(bRepaint); +} + +IMPL_LINK(SvxBulletAndPositionDlg, RatioHdl_Impl, weld::Toggleable&, rBox, void) +{ + if (rBox.get_active()) + { + if (bLastWidthModified) + SizeHdl_Impl(*m_xWidthMF); + else + SizeHdl_Impl(*m_xHeightMF); + } +} + +IMPL_LINK(SvxBulletAndPositionDlg, SelectLeftAlignmentHdl_Impl, weld::Toggleable&, rButton, void) +{ + if (rButton.get_active()) + { + SetAlignmentHdl_Impl(SvxAdjust::Left); + + m_xCenterTB->set_active(false); + m_xRightTB->set_active(false); + + SetModified(); + } +} + +IMPL_LINK(SvxBulletAndPositionDlg, SelectCenterAlignmentHdl_Impl, weld::Toggleable&, rButton, void) +{ + if (rButton.get_active()) + { + SetAlignmentHdl_Impl(SvxAdjust::Center); + + m_xLeftTB->set_active(false); + m_xRightTB->set_active(false); + + SetModified(); + } +} + +IMPL_LINK(SvxBulletAndPositionDlg, SelectRightAlignmentHdl_Impl, weld::Toggleable&, rButton, void) +{ + if (rButton.get_active()) + { + SetAlignmentHdl_Impl(SvxAdjust::Right); + + m_xLeftTB->set_active(false); + m_xCenterTB->set_active(false); + + SetModified(); + } +} + +void SvxBulletAndPositionDlg::SetAlignmentHdl_Impl(SvxAdjust eAdjust) +{ + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + aNumFmt.SetNumAdjust(eAdjust); + pActNum->SetLevel(i, aNumFmt); + } + nMask <<= 1; + } +} + +IMPL_LINK(SvxBulletAndPositionDlg, ApplyToMasterHdl_Impl, weld::Toggleable&, rButton, void) +{ + bApplyToMaster = rButton.get_active(); +} + +IMPL_LINK_NOARG(SvxBulletAndPositionDlg, ResetHdl_Impl, weld::Button&, void) +{ + Reset(&rFirstStateSet); +} + +IMPL_LINK(SvxBulletAndPositionDlg, EditModifyHdl_Impl, weld::Entry&, rEdit, void) +{ + EditModifyHdl_Impl(&rEdit); +} + +IMPL_LINK(SvxBulletAndPositionDlg, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void) +{ + EditModifyHdl_Impl(&rSpinButton); +} + +IMPL_LINK(SvxBulletAndPositionDlg, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void) +{ + if (bInInitControl) + return; + tools::Long nValue = GetCoreValue(rFld, eCoreUnit); + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + if (&rFld == m_xDistBorderMF.get()) + { + if (m_xRelativeCB->get_active()) + { + if (0 == i) + { + auto const nTmp = aNumFmt.GetFirstLineOffset(); + aNumFmt.SetAbsLSpace(nValue - nTmp); + } + else + { + tools::Long nTmp = pActNum->GetLevel(i - 1).GetAbsLSpace() + + pActNum->GetLevel(i - 1).GetFirstLineOffset() + - pActNum->GetLevel(i).GetFirstLineOffset(); + + aNumFmt.SetAbsLSpace(nValue + nTmp); + } + } + else + { + aNumFmt.SetAbsLSpace(nValue - aNumFmt.GetFirstLineOffset()); + } + } + else if (&rFld == m_xIndentMF.get()) + { + // together with the FirstLineOffset the AbsLSpace must be changed, too + tools::Long nDiff = nValue + aNumFmt.GetFirstLineOffset(); + auto const nAbsLSpace = aNumFmt.GetAbsLSpace(); + aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff); + aNumFmt.SetFirstLineOffset(-nValue); + } + + pActNum->SetLevel(i, aNumFmt); + } + nMask <<= 1; + } + + SetModified(); + if (!m_xDistBorderMF->get_sensitive()) + { + m_xDistBorderMF->set_text(""); + } + + sal_Int32 aLastLevelLSpace + = pActNum->GetLevel(pActNum->GetLevelCount() - 1).GetAbsLSpace() / 40; + m_aPreviewWIN.set_size_request(aLastLevelLSpace, 300); +} + +IMPL_LINK(SvxBulletAndPositionDlg, RelativeHdl_Impl, weld::Toggleable&, rBox, void) +{ + bool bOn = rBox.get_active(); + bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl; + bool bSetValue = false; + tools::Long nValue = 0; + if (bOn || bSingleSelection) + { + sal_uInt16 nMask = 1; + bool bFirst = true; + bSetValue = true; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + const SvxNumberFormat& rNumFmt = pActNum->GetLevel(i); + if (bFirst) + { + nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset(); + if (bOn && i) + nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + + pActNum->GetLevel(i - 1).GetFirstLineOffset()); + } + else + bSetValue = nValue + == (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) + - (pActNum->GetLevel(i - 1).GetAbsLSpace() + + pActNum->GetLevel(i - 1).GetFirstLineOffset()); + bFirst = false; + } + nMask <<= 1; + } + } + if (bSetValue) + SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit); + else + m_xDistBorderMF->set_text(""); + m_xDistBorderMF->set_sensitive(bOn || bSingleSelection); + m_xDistBorderFT->set_sensitive(bOn || bSingleSelection); + bLastRelative = bOn; +} + +void SvxBulletAndPositionDlg::EditModifyHdl_Impl(const weld::Entry* pEdit) +{ + bool bPrefixOrSuffix = (pEdit == m_xPrefixED.get()) || (pEdit == m_xSuffixED.get()); + bool bStart = pEdit == m_xStartED.get(); + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + if (bPrefixOrSuffix) + aNumFmt.SetListFormat(m_xPrefixED->get_text(), m_xSuffixED->get_text(), i); + else if (bStart) + aNumFmt.SetStart(m_xStartED->get_value()); + pActNum->SetLevel(i, aNumFmt); + } + nMask <<= 1; + } + SetModified(); +} + +void SvxBulletAndPositionDlg::SetModified(bool bRepaint) +{ + bModified = true; + if (bRepaint) + { + m_aPreviewWIN.SetLevel(nActNumLvl); + m_aPreviewWIN.Invalidate(); + } +} + +void SvxBulletAndPositionDlg::InitPosAndSpaceMode() +{ + if (pActNum == nullptr) + { + SAL_WARN("cui.tabpages", "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of " + "method -> <pAktNum> has to be already set!"); + return; + } + + SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode = SvxNumberFormat::LABEL_ALIGNMENT; + sal_uInt16 nMask = 1; + for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i) + { + if (nActNumLvl & nMask) + { + SvxNumberFormat aNumFmt(pActNum->GetLevel(i)); + ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode(); + if (ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT) + { + break; + } + } + nMask <<= 1; + } + + bLabelAlignmentPosAndSpaceModeActive = ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/LayerTabBar.cxx b/sd/source/ui/dlg/LayerTabBar.cxx new file mode 100644 index 000000000..41cc90ac7 --- /dev/null +++ b/sd/source/ui/dlg/LayerTabBar.cxx @@ -0,0 +1,437 @@ +/* -*- 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 <LayerTabBar.hxx> +#include <svx/svdlayer.hxx> +#include <svx/svdpagv.hxx> +#include <vcl/commandevent.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/viewfrm.hxx> + +#include <helpids.h> +#include <app.hrc> +#include <strings.hrc> + +#include <DrawViewShell.hxx> +#include <View.hxx> +#include <drawdoc.hxx> +#include <sdresid.hxx> +#include <unokywds.hxx> +#include <DrawDocShell.hxx> +#include <drawview.hxx> +#include <undolayer.hxx> + +namespace sd { + +/** + * default constructor + */ +LayerTabBar::LayerTabBar(DrawViewShell* pViewSh, vcl::Window* pParent) + : TabBar( pParent, WinBits( WB_BORDER | WB_3DLOOK | WB_SCROLL ) ), + DropTargetHelper( this ), + pDrViewSh(pViewSh) +{ + EnableEditMode(); + SetSizePixel(Size(0, 0)); + SetMaxPageWidth( 150 ); + SetHelpId( HID_SD_TABBAR_LAYERS ); +} + +LayerTabBar::~LayerTabBar() +{ + disposeOnce(); +} + +void LayerTabBar::dispose() +{ + DropTargetHelper::dispose(); + TabBar::dispose(); +} + +OUString LayerTabBar::convertToLocalizedName(const OUString& rName) +{ + if ( rName == sUNO_LayerName_background ) + return SdResId( STR_LAYER_BCKGRND ); + + if ( rName == sUNO_LayerName_background_objects ) + return SdResId( STR_LAYER_BCKGRNDOBJ ); + + if ( rName == sUNO_LayerName_layout ) + return SdResId( STR_LAYER_LAYOUT ); + + if ( rName == sUNO_LayerName_controls ) + return SdResId( STR_LAYER_CONTROLS ); + + if ( rName == sUNO_LayerName_measurelines ) + return SdResId( STR_LAYER_MEASURELINES ); + + return rName; +} + +// Use a method name, that is specific to LayerTabBar to make code better readable +OUString LayerTabBar::GetLayerName(sal_uInt16 nPageId) const +{ + return GetAuxiliaryText(nPageId); +} + +void LayerTabBar::SetLayerName( sal_uInt16 nPageId, const OUString& rText ) +{ + SetAuxiliaryText(nPageId, rText); +} + +// Here "Page" is a tab in the LayerTabBar. +void LayerTabBar::InsertPage( sal_uInt16 nPageId, const OUString& rText, + TabBarPageBits nBits, sal_uInt16 nPos) +{ + OUString sLocalizedName(convertToLocalizedName(rText)); + TabBar::InsertPage(nPageId, sLocalizedName, nBits, nPos ); + SetLayerName(nPageId, rText); +} + +void LayerTabBar::SetPageText( sal_uInt16 nPageId, const OUString& rText ) +{ + OUString sLocalizedName(convertToLocalizedName(rText)); + SetLayerName(nPageId, rText); + TabBar::SetPageText(nPageId, sLocalizedName); +} + +bool LayerTabBar::IsLocalizedNameOfStandardLayer(std::u16string_view rName) +{ + return ( rName == SdResId(STR_LAYER_LAYOUT) + || rName == SdResId(STR_LAYER_CONTROLS) + || rName == SdResId(STR_LAYER_MEASURELINES) + || rName == SdResId(STR_LAYER_BCKGRND) + || rName == SdResId(STR_LAYER_BCKGRNDOBJ) ); +} + +bool LayerTabBar::IsRealNameOfStandardLayer(std::u16string_view rName) +{ + return ( rName == sUNO_LayerName_layout + || rName == sUNO_LayerName_controls + || rName == sUNO_LayerName_measurelines + || rName == sUNO_LayerName_background + || rName == sUNO_LayerName_background_objects ); +} + +void LayerTabBar::Select() +{ + SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); + pDispatcher->Execute(SID_SWITCHLAYER, SfxCallMode::ASYNCHRON); +} + +void LayerTabBar::MouseButtonDown(const MouseEvent& rMEvt) +{ + bool bSetPageID=false; + + if (rMEvt.IsLeft()) + { + Point aPosPixel = rMEvt.GetPosPixel(); + sal_uInt16 aTabId = GetPageId( PixelToLogic(aPosPixel) ); + if (aTabId == 0) + { + SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); + pDispatcher->Execute(SID_INSERTLAYER, SfxCallMode::SYNCHRON); + + bSetPageID=true; + } + else if (rMEvt.IsMod2()) + { + // direct editing of tab text + // make sure the clicked tab is the current tab otherwise Edit() acts on the wrong tab + if ( aTabId != GetCurPageId()) + { + MouseEvent aSyntheticEvent (rMEvt.GetPosPixel(), 1, MouseEventModifiers::SYNTHETIC, MOUSE_LEFT, 0); + TabBar::MouseButtonDown(aSyntheticEvent); + } + } + else if (rMEvt.IsMod1() || rMEvt.IsShift()) + { + // keyboard Shortcuts to change layer attributes + + OUString aName(GetLayerName(aTabId)); + SdrPageView* pPV = pDrViewSh->GetView()->GetSdrPageView(); + + // Save old state + + bool bOldPrintable = pPV->IsLayerPrintable(aName); + bool bOldVisible = pPV->IsLayerVisible(aName); + bool bOldLocked = pPV->IsLayerLocked(aName); + + bool bNewPrintable = bOldPrintable; + bool bNewVisible = bOldVisible; + bool bNewLocked = bOldLocked; + + if (rMEvt.IsMod1() && rMEvt.IsShift()) + { + // Shift+Ctrl: Toggle between layer printable / not printable + bNewPrintable = !bOldPrintable; + pPV->SetLayerPrintable(aName, bNewPrintable); + } + else if (rMEvt.IsShift()) + { + // Shift: Toggle between layer visible / hidden + bNewVisible = !bOldVisible; + pPV->SetLayerVisible(aName, bNewVisible); + } + else // if (rMEvt.IsMod1()) + { + // Ctrl: Toggle between layer locked / unlocked + bNewLocked = !bOldLocked; + pPV->SetLayerLocked(aName, bNewLocked); + } + + pDrViewSh->ResetActualLayer(); + + // Add Undo action + + ::sd::View* pView = pDrViewSh->GetView(); + DrawView* pDrView = dynamic_cast<DrawView*>(pView); + + SdDrawDocument& rDoc = pView->GetDoc(); + SdrLayer* pLayer = rDoc.GetLayerAdmin().GetLayer(aName); + + if (pLayer) + { + assert (pDrView && "Change layer attribute undo action is only working with a SdDrawView"); + if(pDrView) + { + SfxUndoManager* pManager = rDoc.GetDocSh()->GetUndoManager(); + std::unique_ptr<SdLayerModifyUndoAction> pAction(new SdLayerModifyUndoAction( + &rDoc, + pLayer, + aName, + pLayer->GetTitle(), + pLayer->GetDescription(), + bOldVisible, + bOldLocked, + bOldPrintable, + aName, + pLayer->GetTitle(), + pLayer->GetDescription(), + bNewVisible, + bNewLocked, + bNewPrintable + )); + pManager->AddUndoAction(std::move(pAction)); + } + } + + // Mark document changed + + pView->GetDoc().SetChanged(); + } + } + + // If you insert a new layer you must not call TabBar::MouseButtonDown(rMEvt); + // because you want to activate the new layer + if( !bSetPageID ) + TabBar::MouseButtonDown(rMEvt); +} + +void LayerTabBar::DoubleClick() +{ + if (GetCurPageId() != 0) + { + SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); + pDispatcher->Execute( SID_MODIFYLAYER, SfxCallMode::SYNCHRON ); + } +} + +/** + * AcceptDrop-Event + */ + +sal_Int8 LayerTabBar::AcceptDrop( const AcceptDropEvent& rEvt ) +{ + sal_Int8 nRet = DND_ACTION_NONE; + + if( rEvt.mbLeaving ) + EndSwitchPage(); + + if( !pDrViewSh->GetDocSh()->IsReadOnly() ) + { + Point aPos( PixelToLogic( rEvt.maPosPixel ) ); + OUString sLayerName( GetLayerName(GetPageId(aPos)) ); + SdrLayerID nLayerId = pDrViewSh->GetView()->GetDoc().GetLayerAdmin().GetLayerID(sLayerName); + + nRet = pDrViewSh->AcceptDrop( rEvt, *this, nullptr, SDRPAGE_NOTFOUND, nLayerId ); + + SwitchPage( aPos ); + } + + return nRet; +} + +/** + * ExecuteDrop-Event + */ +sal_Int8 LayerTabBar::ExecuteDrop( const ExecuteDropEvent& rEvt ) +{ + Point aPos( PixelToLogic(rEvt.maPosPixel) ); + OUString sLayerName( GetLayerName(GetPageId(aPos)) ); + SdrLayerID nLayerId = pDrViewSh->GetView()->GetDoc().GetLayerAdmin().GetLayerID(sLayerName); + + sal_Int8 nRet = pDrViewSh->ExecuteDrop( rEvt, *this, nullptr, SDRPAGE_NOTFOUND, nLayerId ); + + EndSwitchPage(); + + return nRet; + +} + +void LayerTabBar::Command(const CommandEvent& rCEvt) +{ + if ( rCEvt.GetCommand() == CommandEventId::ContextMenu ) + { + SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); + pDispatcher->ExecutePopup("layertab"); + } +} + +bool LayerTabBar::StartRenaming() +{ + bool bOK = true; + OUString aLayerName = GetLayerName( GetEditPageId() ); + + if ( IsRealNameOfStandardLayer(aLayerName)) + { + // It is not allowed to change these names + bOK = false; + } + else + { + ::sd::View* pView = pDrViewSh->GetView(); + + if ( pView->IsTextEdit() ) + { + pView->SdrEndTextEdit(); + } + } + + return bOK; +} + +TabBarAllowRenamingReturnCode LayerTabBar::AllowRenaming() +{ + bool bOK = true; + + // Check if names already exists + ::sd::View* pView = pDrViewSh->GetView(); + SdDrawDocument& rDoc = pView->GetDoc(); + OUString aLayerName = pView->GetActiveLayer(); + SdrLayerAdmin& rLayerAdmin = rDoc.GetLayerAdmin(); + OUString aNewName( GetEditText() ); + + if (aNewName.isEmpty() || + (rLayerAdmin.GetLayer( aNewName ) && aLayerName != aNewName) ) + { + // Name already exists. + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pDrViewSh->GetViewFrame()->GetFrameWeld(), + VclMessageType::Warning, VclButtonsType::Ok, + SdResId(STR_WARN_NAME_DUPLICATE))); + xWarn->run(); + bOK = false; + } + + if (bOK) + { + if ( IsLocalizedNameOfStandardLayer(aNewName) || IsRealNameOfStandardLayer(aNewName) ) + { + // Standard layer names may not be changed. + bOK = false; + } + } + + return bOK ? TABBAR_RENAMING_YES : TABBAR_RENAMING_NO; +} + +void LayerTabBar::EndRenaming() +{ + if( IsEditModeCanceled() ) + return; + + ::sd::View* pView = pDrViewSh->GetView(); + DrawView* pDrView = dynamic_cast<DrawView*>( pView ); + + SdDrawDocument& rDoc = pView->GetDoc(); + OUString aLayerName = pView->GetActiveLayer(); + SdrLayerAdmin& rLayerAdmin = rDoc.GetLayerAdmin(); + SdrLayer* pLayer = rLayerAdmin.GetLayer(aLayerName); + + if (!pLayer) + return; + + OUString aNewName( GetEditText() ); + assert (pDrView && "Rename layer undo action is only working with a SdDrawView"); + if( pDrView ) + { + SfxUndoManager* pManager = rDoc.GetDocSh()->GetUndoManager(); + std::unique_ptr<SdLayerModifyUndoAction> pAction(new SdLayerModifyUndoAction( + &rDoc, + pLayer, + aLayerName, + pLayer->GetTitle(), + pLayer->GetDescription(), + pDrView->IsLayerVisible(aLayerName), + pDrView->IsLayerLocked(aLayerName), + pDrView->IsLayerPrintable(aLayerName), + aNewName, + pLayer->GetTitle(), + pLayer->GetDescription(), + pDrView->IsLayerVisible(aLayerName), + pDrView->IsLayerLocked(aLayerName), + pDrView->IsLayerPrintable(aLayerName) + )); + pManager->AddUndoAction( std::move(pAction) ); + } + + // First notify View since SetName() calls ResetActualLayer() and + // the View then already has to know the Layer + pView->SetActiveLayer(aNewName); + pLayer->SetName(aNewName); + rDoc.SetChanged(); +} + +void LayerTabBar::ActivatePage() +{ + if (pDrViewSh!=nullptr) + { + + SfxDispatcher* pDispatcher = pDrViewSh->GetViewFrame()->GetDispatcher(); + pDispatcher->Execute(SID_SWITCHLAYER, SfxCallMode::ASYNCHRON); + } +} + +void LayerTabBar::SendActivatePageEvent() +{ + CallEventListeners (VclEventId::TabbarPageActivated, + reinterpret_cast<void*>(GetCurPageId())); +} + +void LayerTabBar::SendDeactivatePageEvent() +{ + CallEventListeners (VclEventId::TabbarPageDeactivated, + reinterpret_cast<void*>(GetCurPageId())); +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/NavigatorChildWindow.cxx b/sd/source/ui/dlg/NavigatorChildWindow.cxx new file mode 100644 index 000000000..6055c238a --- /dev/null +++ b/sd/source/ui/dlg/NavigatorChildWindow.cxx @@ -0,0 +1,100 @@ +/* -*- 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 <NavigatorChildWindow.hxx> +#include <navigatr.hxx> +#include <app.hrc> +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/sfxsids.hrc> +#include <svl/eitem.hxx> + +namespace sd { + +static void RequestNavigatorUpdate (SfxBindings const * pBindings) +{ + if (pBindings != nullptr + && pBindings->GetDispatcher() != nullptr) + { + SfxBoolItem aItem (SID_NAVIGATOR_INIT, true); + pBindings->GetDispatcher()->ExecuteList( + SID_NAVIGATOR_INIT, + SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, + { &aItem }); + } +} + +SdNavigatorFloat::SdNavigatorFloat(SfxBindings* _pBindings, SfxChildWindow* _pMgr, + vcl::Window* _pParent, SfxChildWinInfo* pInfo) + : SfxNavigator(_pBindings, _pMgr, _pParent, pInfo) + , m_xNavWin(std::make_unique<SdNavigatorWin>(m_xContainer.get(), _pBindings, this)) + , m_bSetInitialFocusOnActivate(true) +{ + m_xNavWin->SetUpdateRequestFunctor( + [_pBindings] () { return RequestNavigatorUpdate(_pBindings); }); + + SetMinOutputSizePixel(GetOptimalSize()); +} + +void SdNavigatorFloat::Activate() +{ + SfxNavigator::Activate(); + // tdf#141708 defer grabbing focus to preferred widget until the float is + // first activated + if (m_bSetInitialFocusOnActivate) + { + m_xNavWin->FirstFocus(); + m_bSetInitialFocusOnActivate = false; + } +} + +void SdNavigatorFloat::InitTreeLB(const SdDrawDocument* pDoc) +{ + m_xNavWin->InitTreeLB(pDoc); +} + +void SdNavigatorFloat::FreshTree(const SdDrawDocument* pDoc) +{ + m_xNavWin->FreshTree(pDoc); +} + +void SdNavigatorFloat::dispose() +{ + m_xNavWin.reset(); + SfxNavigator::dispose(); +} + +SdNavigatorFloat::~SdNavigatorFloat() +{ + disposeOnce(); +} + +SFX_IMPL_DOCKINGWINDOW(SdNavigatorWrapper, SID_NAVIGATOR); + +SdNavigatorWrapper::SdNavigatorWrapper(vcl::Window *_pParent, sal_uInt16 nId, + SfxBindings* pBindings, SfxChildWinInfo* pInfo) + : SfxNavigatorWrapper(_pParent, nId) +{ + SetWindow(VclPtr<SdNavigatorFloat>::Create(pBindings, this, _pParent, pInfo)); + Initialize(); +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/PaneChildWindows.cxx b/sd/source/ui/dlg/PaneChildWindows.cxx new file mode 100644 index 000000000..7f73e005b --- /dev/null +++ b/sd/source/ui/dlg/PaneChildWindows.cxx @@ -0,0 +1,107 @@ +/* -*- 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 <PaneChildWindows.hxx> +#include <PaneDockingWindow.hxx> +#include <ViewShellBase.hxx> +#include <framework/FrameworkHelper.hxx> +#include <app.hrc> +#include <strings.hrc> +#include <sdresid.hxx> + +#include <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> + +namespace sd { + + +SFX_IMPL_DOCKINGWINDOW_WITHID(LeftPaneImpressChildWindow, SID_LEFT_PANE_IMPRESS) +SFX_IMPL_DOCKINGWINDOW_WITHID(LeftPaneDrawChildWindow, SID_LEFT_PANE_DRAW) + +//===== PaneChildWindow ======================================================= +PaneChildWindow::PaneChildWindow ( + vcl::Window* pParentWindow, + sal_uInt16 nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo, + TranslateId pTitleBarResId) + : SfxChildWindow (pParentWindow, nId) +{ + SetWindow( VclPtr<PaneDockingWindow>::Create( + pBindings, + this, + pParentWindow, + SdResId(pTitleBarResId))); + SetAlignment(SfxChildAlignment::LEFT); + SfxDockingWindow* pDockingWindow = static_cast<SfxDockingWindow*>(GetWindow()); + pDockingWindow->EnableInput(); + pDockingWindow->Initialize(pInfo); + SetHideNotDelete(true); + + ViewShellBase* pBase = ViewShellBase::GetViewShellBase(pBindings->GetDispatcher()->GetFrame()); + if (pBase != nullptr) + { + framework::FrameworkHelper::Instance(*pBase)->UpdateConfiguration(); + } +} + +PaneChildWindow::~PaneChildWindow() +{ + ViewShellBase* pBase = nullptr; + PaneDockingWindow* pDockingWindow = dynamic_cast<PaneDockingWindow*>(GetWindow()); + if (pDockingWindow != nullptr) + pBase = ViewShellBase::GetViewShellBase( + pDockingWindow->GetBindings().GetDispatcher()->GetFrame()); + if (pBase != nullptr) + framework::FrameworkHelper::Instance(*pBase)->UpdateConfiguration(); +} + +//===== LeftPaneImpressChildWindow ============================================ +LeftPaneImpressChildWindow::LeftPaneImpressChildWindow ( + vcl::Window* pParentWindow, + sal_uInt16 nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo) + : PaneChildWindow( + pParentWindow, + nId, + pBindings, + pInfo, + STR_LEFT_PANE_IMPRESS_TITLE) +{ +} + +//===== LeftPaneDrawChildWindow =============================================== +LeftPaneDrawChildWindow::LeftPaneDrawChildWindow ( + vcl::Window* pParentWindow, + sal_uInt16 nId, + SfxBindings* pBindings, + SfxChildWinInfo* pInfo) + : PaneChildWindow( + pParentWindow, + nId, + pBindings, + pInfo, + STR_LEFT_PANE_DRAW_TITLE) +{ +} + +} // end of namespace ::sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/PaneDockingWindow.cxx b/sd/source/ui/dlg/PaneDockingWindow.cxx new file mode 100644 index 000000000..6f7332ad9 --- /dev/null +++ b/sd/source/ui/dlg/PaneDockingWindow.cxx @@ -0,0 +1,127 @@ +/* -*- 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 <PaneDockingWindow.hxx> +#include <ViewShellBase.hxx> +#include <framework/FrameworkHelper.hxx> + +#include <sfx2/dispatch.hxx> +#include <vcl/splitwin.hxx> +#include <tools/wintypes.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::drawing::framework; +using ::sd::TitledDockingWindow; + +namespace sd { + +PaneDockingWindow::PaneDockingWindow( + SfxBindings *_pBindings, SfxChildWindow *pChildWindow, vcl::Window* pParent, + const OUString& rsTitle ) + : TitledDockingWindow(_pBindings, pChildWindow, pParent) +{ + SetTitle(rsTitle); + SetSizePixel(LogicToPixel(Size(80,200), MapMode(MapUnit::MapAppFont))); +} + +PaneDockingWindow::~PaneDockingWindow() +{ +} + +void PaneDockingWindow::StateChanged( StateChangedType nType ) +{ + switch (nType) + { + case StateChangedType::InitShow: + Resize(); + GetContentWindow().SetStyle(GetContentWindow().GetStyle() | WB_DIALOGCONTROL); + break; + + case StateChangedType::Visible: + { + // The visibility of the docking window has changed. Tell the + // ConfigurationController so that it can activate or deactivate + // a/the view for the pane. + // Without this the side panes remain empty after closing an + // in-place slide show. + ViewShellBase* pBase = ViewShellBase::GetViewShellBase( + GetBindings().GetDispatcher()->GetFrame()); + if (pBase != nullptr) + { + framework::FrameworkHelper::Instance(*pBase)->UpdateConfiguration(); + } + } + break; + + default:; + } + SfxDockingWindow::StateChanged (nType); +} + +void PaneDockingWindow::MouseButtonDown (const MouseEvent& rEvent) +{ + if (rEvent.GetButtons() == MOUSE_LEFT) + { + // For some strange reason we have to set the WB_DIALOGCONTROL at + // the content window in order to have it pass focus to its content + // window. Without setting this flag here that works only on views + // that have not been taken from the cash and relocated to this pane + // docking window. + GetContentWindow().SetStyle(GetContentWindow().GetStyle() | WB_DIALOGCONTROL); + GetContentWindow().GrabFocus(); + } + SfxDockingWindow::MouseButtonDown(rEvent); +} + +void PaneDockingWindow::SetValidSizeRange (const Range& rValidSizeRange) +{ + SplitWindow* pSplitWindow = dynamic_cast<SplitWindow*>(GetParent()); + if (pSplitWindow == nullptr) + return; + + const sal_uInt16 nId (pSplitWindow->GetItemId(static_cast< vcl::Window*>(this))); + const sal_uInt16 nSetId (pSplitWindow->GetSet(nId)); + // Because the PaneDockingWindow paints its own decoration, we have + // to compensate the valid size range for that. + const SvBorder aBorder (GetDecorationBorder()); + sal_Int32 nCompensation (pSplitWindow->IsHorizontal() + ? aBorder.Top() + aBorder.Bottom() + : aBorder.Left() + aBorder.Right()); + pSplitWindow->SetItemSizeRange( + nSetId, + Range( + rValidSizeRange.Min() + nCompensation, + rValidSizeRange.Max() + nCompensation)); +} + +PaneDockingWindow::Orientation PaneDockingWindow::GetOrientation() const +{ + SplitWindow* pSplitWindow = dynamic_cast<SplitWindow*>(GetParent()); + if (pSplitWindow == nullptr) + return UnknownOrientation; + else if (pSplitWindow->IsHorizontal()) + return HorizontalOrientation; + else + return VerticalOrientation; +} + +} // end of namespace ::sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/PaneShells.cxx b/sd/source/ui/dlg/PaneShells.cxx new file mode 100644 index 000000000..8870d1186 --- /dev/null +++ b/sd/source/ui/dlg/PaneShells.cxx @@ -0,0 +1,79 @@ +/* -*- 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 <PaneShells.hxx> + +#include <PaneChildWindows.hxx> + +#include <sfx2/msg.hxx> +#include <sfx2/objface.hxx> + +namespace sd { + +//===== LeftImpressPaneShell ================================================== + +static SfxSlot aLeftImpressPaneShellSlots_Impl[] = +{ + { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, nullptr } +}; + +SFX_IMPL_INTERFACE(LeftImpressPaneShell, SfxShell) + +void LeftImpressPaneShell::InitInterface_Impl() +{ + GetStaticInterface()->RegisterChildWindow(::sd::LeftPaneImpressChildWindow::GetChildWindowId()); +} + + +LeftImpressPaneShell::LeftImpressPaneShell() +{ + SetName("LeftImpressPane"); +} + +LeftImpressPaneShell::~LeftImpressPaneShell() +{ +} + +//===== LeftDrawPaneShell ===================================================== + +static SfxSlot aLeftDrawPaneShellSlots_Impl[] = +{ + { 0, SfxGroupId::NONE, SfxSlotMode::NONE, 0, 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, SfxDisableFlags::NONE, nullptr } +}; + +SFX_IMPL_INTERFACE(LeftDrawPaneShell, SfxShell) + +void LeftDrawPaneShell::InitInterface_Impl() +{ + GetStaticInterface()->RegisterChildWindow(::sd::LeftPaneDrawChildWindow::GetChildWindowId()); +} + + +LeftDrawPaneShell::LeftDrawPaneShell() +{ + SetName("LeftDrawPane"); +} + +LeftDrawPaneShell::~LeftDrawPaneShell() +{ +} + +} // end of namespace ::sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/PhotoAlbumDialog.cxx b/sd/source/ui/dlg/PhotoAlbumDialog.cxx new file mode 100644 index 000000000..f63afe7bb --- /dev/null +++ b/sd/source/ui/dlg/PhotoAlbumDialog.cxx @@ -0,0 +1,775 @@ +/* -*- 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/. +*/ + +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/processfactory.hxx> +#include <svl/itemset.hxx> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/graphic/GraphicProvider.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#include <sfx2/filedlghelper.hxx> +#include <tools/urlobj.hxx> + +#include <unotools/ucbstreamhelper.hxx> +#include <vcl/graphicfilter.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xfltrit.hxx> +#include <svx/xflclit.hxx> +#include <tools/diagnose_ex.h> +#include <xmloff/autolayout.hxx> + +#include "PhotoAlbumDialog.hxx" +#include <strings.hrc> +#include <sdresid.hxx> +#include <drawdoc.hxx> +#include <sdpage.hxx> + +namespace sd +{ + +SdPhotoAlbumDialog::SdPhotoAlbumDialog(weld::Window* pWindow, SdDrawDocument* pActDoc) + : GenericDialogController(pWindow, "modules/simpress/ui/photoalbum.ui", "PhotoAlbumCreatorDialog") + , m_pDoc(pActDoc) + , m_aImg(m_xDialog.get()) + , m_xCancelBtn(m_xBuilder->weld_button("cancel")) + , m_xCreateBtn(m_xBuilder->weld_button("ok")) + , m_xAddBtn(m_xBuilder->weld_button("add_btn")) + , m_xUpBtn(m_xBuilder->weld_button("up_btn")) + , m_xDownBtn(m_xBuilder->weld_button("down_btn")) + , m_xRemoveBtn(m_xBuilder->weld_button("rem_btn")) + , m_xImagesLst(m_xBuilder->weld_tree_view("images_tree")) + , m_xImg(new weld::CustomWeld(*m_xBuilder, "preview_img", m_aImg)) + , m_xInsTypeCombo(m_xBuilder->weld_combo_box("opt_combo")) + , m_xASRCheck(m_xBuilder->weld_check_button("asr_check")) + , m_xASRCheckCrop(m_xBuilder->weld_check_button("asr_check_crop")) + , m_xCapCheck(m_xBuilder->weld_check_button("cap_check")) + , m_xInsertAsLinkCheck(m_xBuilder->weld_check_button("insert_as_link_check")) +{ + m_xCancelBtn->connect_clicked(LINK(this, SdPhotoAlbumDialog, CancelHdl)); + m_xCreateBtn->connect_clicked(LINK(this, SdPhotoAlbumDialog, CreateHdl)); + + m_xAddBtn->connect_clicked(LINK(this, SdPhotoAlbumDialog, FileHdl)); + m_xUpBtn->connect_clicked(LINK(this, SdPhotoAlbumDialog, UpHdl)); + m_xUpBtn->set_sensitive(false); + m_xDownBtn->connect_clicked(LINK(this, SdPhotoAlbumDialog, DownHdl)); + m_xDownBtn->set_sensitive(false); + m_xRemoveBtn->connect_clicked(LINK(this, SdPhotoAlbumDialog, RemoveHdl)); + m_xRemoveBtn->set_sensitive(false); + m_xImagesLst->connect_changed(LINK(this, SdPhotoAlbumDialog, SelectHdl)); + m_xInsTypeCombo->connect_changed(LINK(this, SdPhotoAlbumDialog, TypeSelectHdl)); + + m_pGraphicFilter = new GraphicFilter; + m_xAddBtn->grab_focus(); +} + +SdPhotoAlbumDialog::~SdPhotoAlbumDialog() +{ +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, CancelHdl, weld::Button&, void) +{ + m_xDialog->response(RET_CANCEL); +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, CreateHdl, weld::Button&, void) +{ + if (m_xImagesLst->n_children() == 0) + { + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, + SdResId(STR_PHOTO_ALBUM_EMPTY_WARNING))); + xWarn->run(); + } + else + { + Reference< drawing::XDrawPagesSupplier > xDPS( m_pDoc->getUnoModel(), uno::UNO_QUERY ); + Reference< drawing::XDrawPages > xDrawPages = xDPS->getDrawPages(); + Reference< lang::XMultiServiceFactory > xShapeFactory( m_pDoc->getUnoModel(), uno::UNO_QUERY ); + + Reference< XComponentContext > xContext(::comphelper::getProcessComponentContext()); + Reference< graphic::XGraphicProvider> xProvider(graphic::GraphicProvider::create(xContext)); + + // determine if to use Captions (use TitleObject) and choose the correct AutoLayout + // from the beginning + const bool bCreateCaptions(m_xCapCheck->get_active()); + const bool bInsertAsLink(m_xInsertAsLinkCheck->get_active()); + const AutoLayout aAutoLayout(bCreateCaptions ? AUTOLAYOUT_TITLE_ONLY : AUTOLAYOUT_NONE); + + // get the option + const int nOpt = m_xInsTypeCombo->get_active(); + if (nOpt == ONE_IMAGE) + { + for( sal_Int32 i = 0; i < m_xImagesLst->n_children(); ++i ) + { + OUString sUrl = m_xImagesLst->get_id(i); + + Reference< drawing::XDrawPage > xSlide = appendNewSlide(aAutoLayout, xDrawPages); + Reference< beans::XPropertySet > xSlideProps( xSlide, uno::UNO_QUERY ); + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl); + + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Size aPageSize; + + xSlideProps->getPropertyValue( + "Width") >>= aPageSize.Width; + xSlideProps->getPropertyValue( + "Height") >>= aPageSize.Height; + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active() && !m_xASRCheckCrop->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, aPageSize); + } + else if (m_xASRCheckCrop->get_active()) + { + aPicSize = createASRSizeCrop(aPicSize, aPageSize); + } + + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width - aPicSize.Width)/2; + aPicPos.Y = (aPageSize.Height - aPicSize.Height)/2; + + xShape->setPosition(aPicPos); + try + { + xSlide->add(xShape); + if (bCreateCaptions) + createCaption( aPageSize ); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + } + else if( nOpt == TWO_IMAGES ) + { + for( sal_Int32 i = 0; i < m_xImagesLst->n_children(); i+=2 ) + { + // create the slide + Reference< drawing::XDrawPage > xSlide = appendNewSlide(aAutoLayout, xDrawPages); + Reference< beans::XPropertySet > xSlideProps( xSlide, uno::UNO_QUERY ); + //Slide dimensions + ::awt::Size aPageSize; + + xSlideProps->getPropertyValue( + "Width") >>= aPageSize.Width; + xSlideProps->getPropertyValue( + "Height") >>= aPageSize.Height; + + // grab the left one + OUString sUrl1 = m_xImagesLst->get_id(i); + // grab the right one + OUString sUrl2 = m_xImagesLst->get_id(i+1); + + if( !sUrl1.isEmpty() ) + { + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl1, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl1); + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, ::awt::Size(aPageSize.Width/2 - 100, aPageSize.Height/2 - 100)); + } + else + { + aPicSize.Width = aPageSize.Width/2 - 100; + aPicSize.Height = aPageSize.Height/2 - 100; + } + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width/4 - aPicSize.Width/2); + aPicPos.Y = aPageSize.Height/2 - aPicSize.Height/2; + + xShape->setPosition(aPicPos); + try + { + xSlide->add(xShape); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + + if( !sUrl2.isEmpty() ) + { + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl2, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl2); + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, ::awt::Size(aPageSize.Width/2 - 100, aPageSize.Height/2 - 100)); + } + else + { + aPicSize.Width = aPageSize.Width/2 - 100; + aPicSize.Height = aPageSize.Height/2 - 100; + } + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width/4 - aPicSize.Width/2) + aPageSize.Width/2; + aPicPos.Y = aPageSize.Height/2 - aPicSize.Height/2; + + xShape->setPosition(aPicPos); + + try + { + xSlide->add(xShape); + if(bCreateCaptions) + createCaption( aPageSize ); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + } + } + else if( nOpt == FOUR_IMAGES ) + { + for( sal_Int32 i = 0; i < m_xImagesLst->n_children(); i+=4 ) + { + // create the slide + Reference< drawing::XDrawPage > xSlide = appendNewSlide(aAutoLayout, xDrawPages); + Reference< beans::XPropertySet > xSlideProps( xSlide, uno::UNO_QUERY ); + //Slide dimensions + ::awt::Size aPageSize; + + xSlideProps->getPropertyValue( + "Width") >>= aPageSize.Width; + xSlideProps->getPropertyValue( + "Height") >>= aPageSize.Height; + + // grab the upper left one + OUString sUrl1 = m_xImagesLst->get_id(i); + + // grab the upper right one + OUString sUrl2 = m_xImagesLst->get_id(i+1); + + // grab the lower left one + OUString sUrl3 = m_xImagesLst->get_id(i+2); + + // grab the lower right one + OUString sUrl4 = m_xImagesLst->get_id(i+3); + + if( !sUrl1.isEmpty() ) + { + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl1, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl1); + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, ::awt::Size(aPageSize.Width/2 - 100, aPageSize.Height/2 - 100)); + } + else + { + aPicSize.Width = aPageSize.Width/2 - 100; + aPicSize.Height = aPageSize.Height/2 - 100; + } + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width/4 - aPicSize.Width/2); + aPicPos.Y = aPageSize.Height/4 - aPicSize.Height/2; + + xShape->setPosition(aPicPos); + try + { + xSlide->add(xShape); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + if( !sUrl2.isEmpty() ) + { + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl2, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl2); + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, ::awt::Size(aPageSize.Width/2 - 100, aPageSize.Height/2 - 100)); + } + else + { + aPicSize.Width = aPageSize.Width/2 - 100; + aPicSize.Height = aPageSize.Height/2 - 100; + } + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width/4 - aPicSize.Width/2) + aPageSize.Width/2; + aPicPos.Y = aPageSize.Height/4 - aPicSize.Height/2; + + xShape->setPosition(aPicPos); + try + { + xSlide->add(xShape); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + if( !sUrl3.isEmpty() ) + { + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl3, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl3); + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, ::awt::Size(aPageSize.Width/2 - 100, aPageSize.Height/2 - 100)); + } + else + { + aPicSize.Width = aPageSize.Width/2 - 100; + aPicSize.Height = aPageSize.Height/2 - 100; + } + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width/4 - aPicSize.Width/2); + aPicPos.Y = aPageSize.Height/4 - aPicSize.Height/2 + aPageSize.Height/2; + + xShape->setPosition(aPicPos); + try + { + xSlide->add(xShape); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + if( !sUrl4.isEmpty() ) + { + Reference< graphic::XGraphic > xGraphic = createXGraphicFromUrl(sUrl4, xProvider); + + Graphic aGraphic(xGraphic); + if (bInsertAsLink) + aGraphic.setOriginURL(sUrl4); + // Save the original size, multiplied with 100 + ::awt::Size aPicSize(aGraphic.GetSizePixel().Width()*100, aGraphic.GetSizePixel().Height()*100); + + Reference< drawing::XShape > xShape( + xShapeFactory->createInstance("com.sun.star.drawing.GraphicObjectShape"), + uno::UNO_QUERY); + + Reference< beans::XPropertySet > xProps( xShape, uno::UNO_QUERY ); + xProps->setPropertyValue("Graphic", ::uno::Any(xGraphic)); + + ::awt::Point aPicPos; + + if (m_xASRCheck->get_active()) + { + // Resize the image, with keeping ASR + aPicSize = createASRSize(aPicSize, ::awt::Size(aPageSize.Width/2 - 100, aPageSize.Height/2 - 100)); + } + else + { + aPicSize.Width = aPageSize.Width/2 - 100; + aPicSize.Height = aPageSize.Height/2 - 100; + } + xShape->setSize(aPicSize); + aPicPos.X = (aPageSize.Width/4 - aPicSize.Width/2) + aPageSize.Width/2; + aPicPos.Y = aPageSize.Height/4 - aPicSize.Height/2 + aPageSize.Height/2; + + xShape->setPosition(aPicPos); + try + { + xSlide->add(xShape); + if(bCreateCaptions) + createCaption( aPageSize ); + } + catch (const css::uno::Exception&) + { + TOOLS_WARN_EXCEPTION( "sd", "" ); + } + } + } + } + else + { + std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Info, VclButtonsType::Ok, + "Function is not implemented!")); + xInfoBox->run(); + } + m_xDialog->response(RET_OK); + } +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, FileHdl, weld::Button&, void) +{ + ::sfx2::FileDialogHelper aDlg( + css::ui::dialogs::TemplateDescription::FILEOPEN_PREVIEW, + FileDialogFlags::Graphic | FileDialogFlags::MultiSelection, m_xDialog.get()); + aDlg.SetContext(sfx2::FileDialogHelper::ImpressPhotoDialog); + + if ( aDlg.Execute() == ERRCODE_NONE ) + { + const Sequence< OUString > aFilesArr = aDlg.GetSelectedFiles(); + for ( const auto& rFile : aFilesArr ) + { + // Store full path, show filename only. Use INetURLObject to display spaces in filename correctly + INetURLObject aUrl(rFile); + m_xImagesLst->append(aUrl.GetMainURL(INetURLObject::DecodeMechanism::NONE), aUrl.GetLastName(INetURLObject::DecodeMechanism::WithCharset), ""); + } + } + EnableDisableButtons(); +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, UpHdl, weld::Button&, void) +{ + const int nActPos = m_xImagesLst->get_selected_index(); + if (nActPos != -1 && nActPos != 0) + { + OUString sActEntry(m_xImagesLst->get_text(nActPos)); + // actual data + OUString sAct(m_xImagesLst->get_id(nActPos)); + + OUString sUpperEntry(m_xImagesLst->get_text(nActPos - 1)); + // upper data + OUString sUpper(m_xImagesLst->get_id(nActPos - 1)); + + m_xImagesLst->remove_text(sActEntry); + m_xImagesLst->remove_text(sUpperEntry); + + m_xImagesLst->insert(nActPos - 1, sActEntry, &sAct, nullptr, nullptr); + m_xImagesLst->insert(nActPos, sUpperEntry, &sUpper, nullptr, nullptr); + + m_xImagesLst->select(nActPos - 1); + } + + EnableDisableButtons(); +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, DownHdl, weld::Button&, void) +{ + const int nActPos = m_xImagesLst->get_selected_index(); + if (!m_xImagesLst->get_text(nActPos + 1).isEmpty()) + { + OUString sActEntry(m_xImagesLst->get_selected_text()); + OUString sAct(m_xImagesLst->get_selected_id()); + + OUString sDownEntry(m_xImagesLst->get_text(nActPos + 1)); + OUString sDown(m_xImagesLst->get_id(nActPos + 1)); + + m_xImagesLst->remove_text(sActEntry); + m_xImagesLst->remove_text(sDownEntry); + + m_xImagesLst->insert(nActPos, sDownEntry, &sDown, nullptr, nullptr); + m_xImagesLst->insert(nActPos + 1, sActEntry, &sAct, nullptr, nullptr); + + m_xImagesLst->select(nActPos + 1); + } + EnableDisableButtons(); +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, RemoveHdl, weld::Button&, void) +{ + m_xImagesLst->remove(m_xImagesLst->get_selected_index()); + m_aImg.SetGraphic(Graphic()); + + EnableDisableButtons(); +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, SelectHdl, weld::TreeView&, void) +{ + OUString sImgUrl = m_xImagesLst->get_selected_id(); + + if (sImgUrl != SdResId(STR_PHOTO_ALBUM_TEXTBOX)) + { + Graphic aGraphic; + INetURLObject aURLObj( sImgUrl ); + + sal_uInt16 nFilter = GRFILTER_FORMAT_DONTKNOW; + + if ( aURLObj.HasError() || INetProtocol::NotValid == aURLObj.GetProtocol() ) + { + aURLObj.SetSmartProtocol( INetProtocol::File ); + aURLObj.SetSmartURL( sImgUrl ); + } + + GraphicFilterImportFlags nFilterImportFlags = GraphicFilterImportFlags::SetLogsizeForJpeg; + // remote? + if ( INetProtocol::File != aURLObj.GetProtocol() ) + { + std::unique_ptr<SvStream> pStream = ::utl::UcbStreamHelper::CreateStream( sImgUrl, StreamMode::READ ); + + if( pStream ) + m_pGraphicFilter->ImportGraphic( aGraphic, sImgUrl, *pStream, nFilter, nullptr, nFilterImportFlags ); + else + m_pGraphicFilter->ImportGraphic( aGraphic, aURLObj, nFilter, nullptr, nFilterImportFlags ); + } + else + { + m_pGraphicFilter->ImportGraphic( aGraphic, aURLObj, nFilter, nullptr, nFilterImportFlags ); + } + + BitmapEx aBmp = aGraphic.GetBitmapEx(); + sal_Int32 nBmpWidth = aBmp.GetSizePixel().Width(); + sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height(); + + double nXRatio = double(200) / nBmpWidth; + double nYRatio = double(150) / nBmpHeight; + if ( nXRatio < nYRatio ) + aBmp.Scale( nXRatio, nXRatio ); + else + aBmp.Scale( nYRatio, nYRatio ); + + aBmp.Convert( BmpConversion::N24Bit ); + m_aImg.SetGraphic(Graphic(aBmp)); + } + else + { + m_aImg.SetGraphic(Graphic()); + } + EnableDisableButtons(); +} + +IMPL_LINK_NOARG(SdPhotoAlbumDialog, TypeSelectHdl, weld::ComboBox&, void) +{ + // Enable "Fill Slide" only for one image + // If we want to have it for other images too, we need to implement the actual cropping. + bool const bEnable = m_xInsTypeCombo->get_active() == ONE_IMAGE; + m_xASRCheckCrop->set_sensitive(bEnable); + if (!bEnable) + m_xASRCheckCrop->set_active(false); +} + +Reference< drawing::XDrawPage > SdPhotoAlbumDialog::appendNewSlide(AutoLayout aLayout, + const Reference< drawing::XDrawPages >& xDrawPages +) +{ + // Create the slide + Reference< drawing::XDrawPage > xSlide = xDrawPages->insertNewByIndex( xDrawPages->getCount() ); + SdPage* pSlide = m_pDoc->GetSdPage( m_pDoc->GetSdPageCount(PageKind::Standard)-1, PageKind::Standard); + pSlide->SetAutoLayout(aLayout, true); // Set the layout here + return xSlide; +} + +awt::Size SdPhotoAlbumDialog::createASRSize(const awt::Size& aPicSize, const awt::Size& aMaxSize) +{ + double resizeWidth = aPicSize.Width; + double resizeHeight = aPicSize.Height; + double aspect = resizeWidth/resizeHeight; + + if( resizeWidth > aMaxSize.Width ) + { + resizeWidth = aMaxSize.Width; + resizeHeight = resizeWidth / aspect; + } + + if( resizeHeight > aMaxSize.Height ) + { + aspect = resizeWidth/resizeHeight; + resizeHeight = aMaxSize.Height; + resizeWidth = resizeHeight * aspect; + } + return awt::Size(resizeWidth, resizeHeight); +} + +awt::Size SdPhotoAlbumDialog::createASRSizeCrop(const awt::Size& aPicSize, const awt::Size& aMaxSize) +{ + double resizeWidth = aPicSize.Width; + double resizeHeight = aPicSize.Height; + double imgAspect = resizeWidth / resizeHeight; + double windowAspectRatio = static_cast<double>(aMaxSize.Width) / aMaxSize.Height ; + + + //When both sides of an image are bigger than canvas size, image would be downscaled. + if( resizeWidth > aMaxSize.Width && resizeHeight > aMaxSize.Height ) + { + if( imgAspect > windowAspectRatio ) + { + resizeHeight = aMaxSize.Height; + resizeWidth = aMaxSize.Height * imgAspect; + } + else + { + resizeHeight = aMaxSize.Width / imgAspect; + resizeWidth = aMaxSize.Width; + } + + } + //In all other cases image is upscaled + else + { + if( imgAspect > windowAspectRatio ) + { + resizeHeight = aMaxSize.Height; + resizeWidth = aMaxSize.Height * imgAspect; + } + else + { + resizeWidth = aMaxSize.Width; + resizeHeight = aMaxSize.Width / imgAspect; + } + } + return awt::Size(resizeWidth, resizeHeight); +} + +void SdPhotoAlbumDialog::createCaption(const awt::Size& aPageSize ) +{ + Point CapPos; + Size CapSize; + + CapSize.setWidth( aPageSize.Width ); + CapSize.setHeight( aPageSize.Height/6 ); + CapPos.setX( 0 ); + CapPos.setY( aPageSize.Height - CapSize.Height() ); + SdPage* pSlide = m_pDoc->GetSdPage( m_pDoc->GetSdPageCount(PageKind::Standard)-1, PageKind::Standard ); + + // try to get existing PresObj + const ::tools::Rectangle rRect(CapPos,CapSize); + SdrObject* pSdrObj = pSlide->GetPresObj(PresObjKind::Title); + + if(!pSdrObj) + { + // if not exists, create. Beware: It is already inserted to the SdPage + pSdrObj = pSlide->CreatePresObj(PresObjKind::Title,false,rRect); + } + else + { + // if exists, bring to front and position it + const size_t nObjNum(pSlide->GetObjCount()); + + if(nObjNum) + { + pSlide->SetObjectOrdNum(pSdrObj->GetOrdNum(), nObjNum - 1); + } + + pSdrObj->SetSnapRect(rRect); + } + + if(pSdrObj) + { + // set color, style and some transparency + SfxItemSet aSet(m_pDoc->GetItemPool() ); + + aSet.Put( XFillStyleItem(drawing::FillStyle_SOLID) ); + aSet.Put( XFillColorItem( "", COL_BLACK ) ); + aSet.Put( XFillTransparenceItem( 20 ) ); + pSdrObj->SetMergedItemSetAndBroadcast(aSet); + } +} + +Reference< graphic::XGraphic> SdPhotoAlbumDialog::createXGraphicFromUrl(const OUString& sUrl, + const Reference< graphic::XGraphicProvider>& xProvider +) +{ + // The same as above, except this returns an XGraphic from the image URL + ::comphelper::NamedValueCollection aMediaProperties; + aMediaProperties.put( "URL", sUrl ); + Reference< graphic::XGraphic> xGraphic = + xProvider->queryGraphic( aMediaProperties.getPropertyValues() ); + return xGraphic; +} + +void SdPhotoAlbumDialog::EnableDisableButtons() +{ + m_xRemoveBtn->set_sensitive(m_xImagesLst->count_selected_rows() > 0); + m_xUpBtn->set_sensitive(m_xImagesLst->count_selected_rows() > 0 && + m_xImagesLst->get_selected_index() != 0); + m_xDownBtn->set_sensitive(m_xImagesLst->count_selected_rows() > 0 && + m_xImagesLst->get_selected_index() < m_xImagesLst->n_children() - 1); +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/PhotoAlbumDialog.hxx b/sd/source/ui/dlg/PhotoAlbumDialog.hxx new file mode 100644 index 000000000..f84ff5cc3 --- /dev/null +++ b/sd/source/ui/dlg/PhotoAlbumDialog.hxx @@ -0,0 +1,91 @@ +/* -*- 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/. +*/ + +#pragma once + +#include <tools/link.hxx> + +#include <vcl/weld.hxx> +#include <svx/graphctl.hxx> +#include <xmloff/autolayout.hxx> + +#include <com/sun/star/awt/Size.hpp> + +namespace com::sun::star::drawing { class XDrawPage; } +namespace com::sun::star::drawing { class XDrawPages; } +namespace com::sun::star::graphic { class XGraphicProvider; } + +class SdDrawDocument; +class GraphicFilter; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace sd +{ + +class SdPhotoAlbumDialog : public weld::GenericDialogController +{ +public: + SdPhotoAlbumDialog(weld::Window* pWindow, SdDrawDocument* pActDoc); + virtual ~SdPhotoAlbumDialog() override; + +private: + SdDrawDocument* m_pDoc; + GraphicFilter* m_pGraphicFilter; + + GraphCtrl m_aImg; + + std::unique_ptr<weld::Button> m_xCancelBtn; + std::unique_ptr<weld::Button> m_xCreateBtn; + std::unique_ptr<weld::Button> m_xAddBtn; + std::unique_ptr<weld::Button> m_xUpBtn; + std::unique_ptr<weld::Button> m_xDownBtn; + std::unique_ptr<weld::Button> m_xRemoveBtn; + std::unique_ptr<weld::TreeView> m_xImagesLst; + std::unique_ptr<weld::CustomWeld> m_xImg; + std::unique_ptr<weld::ComboBox> m_xInsTypeCombo; + std::unique_ptr<weld::CheckButton> m_xASRCheck; + std::unique_ptr<weld::CheckButton> m_xASRCheckCrop; + std::unique_ptr<weld::CheckButton> m_xCapCheck; + std::unique_ptr<weld::CheckButton> m_xInsertAsLinkCheck; + + DECL_LINK(CancelHdl, weld::Button&, void); + DECL_LINK(CreateHdl, weld::Button&, void); + + DECL_LINK(FileHdl, weld::Button&, void); + DECL_LINK(UpHdl, weld::Button&, void); + DECL_LINK(DownHdl, weld::Button&, void); + DECL_LINK(RemoveHdl, weld::Button&, void); + + DECL_LINK(SelectHdl, weld::TreeView&, void); + DECL_LINK(TypeSelectHdl, weld::ComboBox&, void); + + Reference< drawing::XDrawPage > appendNewSlide(AutoLayout aLayout, + const Reference< drawing::XDrawPages >& xDrawPages); + + static awt::Size createASRSize(const awt::Size& aPicSize, const awt::Size& aMaxSize); + static awt::Size createASRSizeCrop(const awt::Size& aPicSize, const awt::Size& aMaxSize); + void createCaption(const awt::Size& aPageSize); + static Reference< graphic::XGraphic> createXGraphicFromUrl(const OUString& sUrl, + const Reference< graphic::XGraphicProvider>& xProvider); + + void EnableDisableButtons(); + + enum SlideImageLayout + { + ONE_IMAGE=0, + TWO_IMAGES, + FOUR_IMAGES + }; +}; + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/RemoteDialog.cxx b/sd/source/ui/dlg/RemoteDialog.cxx new file mode 100644 index 000000000..e28f57ecd --- /dev/null +++ b/sd/source/ui/dlg/RemoteDialog.cxx @@ -0,0 +1,49 @@ +/* -*- 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/. + */ + +#include "RemoteDialog.hxx" +#include <RemoteServer.hxx> + +using namespace ::sd; +using namespace ::std; + +RemoteDialog::RemoteDialog(weld::Window* pWindow) + : GenericDialogController(pWindow, "modules/simpress/ui/remotedialog.ui", "RemoteDialog") + , m_xButtonConnect(m_xBuilder->weld_button("ok")) + , m_xClientBox(new sd::ClientBox(m_xBuilder->weld_scrolled_window("scroll"), + m_xBuilder->weld_container("tree"))) +{ + m_xButtonConnect->connect_clicked(LINK(this, RemoteDialog, HandleConnectButton)); +} + +RemoteDialog::~RemoteDialog() {} + +IMPL_LINK_NOARG(RemoteDialog, HandleConnectButton, weld::Button&, void) +{ + weld::WaitObject(m_xDialog.get()); +#if defined(ENABLE_SDREMOTE) + auto xEntry = m_xClientBox->GetActiveEntry(); + if (!xEntry) + return; + OUString aPin = xEntry->m_xPinBox->get_text(); + if (RemoteServer::connectClient(xEntry->m_xClientInfo, aPin)) + m_xDialog->response(RET_OK); +#endif +} + +short RemoteDialog::run() +{ + short nRet = weld::GenericDialogController::run(); +#ifdef ENABLE_SDREMOTE + RemoteServer::restoreDiscoverable(); +#endif + return nRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/RemoteDialog.hxx b/sd/source/ui/dlg/RemoteDialog.hxx new file mode 100644 index 000000000..6c3f94ff8 --- /dev/null +++ b/sd/source/ui/dlg/RemoteDialog.hxx @@ -0,0 +1,32 @@ +/* -*- 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/. + */ +#pragma once + +#include <vcl/weld.hxx> + +#include "RemoteDialogClientBox.hxx" + +namespace sd +{ +class RemoteDialog : public weld::GenericDialogController +{ +private: + std::unique_ptr<weld::Button> m_xButtonConnect; + std::unique_ptr<ClientBox> m_xClientBox; + + DECL_LINK(HandleConnectButton, weld::Button&, void); + +public: + explicit RemoteDialog(weld::Window* pWindow); + virtual short run() override; + virtual ~RemoteDialog() override; +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/RemoteDialogClientBox.cxx b/sd/source/ui/dlg/RemoteDialogClientBox.cxx new file mode 100644 index 000000000..2371c4fb8 --- /dev/null +++ b/sd/source/ui/dlg/RemoteDialogClientBox.cxx @@ -0,0 +1,134 @@ +/* -*- 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 <vector> + +#include "RemoteDialogClientBox.hxx" +#include <RemoteServer.hxx> + +#include <vcl/svapp.hxx> + +namespace sd { + +// struct ClientBoxEntry + +ClientBoxEntry::ClientBoxEntry(ClientBox* pClientBox, + const std::shared_ptr<ClientInfo>& pClientInfo) + : m_xBuilder(Application::CreateBuilder(pClientBox->GetContainer(), "modules/simpress/ui/clientboxfragment.ui")) + , m_xContainer(m_xBuilder->weld_container("ClientboxFragment")) + , m_xDeviceName(m_xBuilder->weld_label("name")) + , m_xPinLabel(m_xBuilder->weld_label("pinlabel")) + , m_xPinBox(m_xBuilder->weld_entry("pin")) + , m_xDeauthoriseButton(m_xBuilder->weld_button("button")) + , m_xClientInfo(pClientInfo) + , m_pClientBox(pClientBox) +{ + m_xDeviceName->set_label(m_xClientInfo->mName); + m_xDeauthoriseButton->connect_clicked(LINK(this, ClientBoxEntry, DeauthoriseHdl)); + m_xDeauthoriseButton->set_visible(m_xClientInfo->mbIsAlreadyAuthorised); + m_xPinBox->set_visible(!m_xClientInfo->mbIsAlreadyAuthorised); + m_xPinLabel->set_visible(!m_xClientInfo->mbIsAlreadyAuthorised); + + m_xDeauthoriseButton->connect_focus_in(LINK(this, ClientBoxEntry, FocusHdl)); + m_xPinBox->connect_focus_in(LINK(this, ClientBoxEntry, FocusHdl)); +} + +ClientBoxEntry::~ClientBoxEntry() +{ + m_pClientBox->GetContainer()->move(m_xContainer.get(), nullptr); +} + +// ClientBox +ClientBox::ClientBox(std::unique_ptr<weld::ScrolledWindow> xScroll, + std::unique_ptr<weld::Container> xContents) + : m_xScroll(std::move(xScroll)) + , m_xContents(std::move(xContents)) + , m_pActive(nullptr) +{ + Size aSize(m_xScroll->get_approximate_digit_width() * 40, + m_xScroll->get_text_height() * 16); + m_xScroll->set_size_request(aSize.Width(), aSize.Height()); + + m_xContents->set_stack_background(); + + populateEntries(); +} + +ClientBox::~ClientBox() +{ +} + +ClientBoxEntry* ClientBox::GetActiveEntry() +{ + return m_pActive; +} + +void ClientBox::addEntry( const std::shared_ptr<ClientInfo>& pClientInfo ) +{ + TClientBoxEntry xEntry = std::make_shared<ClientBoxEntry>(this, pClientInfo); + m_vEntries.push_back(xEntry); +} + +void ClientBox::setActive(ClientBoxEntry* pClientEntry) +{ + m_pActive = pClientEntry; +} + +void ClientBox::clearEntries() +{ + m_vEntries.clear(); + m_pActive = nullptr; +} + +void ClientBox::populateEntries() +{ + clearEntries(); + +#ifdef ENABLE_SDREMOTE + RemoteServer::ensureDiscoverable(); + + std::vector< std::shared_ptr< ClientInfo > > aClients( RemoteServer::getClients() ); + + for ( const auto& rxClient : aClients ) + { + addEntry( rxClient ); + } +#endif + +} + +IMPL_LINK_NOARG(ClientBoxEntry, DeauthoriseHdl, weld::Button&, void) +{ +#ifdef ENABLE_SDREMOTE + RemoteServer::deauthoriseClient(m_xClientInfo); +#endif + m_pClientBox->populateEntries(); +} + +IMPL_LINK_NOARG(ClientBoxEntry, FocusHdl, weld::Widget&, void) +{ + if (ClientBoxEntry* pOldEntry = m_pClientBox->GetActiveEntry()) + pOldEntry->m_xContainer->set_stack_background(); + m_pClientBox->setActive(this); + m_xContainer->set_highlight_background(); +} + +} //namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/RemoteDialogClientBox.hxx b/sd/source/ui/dlg/RemoteDialogClientBox.hxx new file mode 100644 index 000000000..c7a916dc9 --- /dev/null +++ b/sd/source/ui/dlg/RemoteDialogClientBox.hxx @@ -0,0 +1,85 @@ +/* -*- 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 . + */ + +#pragma once + +#include <vcl/weld.hxx> + +#include <memory> + +namespace sd { + +#define SMALL_ICON_SIZE 16 +#define TOP_OFFSET 5 +#define ICON_HEIGHT 42 +#define ICON_WIDTH 47 +#define ICON_OFFSET 72 +#define RIGHT_ICON_OFFSET 5 +#define SPACE_BETWEEN 3 + +class ClientBox; +struct ClientBoxEntry; +struct ClientInfo; + +typedef std::shared_ptr<ClientBoxEntry> TClientBoxEntry; + +struct ClientBoxEntry +{ + std::unique_ptr<weld::Builder> m_xBuilder; + std::unique_ptr<weld::Container> m_xContainer; + std::unique_ptr<weld::Label> m_xDeviceName; + std::unique_ptr<weld::Label> m_xPinLabel; + std::unique_ptr<weld::Entry> m_xPinBox; + std::unique_ptr<weld::Button> m_xDeauthoriseButton; + + std::shared_ptr<ClientInfo> m_xClientInfo; + ClientBox* m_pClientBox; + + DECL_LINK(DeauthoriseHdl, weld::Button&, void); + DECL_LINK(FocusHdl, weld::Widget&, void); + + ClientBoxEntry(ClientBox* pClientBox, const std::shared_ptr<ClientInfo>& pClientInfo); + ~ClientBoxEntry(); +}; + +class ClientBox +{ + std::unique_ptr<weld::ScrolledWindow> m_xScroll; + std::unique_ptr<weld::Container> m_xContents; + + std::vector< TClientBoxEntry > m_vEntries; + ClientBoxEntry* m_pActive; + +public: + ClientBox(std::unique_ptr<weld::ScrolledWindow> xScroll, std::unique_ptr<weld::Container> xContents); + weld::Container* GetContainer() { return m_xContents.get(); } + ~ClientBox(); + + ClientBoxEntry* GetActiveEntry(); + + void addEntry(const std::shared_ptr<ClientInfo>& pClientInfo); + void setActive(ClientBoxEntry* pClientData); + void clearEntries(); + + void populateEntries(); +}; + +} // end namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/SpellDialogChildWindow.cxx b/sd/source/ui/dlg/SpellDialogChildWindow.cxx new file mode 100644 index 000000000..c87919346 --- /dev/null +++ b/sd/source/ui/dlg/SpellDialogChildWindow.cxx @@ -0,0 +1,172 @@ +/* -*- 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 <SpellDialogChildWindow.hxx> +#include <svx/svxids.hrc> + +#include <ViewShell.hxx> +#include <ViewShellBase.hxx> +#include <DrawViewShell.hxx> +#include <OutlineViewShell.hxx> +#include <Outliner.hxx> +#include <drawdoc.hxx> + +namespace sd { + +SFX_IMPL_CHILDWINDOW_WITHID(SpellDialogChildWindow, SID_SPELL_DIALOG) + +SpellDialogChildWindow::SpellDialogChildWindow ( + vcl::Window* _pParent, + sal_uInt16 nId, + SfxBindings* pBindings, + SAL_UNUSED_PARAMETER SfxChildWinInfo* /*pInfo*/) + : svx::SpellDialogChildWindow (_pParent, nId, pBindings), + mpSdOutliner (nullptr), + mbOwnOutliner (false) +{ + ProvideOutliner(); +} + +SpellDialogChildWindow::~SpellDialogChildWindow() +{ + EndSpellingAndClearOutliner(); +} + +SfxChildWinInfo SpellDialogChildWindow::GetInfo() const +{ + return svx::SpellDialogChildWindow::GetInfo(); +} + +void SpellDialogChildWindow::InvalidateSpellDialog() +{ + svx::SpellDialogChildWindow::InvalidateSpellDialog(); +} + +svx::SpellPortions SpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ ) +{ + svx::SpellPortions aResult; + + if (mpSdOutliner != nullptr) + { + ProvideOutliner(); + aResult = mpSdOutliner->GetNextSpellSentence(); + } + return aResult; +} + +void SpellDialogChildWindow::ApplyChangedSentence ( + const svx::SpellPortions& rChanged, bool bRecheck ) +{ + if (mpSdOutliner != nullptr) + { + OutlinerView* pOutlinerView = mpSdOutliner->GetView(0); + if (pOutlinerView != nullptr) + mpSdOutliner->ApplyChangedSentence ( + pOutlinerView->GetEditView(), + rChanged, bRecheck); + } +} + +void SpellDialogChildWindow::GetFocus() +{ + // In order to detect a cursor movement we could compare the + // currently selected text shape with the one that was selected + // when LoseFocus() was called the last time. + // For the time being we instead rely on the DetectChange() method + // in the SdOutliner class. +} + +void SpellDialogChildWindow::LoseFocus() +{ +} + +void SpellDialogChildWindow::EndSpellingAndClearOutliner() +{ + if (!mpSdOutliner) + return; + EndListening(*mpSdOutliner->GetDoc()); + mpSdOutliner->EndSpelling(); + if (mbOwnOutliner) + delete mpSdOutliner; + mpSdOutliner = nullptr; + mbOwnOutliner = false; +} + +void SpellDialogChildWindow::Notify(SfxBroadcaster&, const SfxHint& rHint) +{ + if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint) + return; + const SdrHint* pSdrHint = static_cast<const SdrHint*>(&rHint); + if (SdrHintKind::ModelCleared == pSdrHint->GetKind()) + { + EndSpellingAndClearOutliner(); + } +} + +void SpellDialogChildWindow::ProvideOutliner() +{ + ViewShellBase* pViewShellBase = dynamic_cast<ViewShellBase*>( SfxViewShell::Current() ); + + if (pViewShellBase == nullptr) + return; + + ViewShell* pViewShell = pViewShellBase->GetMainViewShell().get(); + // If there already exists an outliner that has been created + // for another view shell then destroy it first. + if (mpSdOutliner != nullptr) + if(( dynamic_cast< const DrawViewShell *>( pViewShell ) != nullptr && ! mbOwnOutliner) + || (dynamic_cast< const OutlineViewShell *>( pViewShell ) != nullptr && mbOwnOutliner)) + { + EndSpellingAndClearOutliner(); + } + + // Now create/get an outliner if none is present. + if (mpSdOutliner != nullptr) + return; + + if( dynamic_cast< const DrawViewShell *>( pViewShell ) != nullptr) + { + // We need an outliner for the spell check so we have + // to create one. + mbOwnOutliner = true; + SdDrawDocument *pDoc = pViewShell->GetDoc(); + mpSdOutliner = new SdOutliner(pDoc, OutlinerMode::TextObject); + StartListening(*pDoc); + } + else if( dynamic_cast< const OutlineViewShell *>( pViewShell ) != nullptr) + { + // An outline view is already visible. The SdOutliner + // will use it instead of creating its own. + mbOwnOutliner = false; + SdDrawDocument *pDoc = pViewShell->GetDoc(); + mpSdOutliner = pDoc->GetOutliner(); + StartListening(*pDoc); + } + + // Initialize spelling. + if (mpSdOutliner != nullptr) + { + mpSdOutliner->PrepareSpelling(); + mpSdOutliner->StartSpelling(); + } +} + +} // end of namespace ::sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/TemplateScanner.cxx b/sd/source/ui/dlg/TemplateScanner.cxx new file mode 100644 index 000000000..afd23ff85 --- /dev/null +++ b/sd/source/ui/dlg/TemplateScanner.cxx @@ -0,0 +1,342 @@ +/* -*- 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 <TemplateScanner.hxx> + +#include <comphelper/processfactory.hxx> +#include <comphelper/documentconstants.hxx> + +#include <sfx2/doctempl.hxx> +#include <com/sun/star/frame/DocumentTemplates.hpp> +#include <com/sun/star/frame/XDocumentTemplates.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> + +#include <set> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +namespace { + +constexpr OUStringLiteral TITLE = u"Title"; + +class FolderDescriptor +{ +public: + FolderDescriptor ( + int nPriority, + const OUString& rsContentIdentifier, + const Reference<css::ucb::XCommandEnvironment>& rxFolderEnvironment) + : mnPriority(nPriority), + msContentIdentifier(rsContentIdentifier), + mxFolderEnvironment(rxFolderEnvironment) + { } + int mnPriority; + OUString msContentIdentifier; + // Reference<sdbc::XResultSet> mxFolderResultSet; + Reference<css::ucb::XCommandEnvironment> mxFolderEnvironment; + + class Comparator + { + public: + bool operator() (const FolderDescriptor& r1, const FolderDescriptor& r2) const + { return r1.mnPriority < r2.mnPriority; } + }; +}; + +/** Use a heuristic based on the URL of a top-level template folder to + assign a priority that is used to sort the folders. +*/ +int Classify (std::u16string_view rsURL) +{ + int nPriority (0); + + if (rsURL.empty()) + nPriority = 100; + else if (rsURL.find(u"presnt") != std::u16string_view::npos) + { + nPriority = 30; + } + else if (rsURL.find(u"layout") != std::u16string_view::npos) + { + nPriority = 20; + } + else if (rsURL.find(u"educate") != std::u16string_view::npos) + { + nPriority = 40; + } + else if (rsURL.find(u"finance") != std::u16string_view::npos) + { + nPriority = 40; + } + else + { + // All other folders are taken for user supplied and have the + // highest priority. + nPriority = 10; + } + + return nPriority; +} + +} // end of anonymous namespace + +namespace sd +{ + +class TemplateScanner::FolderDescriptorList + : public ::std::multiset<FolderDescriptor,FolderDescriptor::Comparator> +{ +}; + +TemplateScanner::TemplateScanner() + : meState(INITIALIZE_SCANNING), + mpFolderDescriptors(new FolderDescriptorList) +{ + // empty; +} + +TemplateScanner::~TemplateScanner() +{ +} + +TemplateScanner::State TemplateScanner::GetTemplateRoot() +{ + Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext(); + Reference<frame::XDocumentTemplates> xTemplates = frame::DocumentTemplates::create(xContext); + mxTemplateRoot = xTemplates->getContent(); + + return INITIALIZE_FOLDER_SCANNING; +} + +TemplateScanner::State TemplateScanner::InitializeEntryScanning() +{ + State eNextState (SCAN_ENTRY); + + if (maFolderContent.isFolder()) + { + mxEntryEnvironment.clear(); + + // Create a cursor to iterate over the templates in this folders. + // We are interested only in three properties: the entry's name, + // its URL, and its content type. + mxEntryResultSet.set( maFolderContent.createCursor({ TITLE, "TargetURL", "TypeDescription" }, ::ucbhelper::INCLUDE_DOCUMENTS_ONLY)); + } + else + eNextState = ERROR; + + return eNextState; +} + +TemplateScanner::State TemplateScanner::ScanEntry() +{ + State eNextState (ERROR); + + Reference<css::ucb::XContentAccess> xContentAccess (mxEntryResultSet, UNO_QUERY); + Reference<css::sdbc::XRow> xRow (mxEntryResultSet, UNO_QUERY); + + if (xContentAccess.is() && xRow.is() && mxEntryResultSet.is()) + { + if (mxEntryResultSet->next()) + { + OUString sTitle (xRow->getString (1)); + OUString sTargetURL (xRow->getString (2)); + OUString sContentType (xRow->getString (3)); + + OUString aId = xContentAccess->queryContentIdentifierString(); + ::ucbhelper::Content aContent(aId, mxEntryEnvironment, comphelper::getProcessComponentContext()); + if (aContent.isDocument ()) + { + // Check whether the entry is an impress template. If so + // add a new entry to the resulting list (which is created + // first if necessary). + // These strings are used to find impress templates in the tree of + // template files. Should probably be determined dynamically. + if ( (sContentType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) + || (sContentType == MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) + || (sContentType == "application/vnd.stardivision.impress") + || (sContentType == MIMETYPE_VND_SUN_XML_IMPRESS_ASCII) + // The following id comes from the bugdoc in #i2764#. + || (sContentType == "Impress 2.0")) + { + OUString sLocalisedTitle = SfxDocumentTemplates::ConvertResourceString(sTitle); + mpTemplateEntries.push_back(std::make_unique<TemplateEntry>(sLocalisedTitle, sTargetURL)); + } + } + + // Continue scanning entries. + eNextState = SCAN_ENTRY; + } + else + { + // Continue with scanning the next folder. + eNextState = SCAN_FOLDER; + } + } + + return eNextState; +} + +TemplateScanner::State TemplateScanner::InitializeFolderScanning() +{ + State eNextState (ERROR); + + mxFolderResultSet.clear(); + + try + { + // Create content for template folders. + mxFolderEnvironment.clear(); + ::ucbhelper::Content aTemplateDir (mxTemplateRoot, mxFolderEnvironment, comphelper::getProcessComponentContext()); + + // Create a cursor to iterate over the template folders. + mxFolderResultSet.set( aTemplateDir.createCursor({ TITLE, "TargetDirURL" }, ::ucbhelper::INCLUDE_FOLDERS_ONLY)); + if (mxFolderResultSet.is()) + eNextState = GATHER_FOLDER_LIST; + } + catch (css::uno::Exception&) + { + eNextState = ERROR; + } + + return eNextState; +} + +TemplateScanner::State TemplateScanner::GatherFolderList() +{ + State eNextState (ERROR); + + Reference<css::ucb::XContentAccess> xContentAccess (mxFolderResultSet, UNO_QUERY); + if (xContentAccess.is() && mxFolderResultSet.is()) + { + while (mxFolderResultSet->next()) + { + Reference<sdbc::XRow> xRow (mxFolderResultSet, UNO_QUERY); + if (xRow.is()) + { + OUString sTargetDir (xRow->getString (2)); + OUString aId = xContentAccess->queryContentIdentifierString(); + + mpFolderDescriptors->insert( + FolderDescriptor( + Classify(sTargetDir), + aId, + mxFolderEnvironment)); + } + } + + eNextState = SCAN_FOLDER; + } + + return eNextState; +} + +TemplateScanner::State TemplateScanner::ScanFolder() +{ + State eNextState (ERROR); + + if (!mpFolderDescriptors->empty()) + { + FolderDescriptor aDescriptor (*mpFolderDescriptors->begin()); + mpFolderDescriptors->erase(mpFolderDescriptors->begin()); + + OUString aId (aDescriptor.msContentIdentifier); + + maFolderContent = ::ucbhelper::Content (aId, aDescriptor.mxFolderEnvironment, comphelper::getProcessComponentContext()); + if (maFolderContent.isFolder()) + { + // Scan the folder and insert it into the list of template + // folders. + // Continue with scanning all entries in the folder. + mpTemplateEntries.clear(); + eNextState = INITIALIZE_ENTRY_SCAN; + } + } + else + { + eNextState = DONE; + } + + return eNextState; +} + +void TemplateScanner::RunNextStep() +{ + switch (meState) + { + case INITIALIZE_SCANNING: + meState = GetTemplateRoot(); + break; + + case INITIALIZE_FOLDER_SCANNING: + meState = InitializeFolderScanning(); + break; + + case SCAN_FOLDER: + meState = ScanFolder(); + break; + + case GATHER_FOLDER_LIST: + meState = GatherFolderList(); + break; + + case INITIALIZE_ENTRY_SCAN: + meState = InitializeEntryScanning(); + break; + + case SCAN_ENTRY: + meState = ScanEntry(); + break; + default: + break; + } + + switch (meState) + { + case DONE: + case ERROR: + mxTemplateRoot.clear(); + mxFolderEnvironment.clear(); + mxEntryEnvironment.clear(); + mxFolderResultSet.clear(); + mxEntryResultSet.clear(); + break; + default: + break; + } +} + +bool TemplateScanner::HasNextStep() +{ + switch (meState) + { + case DONE: + case ERROR: + return false; + + default: + return true; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/animobjs.cxx b/sd/source/ui/dlg/animobjs.cxx new file mode 100644 index 000000000..b70848e23 --- /dev/null +++ b/sd/source/ui/dlg/animobjs.cxx @@ -0,0 +1,1134 @@ +/* -*- 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 <time.h> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> +#include <svx/svdograf.hxx> +#include <svx/svdogrp.hxx> +#include <svx/svdpagv.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/progress.hxx> +#include <vcl/help.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <vcl/virdev.hxx> + +#include <anminfo.hxx> +#include <animobjs.hxx> +#include <app.hrc> +#include <strings.hrc> +#include <sdresid.hxx> +#include <View.hxx> +#include <drawdoc.hxx> +#include <sdpage.hxx> + +#include <ViewShell.hxx> + +#include <vcl/settings.hxx> + +#include <EffectMigration.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; + +namespace sd { + +/** + * SdDisplay - Control + */ +SdDisplay::SdDisplay() + : aScale(1, 1) +{ +} + +SdDisplay::~SdDisplay() +{ +} + +void SdDisplay::SetBitmapEx( BitmapEx const * pBmpEx ) +{ + if( pBmpEx ) + { + aBitmapEx = *pBmpEx; + } + else + { + const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings(); + const Color aFillColor = rStyles.GetFieldColor(); + aBitmapEx.Erase(aFillColor); + } +} + +void SdDisplay::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&) +{ + rRenderContext.Push(vcl::PushFlags::MAPMODE); + + rRenderContext.SetMapMode(MapMode(MapUnit::MapPixel)); + const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings(); + rRenderContext.SetBackground( Wallpaper( rStyles.GetFieldColor() ) ); + rRenderContext.Erase(); + + Point aPt; + Size aSize = GetOutputSizePixel(); + + Size aBmpSize = aBitmapEx.GetBitmap().GetSizePixel(); + aBmpSize.setWidth( static_cast<::tools::Long>( static_cast<double>(aBmpSize.Width()) * static_cast<double>(aScale) ) ); + aBmpSize.setHeight( static_cast<::tools::Long>( static_cast<double>(aBmpSize.Height()) * static_cast<double>(aScale) ) ); + + if( aBmpSize.Width() < aSize.Width() ) + aPt.setX( ( aSize.Width() - aBmpSize.Width() ) / 2 ); + if( aBmpSize.Height() < aSize.Height() ) + aPt.setY( ( aSize.Height() - aBmpSize.Height() ) / 2 ); + + aBitmapEx.Draw(&rRenderContext, aPt, aBmpSize); + + rRenderContext.Pop(); +} + +void SdDisplay::SetScale( const Fraction& rFrac ) +{ + aScale = rFrac; +} + +void SdDisplay::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + CustomWidgetController::SetDrawingArea(pDrawingArea); + Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(147, 87), MapMode(MapUnit::MapAppFont))); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); + SetOutputSizePixel(aSize); +} + +const size_t AnimationWindow::EMPTY_FRAMELIST = std::numeric_limits<size_t>::max(); + +/** + * AnimationWindow - FloatingWindow + */ +AnimationWindow::AnimationWindow(SfxBindings* pInBindings, SfxChildWindow *pCW, vcl::Window* pParent) + : SfxDockingWindow(pInBindings, pCW, pParent, + "DockingAnimation", "modules/simpress/ui/dockinganimation.ui") + , m_xCtlDisplay(new SdDisplay) + , m_xCtlDisplayWin(new weld::CustomWeld(*m_xBuilder, "preview", *m_xCtlDisplay)) + , m_xBtnFirst(m_xBuilder->weld_button("first")) + , m_xBtnReverse(m_xBuilder->weld_button("prev")) + , m_xBtnStop(m_xBuilder->weld_button("stop")) + , m_xBtnPlay(m_xBuilder->weld_button("next")) + , m_xBtnLast(m_xBuilder->weld_button("last")) + , m_xNumFldBitmap(m_xBuilder->weld_spin_button("numbitmap")) + , m_xTimeField(m_xBuilder->weld_formatted_spin_button("duration")) + , m_xFormatter(new weld::TimeFormatter(*m_xTimeField)) + , m_xLbLoopCount(m_xBuilder->weld_combo_box("loopcount")) + , m_xBtnGetOneObject(m_xBuilder->weld_button("getone")) + , m_xBtnGetAllObjects(m_xBuilder->weld_button("getall")) + , m_xBtnRemoveBitmap(m_xBuilder->weld_button("delone")) + , m_xBtnRemoveAll(m_xBuilder->weld_button("delall")) + , m_xFiCount(m_xBuilder->weld_label("count")) + , m_xRbtGroup(m_xBuilder->weld_radio_button("group")) + , m_xRbtBitmap(m_xBuilder->weld_radio_button("bitmap")) + , m_xFtAdjustment(m_xBuilder->weld_label("alignmentft")) + , m_xLbAdjustment(m_xBuilder->weld_combo_box("alignment")) + , m_xBtnCreateGroup(m_xBuilder->weld_button("create")) + , m_xBtnHelp(m_xBuilder->weld_button("help")) + , m_nCurrentFrame(EMPTY_FRAMELIST) + , bMovie(false) + , bAllObjects(false) +{ + SetText(SdResId(STR_ANIMATION_DIALOG_TITLE)); + + m_xFormatter->SetDuration(true); + m_xFormatter->SetTimeFormat(TimeFieldFormat::F_SEC_CS); + m_xFormatter->EnableEmptyField(false); + + // create new document with page + pMyDoc.reset( new SdDrawDocument(DocumentType::Impress, nullptr) ); + rtl::Reference<SdPage> pPage = pMyDoc->AllocSdPage(false); + pMyDoc->InsertPage(pPage.get()); + + pControllerItem.reset( new AnimationControllerItem( SID_ANIMATOR_STATE, this, pInBindings ) ); + + m_xBtnFirst->connect_clicked( LINK( this, AnimationWindow, ClickFirstHdl ) ); + m_xBtnReverse->connect_clicked( LINK( this, AnimationWindow, ClickPlayHdl ) ); + m_xBtnStop->connect_clicked( LINK( this, AnimationWindow, ClickStopHdl ) ); + m_xBtnPlay->connect_clicked( LINK( this, AnimationWindow, ClickPlayHdl ) ); + m_xBtnLast->connect_clicked( LINK( this, AnimationWindow, ClickLastHdl ) ); + + m_xBtnGetOneObject->connect_clicked( LINK( this, AnimationWindow, ClickGetObjectHdl ) ); + m_xBtnGetAllObjects->connect_clicked( LINK( this, AnimationWindow, ClickGetObjectHdl ) ); + m_xBtnRemoveBitmap->connect_clicked( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) ); + m_xBtnRemoveAll->connect_clicked( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) ); + + m_xRbtGroup->connect_toggled( LINK( this, AnimationWindow, ClickRbtHdl ) ); + m_xRbtBitmap->connect_toggled( LINK( this, AnimationWindow, ClickRbtHdl ) ); + m_xBtnCreateGroup->connect_clicked( LINK( this, AnimationWindow, ClickCreateGroupHdl ) ); + m_xBtnHelp->connect_clicked( LINK( this, AnimationWindow, ClickHelpHdl ) ); + m_xNumFldBitmap->connect_value_changed( LINK( this, AnimationWindow, ModifyBitmapHdl ) ); + m_xTimeField->connect_value_changed( LINK( this, AnimationWindow, ModifyTimeHdl ) ); + + SetMinOutputSizePixel(GetOptimalSize()); + + ResetAttrs(); + + // the animator is empty; no animation group can be created + m_xBtnCreateGroup->set_sensitive(false); +} + +AnimationWindow::~AnimationWindow() +{ + disposeOnce(); +} + +void AnimationWindow::dispose() +{ + pControllerItem.reset(); + + m_FrameList.clear(); + m_nCurrentFrame = EMPTY_FRAMELIST; + + // delete the clones + pMyDoc.reset(); + + m_xCtlDisplayWin.reset(); + m_xCtlDisplay.reset(); + m_xBtnFirst.reset(); + m_xBtnReverse.reset(); + m_xBtnStop.reset(); + m_xBtnPlay.reset(); + m_xBtnLast.reset(); + m_xNumFldBitmap.reset(); + m_xFormatter.reset(); + m_xTimeField.reset(); + m_xLbLoopCount.reset(); + m_xBtnGetOneObject.reset(); + m_xBtnGetAllObjects.reset(); + m_xBtnRemoveBitmap.reset(); + m_xBtnRemoveAll.reset(); + m_xFiCount.reset(); + m_xRbtGroup.reset(); + m_xRbtBitmap.reset(); + m_xFtAdjustment.reset(); + m_xLbAdjustment.reset(); + m_xBtnCreateGroup.reset(); + m_xBtnHelp.reset(); + SfxDockingWindow::dispose(); +} + +IMPL_LINK_NOARG(AnimationWindow, ClickFirstHdl, weld::Button&, void) +{ + m_nCurrentFrame = (m_FrameList.empty()) ? EMPTY_FRAMELIST : 0; + UpdateControl(); +} + +IMPL_LINK_NOARG(AnimationWindow, ClickStopHdl, weld::Button&, void) +{ + bMovie = false; +} + +IMPL_LINK( AnimationWindow, ClickPlayHdl, weld::Button&, rButton, void ) +{ + ScopeLockGuard aGuard( maPlayLock ); + + bMovie = true; + bool bDisableCtrls = false; + size_t const nCount = m_FrameList.size(); + bool bReverse = &rButton == m_xBtnReverse.get(); + + // it is difficult to find it later on + bool bRbtGroupEnabled = m_xRbtGroup->get_sensitive(); + bool bBtnGetAllObjectsEnabled = m_xBtnGetAllObjects->get_sensitive(); + bool bBtnGetOneObjectEnabled = m_xBtnGetOneObject->get_sensitive(); + + // calculate overall time + ::tools::Time aTime( 0 ); + ::tools::Long nFullTime; + if( m_xRbtBitmap->get_active() ) + { + for (size_t i = 0; i < nCount; ++i) + { + aTime += m_FrameList[i].second; + } + nFullTime = aTime.GetMSFromTime(); + } + else + { + nFullTime = nCount * 100; + aTime.MakeTimeFromMS( nFullTime ); + } + + // StatusBarManager from 1 second + std::unique_ptr<SfxProgress> pProgress; + if( nFullTime >= 1000 ) + { + bDisableCtrls = true; + m_xBtnStop->set_sensitive(true); + pProgress.reset(new SfxProgress( nullptr, "Animator:", nFullTime )); // "Animator:" here we should think about something smart + } + + sal_uLong nTmpTime = 0; + size_t i = 0; + bool bCount = i < nCount; + if( bReverse ) + { + i = nCount - 1; + } + while( bCount && bMovie ) + { + // make list and view consistent + assert(i < m_FrameList.size()); + m_nCurrentFrame = i; + + UpdateControl(bDisableCtrls); + + if( m_xRbtBitmap->get_active() ) + { + ::tools::Time const & rTime = m_FrameList[i].second; + + m_xFormatter->SetTime( rTime ); + sal_uLong nTime = rTime.GetMSFromTime(); + + WaitInEffect( nTime, nTmpTime, pProgress.get() ); + nTmpTime += nTime; + } + else + { + WaitInEffect( 100, nTmpTime, pProgress.get() ); + nTmpTime += 100; + } + if( bReverse ) + { + if (i == 0) + { + // Terminate loop. + bCount = false; + } + else + { + --i; + } + } + else + { + i++; + if (i >= nCount) + { + // Terminate loop. + bCount = false; + // Move i back into valid range. + i = nCount - 1; + } + } + } + + // to re-enable the controls + bMovie = false; + if (nCount > 0) + { + assert(i == m_nCurrentFrame); + UpdateControl(); + } + + if( pProgress ) + { + pProgress.reset(); + m_xBtnStop->set_sensitive(false); + } + + m_xRbtGroup->set_sensitive( bRbtGroupEnabled ); + m_xBtnGetAllObjects->set_sensitive( bBtnGetAllObjectsEnabled ); + m_xBtnGetOneObject->set_sensitive( bBtnGetOneObjectEnabled ); +} + +IMPL_LINK_NOARG(AnimationWindow, ClickLastHdl, weld::Button&, void) +{ + m_nCurrentFrame = + (m_FrameList.empty()) ? EMPTY_FRAMELIST : m_FrameList.size() - 1 ; + UpdateControl(); +} + +IMPL_LINK_NOARG(AnimationWindow, ClickRbtHdl, weld::Toggleable&, void) +{ + if (m_FrameList.empty() || m_xRbtGroup->get_active()) + { + m_xTimeField->set_text( OUString() ); + m_xTimeField->set_sensitive( false ); + m_xLbLoopCount->set_sensitive( false ); + } + else if (m_xRbtBitmap->get_active()) + { + sal_uLong n = m_xNumFldBitmap->get_value(); + if( n > 0 ) + { + ::tools::Time const & rTime = m_FrameList[n - 1].second; + m_xFormatter->SetTime( rTime ); + m_xFormatter->ReFormat(); + } + m_xTimeField->set_sensitive(true); + m_xLbLoopCount->set_sensitive(true); + } +} + +IMPL_LINK(AnimationWindow, ClickHelpHdl, weld::Button&, rButton, void) +{ + if (Help* pHelp = Application::GetHelp()) + pHelp->Start(OUString::fromUtf8(m_xContainer->get_help_id()), &rButton); +} + +IMPL_LINK( AnimationWindow, ClickGetObjectHdl, weld::Button&, rBtn, void ) +{ + bAllObjects = &rBtn == m_xBtnGetAllObjects.get(); + + // Code now in AddObj() + SfxBoolItem aItem( SID_ANIMATOR_ADD, true ); + + GetBindings().GetDispatcher()->ExecuteList( + SID_ANIMATOR_ADD, SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK( AnimationWindow, ClickRemoveBitmapHdl, weld::Button&, rBtn, void ) +{ + SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard); + SdrObject* pObject; + + // tdf#95298 check m_nCurrentFrame for EMPTY_FRAMELIST to avoid out-of-bound array access + if (&rBtn == m_xBtnRemoveBitmap.get() && EMPTY_FRAMELIST != m_nCurrentFrame) + { + m_FrameList.erase(m_FrameList.begin() + m_nCurrentFrame); + + pObject = pPage->GetObj(m_nCurrentFrame); + // Through acquisition of the AnimatedGIFs, objects does not need to + // exist. + if( pObject ) + { + pObject = pPage->RemoveObject(m_nCurrentFrame); + DBG_ASSERT(pObject, "Clone not found during deletion"); + SdrObject::Free( pObject ); + pPage->RecalcObjOrdNums(); + } + + if (m_nCurrentFrame >= m_FrameList.size()) + { + // tdf#95298 last frame was deleted, try to use the one before it or go on empty state + m_nCurrentFrame = m_FrameList.empty() ? EMPTY_FRAMELIST : m_FrameList.size() - 1; + } + } + else // delete everything + { + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(), + VclMessageType::Warning, VclButtonsType::YesNo, + SdResId(STR_ASK_DELETE_ALL_PICTURES))); + short nReturn = xWarn->run(); + + if( nReturn == RET_YES ) + { + // clear frame list + for (size_t i = m_FrameList.size(); i > 0; ) + { + --i; + pObject = pPage->GetObj( i ); + if( pObject ) + { + pObject = pPage->RemoveObject( i ); + DBG_ASSERT(pObject, "Clone not found during deletion"); + SdrObject::Free( pObject ); + //pPage->RecalcObjOrdNums(); + } + } + m_FrameList.clear(); + m_nCurrentFrame = EMPTY_FRAMELIST; + } + } + + // can we create an animation group + if (m_FrameList.empty()) + { + m_xBtnCreateGroup->set_sensitive(false); + // if previous disabled by acquisition of AnimatedGIFs: + //m_xRbtBitmap->set_sensitive(true); + m_xRbtGroup->set_sensitive(true); + } + + // calculate and set zoom for DisplayWin + Fraction aFrac(GetScale()); + m_xCtlDisplay->SetScale(aFrac); + + UpdateControl(); +} + +IMPL_LINK_NOARG(AnimationWindow, ClickCreateGroupHdl, weld::Button&, void) +{ + // Code now in CreatePresObj() + SfxBoolItem aItem( SID_ANIMATOR_CREATE, true ); + + GetBindings().GetDispatcher()->ExecuteList(SID_ANIMATOR_CREATE, + SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); +} + +IMPL_LINK_NOARG(AnimationWindow, ModifyBitmapHdl, weld::SpinButton&, void) +{ + sal_uLong nBmp = m_xNumFldBitmap->get_value(); + + if (nBmp > m_FrameList.size()) + { + nBmp = m_FrameList.size(); + } + + m_nCurrentFrame = nBmp - 1; + + UpdateControl(); +} + +IMPL_LINK_NOARG(AnimationWindow, ModifyTimeHdl, weld::FormattedSpinButton&, void) +{ + sal_uLong nPos = m_xNumFldBitmap->get_value() - 1; + + ::tools::Time & rTime = m_FrameList[nPos].second; + + rTime = m_xFormatter->GetTime(); +} + +void AnimationWindow::UpdateControl(bool const bDisableCtrls) +{ + // tdf#95298 check m_nCurrentFrame for EMPTY_FRAMELIST to avoid out-of-bound array access + if (!m_FrameList.empty() && EMPTY_FRAMELIST != m_nCurrentFrame) + { + BitmapEx & rBmp(m_FrameList[m_nCurrentFrame].first); + + SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard); + SdrObject *const pObject = pPage->GetObj(m_nCurrentFrame); + if( pObject ) + { + ScopedVclPtrInstance< VirtualDevice > pVD; + ::tools::Rectangle aObjRect( pObject->GetCurrentBoundRect() ); + Size aObjSize( aObjRect.GetSize() ); + Point aOrigin( Point( -aObjRect.Left(), -aObjRect.Top() ) ); + MapMode aMap( pVD->GetMapMode() ); + aMap.SetMapUnit( MapUnit::Map100thMM ); + aMap.SetOrigin( aOrigin ); + pVD->SetMapMode( aMap ); + pVD->SetOutputSize( aObjSize ); + const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings(); + pVD->SetBackground( Wallpaper( rStyles.GetFieldColor() ) ); + pVD->SetDrawMode( rStyles.GetHighContrastMode() + ? sd::OUTPUT_DRAWMODE_CONTRAST + : sd::OUTPUT_DRAWMODE_COLOR ); + pVD->Erase(); + pObject->SingleObjectPainter( *pVD ); + rBmp = pVD->GetBitmapEx( aObjRect.TopLeft(), aObjSize ); + } + + m_xCtlDisplay->SetBitmapEx(&rBmp); + } + else + { + m_xCtlDisplay->SetBitmapEx(nullptr); + } + + m_xCtlDisplay->Invalidate(); + + m_xFiCount->set_label(OUString::number( + m_FrameList.size())); + + if (!m_FrameList.empty() && !bMovie) + { + size_t nIndex = m_nCurrentFrame + 1; + m_xNumFldBitmap->set_value(nIndex); + + // if there is at least 1 object in the list + m_xBtnFirst->set_sensitive(true); + m_xBtnReverse->set_sensitive(true); + m_xBtnPlay->set_sensitive(true); + m_xBtnLast->set_sensitive(true); + m_xNumFldBitmap->set_sensitive(true); + m_xTimeField->set_sensitive(true); + m_xLbLoopCount->set_sensitive(true); + m_xBtnRemoveBitmap->set_sensitive(true); + m_xBtnRemoveAll->set_sensitive(true); + } + else + { + // if no object is in the list + m_xBtnFirst->set_sensitive( false ); + m_xBtnReverse->set_sensitive( false ); + m_xBtnPlay->set_sensitive( false ); + m_xBtnLast->set_sensitive( false ); + m_xNumFldBitmap->set_sensitive( false ); + m_xTimeField->set_sensitive( false ); + m_xLbLoopCount->set_sensitive( false ); + m_xBtnRemoveBitmap->set_sensitive( false ); + m_xBtnRemoveAll->set_sensitive( false ); + } + + if( bMovie && bDisableCtrls ) + { + m_xBtnGetOneObject->set_sensitive( false ); + m_xBtnGetAllObjects->set_sensitive( false ); + m_xRbtGroup->set_sensitive( false ); + m_xRbtBitmap->set_sensitive( false ); + m_xBtnCreateGroup->set_sensitive( false ); + m_xFtAdjustment->set_sensitive( false ); + m_xLbAdjustment->set_sensitive( false ); + } + else + { + // enable 'group object' only if it is not an Animated GIF + if (m_FrameList.empty()) + { + m_xRbtGroup->set_sensitive(true); + } + + m_xRbtBitmap->set_sensitive(true); + m_xBtnCreateGroup->set_sensitive(!m_FrameList.empty()); + m_xFtAdjustment->set_sensitive(true); + m_xLbAdjustment->set_sensitive(true); + } + + ClickRbtHdl(*m_xRbtGroup); +} + +void AnimationWindow::ResetAttrs() +{ + m_xRbtGroup->set_active(true); + m_xLbAdjustment->set_active( BA_CENTER ); + // LoopCount + m_xLbLoopCount->set_active( m_xLbLoopCount->get_count() - 1); + + UpdateControl(); +} + +void AnimationWindow::WaitInEffect( sal_uLong nMilliSeconds, sal_uLong nTime, + SfxProgress* pProgress ) const +{ + sal_uInt64 aEnd = ::tools::Time::GetSystemTicks() + nMilliSeconds; + sal_uInt64 aCurrent = ::tools::Time::GetSystemTicks(); + while (aCurrent < aEnd) + { + aCurrent = ::tools::Time::GetSystemTicks(); + + if( pProgress ) + pProgress->SetState( nTime + nMilliSeconds + aCurrent - aEnd ); + + Application::Reschedule(); + + if( !bMovie ) + return; + } +} + +Fraction AnimationWindow::GetScale() +{ + Fraction aFrac; + size_t const nCount = m_FrameList.size(); + if (nCount > 0) + { + Size aBmpSize(0, 0); + for (size_t i = 0; i < nCount; i++) + { + BitmapEx const & rBitmap = m_FrameList[i].first; + Size aTempSize( rBitmap.GetBitmap().GetSizePixel() ); + aBmpSize.setWidth( std::max( aBmpSize.Width(), aTempSize.Width() ) ); + aBmpSize.setHeight( std::max( aBmpSize.Height(), aTempSize.Height() ) ); + } + + aBmpSize.AdjustWidth(10 ); + aBmpSize.AdjustHeight(10 ); + + Size aDisplaySize(m_xCtlDisplay->GetOutputSizePixel()); + + aFrac = Fraction( std::min( static_cast<double>(aDisplaySize.Width()) / static_cast<double>(aBmpSize.Width()), + static_cast<double>(aDisplaySize.Height()) / static_cast<double>(aBmpSize.Height()) ) ); + } + return aFrac; +} + +void AnimationWindow::Resize() +{ + SfxDockingWindow::Resize(); + Fraction aFrac(GetScale()); + m_xCtlDisplay->SetScale(aFrac); +} + +bool AnimationWindow::Close() +{ + if( maPlayLock.isLocked() ) + { + return false; + } + else + { + SfxBoolItem aItem( SID_ANIMATION_OBJECTS, false ); + + GetBindings().GetDispatcher()->ExecuteList( + SID_ANIMATION_OBJECTS, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, + { &aItem }); + + SfxDockingWindow::Close(); + + return true; + } +} + +void AnimationWindow::AddObj (::sd::View& rView ) +{ + // finish text entry mode to ensure that bitmap is identical with object + if( rView.IsTextEdit() ) + rView.SdrEndTextEdit(); + + // clone object(s) and insert the clone(s) into the list + const SdrMarkList& rMarkList = rView.GetMarkedObjectList(); + const size_t nMarkCount = rMarkList.GetMarkCount(); + SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard); + const size_t nCloneCount = pPage->GetObjCount(); + + if (nMarkCount <= 0) + return; + + // If it is ONE animation object or one group object, which was + // 'individually taken', we insert the objects separately + bool bAnimObj = false; + if( nMarkCount == 1 ) + { + SdrMark* pMark = rMarkList.GetMark(0); + SdrObject* pObject = pMark->GetMarkedSdrObj(); + SdAnimationInfo* pAnimInfo = SdDrawDocument::GetAnimationInfo( pObject ); + SdrInventor nInv = pObject->GetObjInventor(); + SdrObjKind nId = pObject->GetObjIdentifier(); + + // Animated Bitmap (GIF) + if( nInv == SdrInventor::Default && nId == SdrObjKind::Graphic && static_cast<SdrGrafObj*>( pObject )->IsAnimated() ) + { + const SdrGrafObj* pGrafObj = static_cast<SdrGrafObj*>(pObject); + Graphic aGraphic( pGrafObj->GetTransformedGraphic() ); + sal_uInt16 nCount = 0; + + if( aGraphic.IsAnimated() ) + nCount = aGraphic.GetAnimation().Count(); + + if( nCount > 0 ) + { + const Animation aAnimation( aGraphic.GetAnimation() ); + + for( sal_uInt16 i = 0; i < nCount; i++ ) + { + const AnimationBitmap& rAnimationBitmap = aAnimation.Get( i ); + + // LoopCount + if( i == 0 ) + { + sal_uInt32 nLoopCount = aAnimation.GetLoopCount(); + + if( !nLoopCount ) // endless + m_xLbLoopCount->set_active( m_xLbLoopCount->get_count() - 1); + else + m_xLbLoopCount->set_active_text(OUString::number( nLoopCount ) ); + } + + ::tools::Long nTime = rAnimationBitmap.mnWait; + ::tools::Time aTime( 0, 0, nTime / 100, nTime % 100 ); + size_t nIndex = m_nCurrentFrame + 1; + m_FrameList.insert( + m_FrameList.begin() + nIndex, + ::std::make_pair(rAnimationBitmap.maBitmapEx, aTime)); + + // increment => next one inserted after this one + ++m_nCurrentFrame; + } + // if an animated GIF is taken, only such one can be created + m_xRbtBitmap->set_active(true); + m_xRbtGroup->set_sensitive( false ); + bAnimObj = true; + } + } + else if( bAllObjects || ( pAnimInfo && pAnimInfo->mbIsMovie ) ) + { + // several objects + SdrObjList* pObjList = static_cast<SdrObjGroup*>(pObject)->GetSubList(); + + for( size_t nObject = 0; nObject < pObjList->GetObjCount(); ++nObject ) + { + SdrObject* pSnapShot(pObjList->GetObj(nObject)); + BitmapEx aBitmapEx(SdrExchangeView::GetObjGraphic(*pSnapShot).GetBitmapEx()); + size_t nIndex = m_nCurrentFrame + 1; + m_FrameList.insert( + m_FrameList.begin() + nIndex, + ::std::make_pair(aBitmapEx, m_xFormatter->GetTime())); + + // increment => next one inserted after this one + ++m_nCurrentFrame; + + // Clone + pPage->InsertObject( + pSnapShot->CloneSdrObject(pPage->getSdrModelFromSdrPage()), + m_nCurrentFrame); + } + bAnimObj = true; + } + } + // also one single animated object + if( !bAnimObj && !( bAllObjects && nMarkCount > 1 ) ) + { + BitmapEx aBitmapEx(rView.GetAllMarkedGraphic().GetBitmapEx()); + + ::tools::Time aTime( m_xFormatter->GetTime() ); + + size_t nIndex = m_nCurrentFrame + 1; + m_FrameList.insert( + m_FrameList.begin() + nIndex, + ::std::make_pair(aBitmapEx, aTime)); + } + + // one single object + if( nMarkCount == 1 && !bAnimObj ) + { + SdrMark* pMark = rMarkList.GetMark(0); + SdrObject* pObject = pMark->GetMarkedSdrObj(); + SdrObject* pClone(pObject->CloneSdrObject(pPage->getSdrModelFromSdrPage())); + size_t nIndex = m_nCurrentFrame + 1; + pPage->InsertObject(pClone, nIndex); + } + // several objects: group the clones + else if (nMarkCount > 1) + { + // take objects separately + if( bAllObjects ) + { + for( size_t nObject= 0; nObject < nMarkCount; ++nObject ) + { + // Clone + SdrObject* pObject(rMarkList.GetMark(nObject)->GetMarkedSdrObj()); + BitmapEx aBitmapEx(SdrExchangeView::GetObjGraphic(*pObject).GetBitmapEx()); + size_t nIndex = m_nCurrentFrame + 1; + m_FrameList.insert( + m_FrameList.begin() + nIndex, + ::std::make_pair(aBitmapEx, m_xFormatter->GetTime())); + + // increment => next one inserted after this one + ++m_nCurrentFrame; + + pPage->InsertObject( + pObject->CloneSdrObject(pPage->getSdrModelFromSdrPage()), + m_nCurrentFrame); + } + bAnimObj = true; // that we don't change again + } + else + { + SdrObjGroup* pCloneGroup = new SdrObjGroup(rView.getSdrModelFromSdrView()); + SdrObjList* pObjList = pCloneGroup->GetSubList(); + + for (size_t nObject= 0; nObject < nMarkCount; ++nObject) + { + pObjList->InsertObject( + rMarkList.GetMark(nObject)->GetMarkedSdrObj()->CloneSdrObject( + pPage->getSdrModelFromSdrPage())); + } + + size_t nIndex = m_nCurrentFrame + 1; + pPage->InsertObject(pCloneGroup, nIndex); + } + } + + if( !bAnimObj ) + { + ++m_nCurrentFrame; + } + + // if there was nothing in the animator before but now is something + // there, we can create an animation group + if (nCloneCount == 0 && !m_FrameList.empty()) + { + m_xBtnCreateGroup->set_sensitive(true); + } + + // calculate and set zoom for DisplayWin + Fraction aFrac( GetScale() ); + m_xCtlDisplay->SetScale(aFrac); + + UpdateControl(); +} + +void AnimationWindow::CreateAnimObj (::sd::View& rView ) +{ + vcl::Window* pOutWin = rView.GetFirstOutputDevice()->GetOwnerWindow(); // GetWin( 0 ); + DBG_ASSERT( pOutWin, "Window does not exist!" ); + + // find window center + const MapMode aMap100( MapUnit::Map100thMM ); + Size aMaxSizeLog; + Size aMaxSizePix; + Size aTemp( pOutWin->GetOutputSizePixel() ); + const Point aWindowCenter( pOutWin->PixelToLogic( Point( aTemp.Width() >> 1, aTemp.Height() >> 1 ) ) ); + const OutputDevice* pDefDev = Application::GetDefaultDevice(); + const size_t nCount = m_FrameList.size(); + BitmapAdjustment eBA = static_cast<BitmapAdjustment>(m_xLbAdjustment->get_active()); + + // find biggest bitmap + for (size_t i = 0; i < nCount; ++i) + { + const BitmapEx& rBmpEx = m_FrameList[i].first; + const Graphic aGraphic( rBmpEx ); + Size aTmpSizeLog; + const Size aTmpSizePix( rBmpEx.GetSizePixel() ); + + if ( aGraphic.GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel ) + aTmpSizeLog = pDefDev->PixelToLogic( aGraphic.GetPrefSize(), aMap100 ); + else + aTmpSizeLog = OutputDevice::LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 ); + + aMaxSizeLog.setWidth( std::max( aMaxSizeLog.Width(), aTmpSizeLog.Width() ) ); + aMaxSizeLog.setHeight( std::max( aMaxSizeLog.Height(), aTmpSizeLog.Height() ) ); + + aMaxSizePix.setWidth( std::max( aMaxSizePix.Width(), aTmpSizePix.Width() ) ); + aMaxSizePix.setHeight( std::max( aMaxSizePix.Height(), aTmpSizePix.Height() ) ); + } + + SdrPageView* pPV = rView.GetSdrPageView(); + + if( m_xRbtBitmap->get_active() ) + { + // create bitmap group (Animated GIF) + Animation aAnimation; + Point aPt; + + for (size_t i = 0; i < nCount; ++i) + { + ::tools::Time const & rTime = m_FrameList[i].second; + ::tools::Long nTime = rTime.GetNanoSec(); + nTime += rTime.GetSec() * 100; + + BitmapEx const & rBitmapEx = m_FrameList[i].first; + + // calculate offset for the specified direction + const Size aBitmapSize( rBitmapEx.GetSizePixel() ); + + switch( eBA ) + { + case BA_LEFT_UP: + break; + + case BA_LEFT: + aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 ); + break; + + case BA_LEFT_DOWN: + aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() ); + break; + + case BA_UP: + aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 ); + break; + + case BA_CENTER: + aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 ); + aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 ); + break; + + case BA_DOWN: + aPt.setX( (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1 ); + aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() ); + break; + + case BA_RIGHT_UP: + aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() ); + break; + + case BA_RIGHT: + aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() ); + aPt.setY( (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1 ); + break; + + case BA_RIGHT_DOWN: + aPt.setX( aMaxSizePix.Width() - aBitmapSize.Width() ); + aPt.setY( aMaxSizePix.Height() - aBitmapSize.Height() ); + break; + + } + + // find LoopCount (number of passes) + AnimationBitmap aAnimationBitmap; + sal_uInt32 nLoopCount = 0; + sal_Int32 nPos = m_xLbLoopCount->get_active(); + + if( nPos != -1 && nPos != m_xLbLoopCount->get_count() - 1 ) // endless + nLoopCount = m_xLbLoopCount->get_active_text().toUInt32(); + + aAnimationBitmap.maBitmapEx = rBitmapEx; + aAnimationBitmap.maPositionPixel = aPt; + aAnimationBitmap.maSizePixel = aBitmapSize; + aAnimationBitmap.mnWait = nTime; + aAnimationBitmap.meDisposal = Disposal::Back; + aAnimationBitmap.mbUserInput = false; + + aAnimation.Insert( aAnimationBitmap ); + aAnimation.SetDisplaySizePixel( aMaxSizePix ); + aAnimation.SetLoopCount( nLoopCount ); + } + + SdrGrafObj* pGrafObj = new SdrGrafObj( + rView.getSdrModelFromSdrView(), + Graphic(aAnimation)); + const Point aOrg( aWindowCenter.X() - ( aMaxSizeLog.Width() >> 1 ), aWindowCenter.Y() - ( aMaxSizeLog.Height() >> 1 ) ); + + pGrafObj->SetLogicRect( ::tools::Rectangle( aOrg, aMaxSizeLog ) ); + rView.InsertObjectAtView( pGrafObj, *pPV, SdrInsertFlags::SETDEFLAYER); + } + else + { + // calculate offset for the specified direction + Size aOffset; + SdrObject * pClone = nullptr; + SdPage* pPage = pMyDoc->GetSdPage(0, PageKind::Standard); + + for (size_t i = 0; i < nCount; ++i) + { + pClone = pPage->GetObj(i); + ::tools::Rectangle aRect( pClone->GetSnapRect() ); + + switch( eBA ) + { + case BA_LEFT_UP: + break; + + case BA_LEFT: + aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 ); + break; + + case BA_LEFT_DOWN: + aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() ); + break; + + case BA_UP: + aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 ); + break; + + case BA_CENTER: + aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 ); + aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 ); + break; + + case BA_DOWN: + aOffset.setWidth( (aMaxSizeLog.Width() - aRect.GetWidth()) / 2 ); + aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() ); + break; + + case BA_RIGHT_UP: + aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() ); + break; + + case BA_RIGHT: + aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() ); + aOffset.setHeight( (aMaxSizeLog.Height() - aRect.GetHeight()) / 2 ); + break; + + case BA_RIGHT_DOWN: + aOffset.setWidth( aMaxSizeLog.Width() - aRect.GetWidth() ); + aOffset.setHeight( aMaxSizeLog.Height() - aRect.GetHeight() ); + break; + + } + // Unfortunately, SetSnapRect is not implemented for ellipses !!! + Point aMovePt( aWindowCenter + Point( aOffset.Width(), aOffset.Height() ) - aRect.TopLeft() ); + Size aMoveSize( aMovePt.X(), aMovePt.Y() ); + pClone->NbcMove( aMoveSize ); + } + + // #i42894# Caution(!) variable pPage looks right, but it is a page from the local + // document the dialog is using (!), so get the target page from the target view + SdPage* pTargetSdPage = dynamic_cast< SdPage* >(rView.GetSdrPageView() ? rView.GetSdrPageView()->GetPage() : nullptr); + + if(pTargetSdPage) + { + // create animation group + SdrObjGroup* pGroup = new SdrObjGroup(rView.getSdrModelFromSdrView()); + SdrObjList* pObjList = pGroup->GetSubList(); + + for (size_t i = 0; i < nCount; ++i) + { + // the clone remains in the animation; we insert a clone of the + // clone into the group + pClone = pPage->GetObj(i); + SdrObject* pCloneOfClone(pClone->CloneSdrObject(pTargetSdPage->getSdrModelFromSdrPage())); + //SdrObject* pCloneOfClone = pPage->GetObj(i)->Clone(); + pObjList->InsertObject(pCloneOfClone); + } + + // until now the top left corner of the group is in the window center; + // correct the position by half of the size of the group + aTemp = aMaxSizeLog; + aTemp.setHeight( - aTemp.Height() / 2 ); + aTemp.setWidth( - aTemp.Width() / 2 ); + pGroup->NbcMove(aTemp); + + // #i42894# create needed SMIL stuff and move child objects to page directly (see + // comments at EffectMigration::CreateAnimatedGroup why this has to be done). + EffectMigration::CreateAnimatedGroup(*pGroup, *pTargetSdPage); + + // #i42894# if that worked, delete the group again + if(!pGroup->GetSubList()->GetObjCount()) + { + // always use SdrObject::Free(...) for SdrObjects (!) + SdrObject* pTemp(pGroup); + SdrObject::Free(pTemp); + } + } + } + + ClickFirstHdl(*m_xBtnFirst); +} + +void AnimationWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + SfxDockingWindow::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) + { + UpdateControl(); + } +} + +/** + * ControllerItem for Animator + */ +AnimationControllerItem::AnimationControllerItem( + sal_uInt16 _nId, + AnimationWindow* pAnimWin, + SfxBindings* _pBindings) + : SfxControllerItem( _nId, *_pBindings ), + pAnimationWin( pAnimWin ) +{ +} + +void AnimationControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId, + SfxItemState eState, const SfxPoolItem* pItem ) +{ + if( eState >= SfxItemState::DEFAULT && nSId == SID_ANIMATOR_STATE ) + { + const SfxUInt16Item* pStateItem = dynamic_cast< const SfxUInt16Item*>( pItem ); + assert(pStateItem); //SfxUInt16Item expected + if (pStateItem) + { + sal_uInt16 nState = pStateItem->GetValue(); + pAnimationWin->m_xBtnGetOneObject->set_sensitive( nState & 1 ); + pAnimationWin->m_xBtnGetAllObjects->set_sensitive( nState & 2 ); + } + } +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/assclass.cxx b/sd/source/ui/dlg/assclass.cxx new file mode 100644 index 000000000..4d48a327f --- /dev/null +++ b/sd/source/ui/dlg/assclass.cxx @@ -0,0 +1,160 @@ +/* -*- 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 <tools/debug.hxx> +#include <vcl/weld.hxx> + +#include <assclass.hxx> + +Assistent::Assistent(int nNoOfPages) + : mnPages(nNoOfPages), mnCurrentPage(1) +{ + if(mnPages > MAX_PAGES) + mnPages = MAX_PAGES; + + mpPageStatus.reset(new bool[mnPages]); + + for(int i=0; i < mnPages; ++i) + mpPageStatus[i] = true; +} + +bool Assistent::InsertControl(int nDestPage, weld::Widget* pUsedControl) +{ + DBG_ASSERT( (nDestPage > 0) && (nDestPage <= mnPages), "Page not available!"); + + if((nDestPage>0)&&(nDestPage<=mnPages)) + { + maPages[nDestPage-1].emplace_back(pUsedControl); + pUsedControl->hide(); + pUsedControl->set_sensitive(false); + return true; + } + + return false; +} + +void Assistent::NextPage() +{ + if(mnCurrentPage<mnPages) + { + int nPage = mnCurrentPage+1; + while(nPage <= mnPages && !mpPageStatus[nPage-1]) + nPage++; + + if(nPage <= mnPages) + GotoPage(nPage); + } +} + +void Assistent::PreviousPage() +{ + if(mnCurrentPage>1) + { + int nPage = mnCurrentPage-1; + while(nPage >= 0 && !mpPageStatus[nPage-1]) + nPage--; + + if(nPage >= 0) + GotoPage(nPage); + } +} + +bool Assistent::GotoPage(const int nPageToGo) +{ + DBG_ASSERT( (nPageToGo > 0) && (nPageToGo <= mnPages), "Page not available!"); + + if((nPageToGo>0)&&(nPageToGo<=mnPages)&&mpPageStatus[nPageToGo-1]) + { + int nIndex=mnCurrentPage-1; + + for(auto& rxPage : maPages[nIndex]) + { + rxPage->set_sensitive(false); + rxPage->hide(); + } + + mnCurrentPage=nPageToGo; + nIndex=mnCurrentPage-1; + + for(auto& rxPage : maPages[nIndex]) + { + rxPage->set_sensitive(true); + rxPage->show(); + } + + return true; + } + + return false; +} + +bool Assistent::IsLastPage() const +{ + if(mnCurrentPage == mnPages) + return true; + + int nPage = mnCurrentPage+1; + while(nPage <= mnPages && !mpPageStatus[nPage-1]) + nPage++; + + return nPage > mnPages; +} + +bool Assistent::IsFirstPage() const +{ + if(mnCurrentPage == 1) + return true; + + int nPage = mnCurrentPage-1; + while(nPage > 0 && !mpPageStatus[nPage-1]) + nPage--; + + return nPage == 0; +} + +bool Assistent::IsEnabled( int nPage ) const +{ + DBG_ASSERT( (nPage>0) && (nPage <= mnPages), "Page not available!" ); + + return (nPage>0) && (nPage <= mnPages && mpPageStatus[nPage-1]); +} + +void Assistent::EnablePage( int nPage ) +{ + DBG_ASSERT( (nPage>0) && (nPage <= mnPages), "Page not available!" ); + + if((nPage>0) && (nPage < mnPages && !mpPageStatus[nPage-1])) + { + mpPageStatus[nPage-1] = true; + } +} + +void Assistent::DisablePage( int nPage ) +{ + DBG_ASSERT( (nPage>0) && (nPage <= mnPages), "Page not available!" ); + + if((nPage>0) && (nPage <= mnPages && mpPageStatus[nPage-1])) + { + mpPageStatus[nPage-1] = false; + if(mnCurrentPage == nPage) + GotoPage(1); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/brkdlg.cxx b/sd/source/ui/dlg/brkdlg.cxx new file mode 100644 index 000000000..bc1d0f5cf --- /dev/null +++ b/sd/source/ui/dlg/brkdlg.cxx @@ -0,0 +1,156 @@ +/* -*- 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 <BreakDlg.hxx> +#include <sfx2/progress.hxx> + +#include <svx/svdetc.hxx> +#include <vcl/scheduler.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> + +#include <sdresid.hxx> +#include <drawview.hxx> +#include <strings.hrc> +#include <DrawDocShell.hxx> + +namespace sd { + +/** + * dialog to split metafiles + */ + +BreakDlg::BreakDlg(weld::Window* pWindow, DrawView* pDrView, DrawDocShell* pShell, + sal_uLong nSumActionCount, sal_uLong nObjCount) + : SfxDialogController(pWindow, "modules/sdraw/ui/breakdialog.ui", "BreakDialog") + , m_xFiObjInfo(m_xBuilder->weld_label("metafiles")) + , m_xFiActInfo(m_xBuilder->weld_label("metaobjects")) + , m_xFiInsInfo(m_xBuilder->weld_label("drawingobjects")) + , m_xBtnCancel(m_xBuilder->weld_button("cancel")) + , m_pDrView(pDrView) + , m_bCancel(false) + , m_aUpdateIdle( "sd::BreakDlg m_aUpdateIdle" ) +{ + m_aUpdateIdle.SetPriority( TaskPriority::REPAINT ); + m_aUpdateIdle.SetInvokeHandler( LINK( this, BreakDlg, InitialUpdate ) ); + + m_xBtnCancel->connect_clicked(LINK(this, BreakDlg, CancelButtonHdl)); + + m_xProgress.reset(new SfxProgress(pShell, SdResId(STR_BREAK_METAFILE), nSumActionCount*3)); + + m_xProgrInfo.reset(new SvdProgressInfo(LINK(this, BreakDlg, UpDate))); + // every action is edited 3 times in DoImport() + m_xProgrInfo->Init( nObjCount ); +} + +// Control-Handler for cancel button +IMPL_LINK_NOARG(BreakDlg, CancelButtonHdl, weld::Button&, void) +{ + m_bCancel = true; + m_xBtnCancel->set_sensitive(false); +} + +/** + * The working function has to call the UpDate method periodically. + * With the first call, the overall number of actions is provided. + * Every following call should contain the finished actions since the + * last call of UpDate. + */ +IMPL_LINK( BreakDlg, UpDate, void*, nInit, bool ) +{ + if (!m_xProgrInfo) + return true; + + // update status bar or show an error message? + if(nInit == reinterpret_cast<void*>(1)) + { + std::unique_ptr<weld::MessageDialog> xErrBox(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, + SdResId(STR_BREAK_FAIL))); + xErrBox->run(); + } + else + { + if (m_xProgress) + m_xProgress->SetState(m_xProgrInfo->GetSumCurAction()); + } + + // which object is shown at the moment? + OUString info = OUString::number(m_xProgrInfo->GetCurObj()) + + "/" + + OUString::number(m_xProgrInfo->GetObjCount()); + m_xFiObjInfo->set_label(info); + + // how many actions are started? + if (m_xProgrInfo->GetActionCount() == 0) + { + m_xFiActInfo->set_label( OUString() ); + } + else + { + info = OUString::number(m_xProgrInfo->GetCurAction()) + + "/" + + OUString::number(m_xProgrInfo->GetActionCount()); + m_xFiActInfo->set_label(info); + } + + // and inserted???? + if (m_xProgrInfo->GetInsertCount() == 0) + { + m_xFiInsInfo->set_label( OUString() ); + } + else + { + info = OUString::number(m_xProgrInfo->GetCurInsert()) + + "/" + + OUString::number(m_xProgrInfo->GetInsertCount()); + m_xFiInsInfo->set_label(info); + } + + // make sure dialog gets painted, it is intended to + // show the progress to the user. Also necessary to + // provide a clickable cancel button + Scheduler::ProcessEventsToIdle(); + + // return okay-value (-> !cancel) + return !m_bCancel; +} + +/** + * open a modal dialog and start a timer which calls the working function after + * the opening of the dialog + */ +short BreakDlg::run() +{ + m_aUpdateIdle.Start(); + return SfxDialogController::run(); +} + +/** + * link-method which starts the working function + */ +IMPL_LINK_NOARG(BreakDlg, InitialUpdate, Timer *, void) +{ + m_pDrView->DoImportMarkedMtf(m_xProgrInfo.get()); + m_xDialog->response(RET_OK); +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/copydlg.cxx b/sd/source/ui/dlg/copydlg.cxx new file mode 100644 index 000000000..1fa8c2dab --- /dev/null +++ b/sd/source/ui/dlg/copydlg.cxx @@ -0,0 +1,263 @@ +/* -*- 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 <copydlg.hxx> +#include <svx/colorbox.hxx> +#include <svx/svdpagv.hxx> +#include <svx/sdangitm.hxx> +#include <sfx2/module.hxx> +#include <svx/xcolit.hxx> +#include <svl/intitem.hxx> + +#include <unotools/viewoptions.hxx> +#include <svtools/unitconv.hxx> +#include <o3tl/string_view.hxx> + +#include <sdattr.hrc> +#include <View.hxx> +#include <drawdoc.hxx> + + +namespace sd { + +constexpr char TOKEN = ';'; + +CopyDlg::CopyDlg(weld::Window* pWindow, const SfxItemSet& rInAttrs, ::sd::View* pInView) + : SfxDialogController(pWindow, "modules/sdraw/ui/copydlg.ui", "DuplicateDialog") + , mrOutAttrs(rInAttrs) + , maUIScale(pInView->GetDoc().GetUIScale()) + , mpView(pInView) + , m_xNumFldCopies(m_xBuilder->weld_spin_button("copies")) + , m_xBtnSetViewData(m_xBuilder->weld_button("viewdata")) + , m_xMtrFldMoveX(m_xBuilder->weld_metric_spin_button("x", FieldUnit::CM)) + , m_xMtrFldMoveY(m_xBuilder->weld_metric_spin_button("y", FieldUnit::CM)) + , m_xMtrFldAngle(m_xBuilder->weld_metric_spin_button("angle", FieldUnit::DEGREE)) + , m_xMtrFldWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM)) + , m_xMtrFldHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM)) + , m_xFtEndColor(m_xBuilder->weld_label("endlabel")) + , m_xBtnSetDefault(m_xBuilder->weld_button("default")) + , m_xLbStartColor(new ColorListBox(m_xBuilder->weld_menu_button("start"), [this]{ return m_xDialog.get(); } )) + , m_xLbEndColor(new ColorListBox(m_xBuilder->weld_menu_button("end"), [this]{ return m_xDialog.get(); } )) +{ + m_xLbStartColor->SetSelectHdl( LINK( this, CopyDlg, SelectColorHdl ) ); + m_xBtnSetViewData->connect_clicked( LINK( this, CopyDlg, SetViewData ) ); + m_xBtnSetDefault->connect_clicked( LINK( this, CopyDlg, SetDefault ) ); + + FieldUnit eFUnit( SfxModule::GetCurrentFieldUnit() ); + + SetFieldUnit( *m_xMtrFldMoveX, eFUnit, true ); + SetFieldUnit( *m_xMtrFldMoveY, eFUnit, true ); + SetFieldUnit( *m_xMtrFldWidth, eFUnit, true ); + SetFieldUnit( *m_xMtrFldHeight, eFUnit, true ); + + Reset(); +} + +CopyDlg::~CopyDlg() +{ + SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8)); + OUString sStr = + OUString::number(m_xNumFldCopies->get_value()) + OUStringChar(TOKEN) + + OUString::number(m_xMtrFldMoveX->get_value(FieldUnit::NONE)) + OUStringChar(TOKEN) + + OUString::number(m_xMtrFldMoveY->get_value(FieldUnit::NONE)) + OUStringChar(TOKEN) + + OUString::number(m_xMtrFldAngle->get_value(FieldUnit::NONE)) + OUStringChar(TOKEN) + + OUString::number(m_xMtrFldWidth->get_value(FieldUnit::NONE)) + OUStringChar(TOKEN) + + OUString::number(m_xMtrFldHeight->get_value(FieldUnit::NONE)) + OUStringChar(TOKEN) + + OUString::number(static_cast<sal_uInt32>(m_xLbStartColor->GetSelectEntryColor())) + OUStringChar(TOKEN) + + OUString::number(static_cast<sal_uInt32>(m_xLbEndColor->GetSelectEntryColor())); + aDlgOpt.SetUserItem("UserItem", css::uno::Any(sStr)); +} + +/** + * reads provided item set or evaluate ini string + */ +void CopyDlg::Reset() +{ + // Set Min/Max values + ::tools::Rectangle aRect = mpView->GetAllMarkedRect(); + Size aPageSize = mpView->GetSdrPageView()->GetPage()->GetSize(); + + // tdf#125011 draw/impress sizes are in mm_100th already, "normalize" to + // decimal shift by number of decimal places the widgets are using (2) then + // scale by the ui scaling factor + auto nPageWidth = tools::Long(m_xMtrFldMoveX->normalize(aPageSize.Width()) / maUIScale); + auto nPageHeight = tools::Long(m_xMtrFldMoveX->normalize(aPageSize.Height()) / maUIScale); + auto nRectWidth = tools::Long(m_xMtrFldMoveX->normalize(aRect.GetWidth()) / maUIScale); + auto nRectHeight = tools::Long(m_xMtrFldMoveX->normalize(aRect.GetHeight()) / maUIScale); + + m_xMtrFldMoveX->set_range(-nPageWidth, nPageWidth, FieldUnit::MM_100TH); + m_xMtrFldMoveY->set_range(-nPageHeight, nPageHeight, FieldUnit::MM_100TH); + m_xMtrFldWidth->set_range(-nRectWidth, nPageWidth, FieldUnit::MM_100TH); + m_xMtrFldHeight->set_range(-nRectHeight, nPageHeight, FieldUnit::MM_100TH); + + OUString aStr; + SvtViewOptions aDlgOpt(EViewType::Dialog, OStringToOUString(m_xDialog->get_help_id(), RTL_TEXTENCODING_UTF8)); + if (aDlgOpt.Exists()) + { + css::uno::Any aUserItem = aDlgOpt.GetUserItem("UserItem"); + aUserItem >>= aStr; + } + + if (aStr.isEmpty()) + { + if( const SfxUInt16Item* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_NUMBER ) ) + m_xNumFldCopies->set_value(pPoolItem->GetValue()); + else + m_xNumFldCopies->set_value(1); + + tools::Long nMoveX = 500; + if( const SfxInt32Item* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_MOVE_X ) ) + nMoveX = pPoolItem->GetValue(); + SetMetricValue( *m_xMtrFldMoveX, tools::Long(nMoveX / maUIScale), MapUnit::Map100thMM); + + tools::Long nMoveY = 500; + if( const SfxInt32Item* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_MOVE_Y ) ) + nMoveY = pPoolItem->GetValue(); + SetMetricValue( *m_xMtrFldMoveY, tools::Long(nMoveY / maUIScale), MapUnit::Map100thMM); + + if( const SdrAngleItem* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_ANGLE ) ) + m_xMtrFldAngle->set_value( pPoolItem->GetValue().get(), FieldUnit::NONE); + else + m_xMtrFldAngle->set_value(0, FieldUnit::NONE); + + tools::Long nWidth = 0; + if( const SfxInt32Item* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_WIDTH ) ) + nWidth = pPoolItem->GetValue(); + SetMetricValue( *m_xMtrFldWidth, tools::Long(nWidth / maUIScale), MapUnit::Map100thMM); + + tools::Long nHeight = 0; + if( const SfxInt32Item* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_HEIGHT ) ) + nHeight = pPoolItem->GetValue(); + SetMetricValue( *m_xMtrFldHeight, tools::Long(nHeight / maUIScale), MapUnit::Map100thMM); + + if( const XColorItem* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_START_COLOR ) ) + { + Color aColor = pPoolItem->GetColorValue(); + m_xLbStartColor->SelectEntry( aColor ); + m_xLbEndColor->SelectEntry( aColor ); + } + else + { + m_xLbStartColor->SetNoSelection(); + m_xLbEndColor->SetNoSelection(); + m_xLbEndColor->set_sensitive(false); + m_xFtEndColor->set_sensitive(false); + } + } + else + { + sal_Int32 nIdx {0}; + m_xNumFldCopies->set_value(o3tl::toInt64(o3tl::getToken(aStr, 0, TOKEN, nIdx))); + m_xMtrFldMoveX->set_value(o3tl::toInt64(o3tl::getToken(aStr, 0, TOKEN, nIdx)), FieldUnit::NONE); + m_xMtrFldMoveY->set_value(o3tl::toInt64(o3tl::getToken(aStr, 0, TOKEN, nIdx)), FieldUnit::NONE); + m_xMtrFldAngle->set_value(o3tl::toInt64(o3tl::getToken(aStr, 0, TOKEN, nIdx)), FieldUnit::NONE); + m_xMtrFldWidth->set_value(o3tl::toInt64(o3tl::getToken(aStr, 0, TOKEN, nIdx)), FieldUnit::NONE); + m_xMtrFldHeight->set_value(o3tl::toInt64(o3tl::getToken(aStr, 0, TOKEN, nIdx)), FieldUnit::NONE); + m_xLbStartColor->SelectEntry( Color( ColorTransparency, o3tl::toUInt32(o3tl::getToken(aStr, 0, TOKEN, nIdx)) ) ); + m_xLbEndColor->SelectEntry( Color( ColorTransparency, o3tl::toUInt32(o3tl::getToken(aStr, 0, TOKEN, nIdx)) ) ); + } + +} + +/** + * fills provided item set with dialog box attributes + */ +void CopyDlg::GetAttr( SfxItemSet& rOutAttrs ) +{ + tools::Long nMoveX = tools::Long( GetCoreValue( *m_xMtrFldMoveX, MapUnit::Map100thMM) * maUIScale); + tools::Long nMoveY = tools::Long( GetCoreValue( *m_xMtrFldMoveY, MapUnit::Map100thMM) * maUIScale); + tools::Long nHeight = tools::Long( GetCoreValue( *m_xMtrFldHeight, MapUnit::Map100thMM) * maUIScale); + tools::Long nWidth = tools::Long( GetCoreValue( *m_xMtrFldWidth, MapUnit::Map100thMM) * maUIScale); + + rOutAttrs.Put( SfxUInt16Item( ATTR_COPY_NUMBER, static_cast<sal_uInt16>(m_xNumFldCopies->get_value()) ) ); + rOutAttrs.Put( SfxInt32Item( ATTR_COPY_MOVE_X, nMoveX ) ); + rOutAttrs.Put( SfxInt32Item( ATTR_COPY_MOVE_Y, nMoveY ) ); + rOutAttrs.Put( SdrAngleItem( ATTR_COPY_ANGLE, Degree100(static_cast<sal_Int32>(m_xMtrFldAngle->get_value(FieldUnit::DEGREE))) ) ); + rOutAttrs.Put( SfxInt32Item( ATTR_COPY_WIDTH, nWidth ) ); + rOutAttrs.Put( SfxInt32Item( ATTR_COPY_HEIGHT, nHeight ) ); + + NamedColor aColor = m_xLbStartColor->GetSelectedEntry(); + rOutAttrs.Put(XColorItem(ATTR_COPY_START_COLOR, aColor.second, aColor.first)); + aColor = m_xLbEndColor->GetSelectedEntry(); + rOutAttrs.Put(XColorItem(ATTR_COPY_END_COLOR, aColor.second, aColor.first)); +} + +/** + * enables and selects end color LB + */ +IMPL_LINK_NOARG(CopyDlg, SelectColorHdl, ColorListBox&, void) +{ + const Color aColor = m_xLbStartColor->GetSelectEntryColor(); + + if (!m_xLbEndColor->get_sensitive()) + { + m_xLbEndColor->SelectEntry(aColor); + m_xLbEndColor->set_sensitive(true); + m_xFtEndColor->set_sensitive(true); + } +} + +/** + * sets values of selection + */ +IMPL_LINK_NOARG(CopyDlg, SetViewData, weld::Button&, void) +{ + ::tools::Rectangle aRect = mpView->GetAllMarkedRect(); + + SetMetricValue( *m_xMtrFldMoveX, tools::Long( aRect.GetWidth() / + maUIScale ), MapUnit::Map100thMM); + SetMetricValue( *m_xMtrFldMoveY, tools::Long( aRect.GetHeight() / + maUIScale ), MapUnit::Map100thMM); + + // sets color attribute + if( const XColorItem* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_START_COLOR ) ) + { + Color aColor = pPoolItem->GetColorValue(); + m_xLbStartColor->SelectEntry( aColor ); + } +} + +/** + * resets values to default + */ +IMPL_LINK_NOARG(CopyDlg, SetDefault, weld::Button&, void) +{ + m_xNumFldCopies->set_value(1); + + tools::Long nValue = 500; + SetMetricValue( *m_xMtrFldMoveX, tools::Long(nValue / maUIScale), MapUnit::Map100thMM); + SetMetricValue( *m_xMtrFldMoveY, tools::Long(nValue / maUIScale), MapUnit::Map100thMM); + + nValue = 0; + m_xMtrFldAngle->set_value(nValue, FieldUnit::DEGREE); + SetMetricValue( *m_xMtrFldWidth, tools::Long(nValue / maUIScale), MapUnit::Map100thMM); + SetMetricValue( *m_xMtrFldHeight, tools::Long(nValue / maUIScale), MapUnit::Map100thMM); + + // set color attribute + if( const XColorItem* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_COPY_START_COLOR ) ) + { + Color aColor = pPoolItem->GetColorValue(); + m_xLbStartColor->SelectEntry( aColor ); + m_xLbEndColor->SelectEntry( aColor ); + } +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/custsdlg.cxx b/sd/source/ui/dlg/custsdlg.cxx new file mode 100644 index 000000000..bc421d7e4 --- /dev/null +++ b/sd/source/ui/dlg/custsdlg.cxx @@ -0,0 +1,478 @@ +/* -*- 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 <custsdlg.hxx> + +#include <strings.hrc> +#include <sdresid.hxx> + +#include <drawdoc.hxx> +#include <sdpage.hxx> +#include <cusshow.hxx> +#include <customshowlist.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <unotools/charclass.hxx> +#include <tools/debug.hxx> + +// SdCustomShowDlg +SdCustomShowDlg::SdCustomShowDlg(weld::Window* pWindow, SdDrawDocument& rDrawDoc) + : GenericDialogController(pWindow, "modules/simpress/ui/customslideshows.ui", "CustomSlideShows") + , rDoc(rDrawDoc) + , pCustomShowList(nullptr) + , m_xLbCustomShows(m_xBuilder->weld_tree_view("customshowlist")) + , m_xBtnNew(m_xBuilder->weld_button("new")) + , m_xBtnEdit(m_xBuilder->weld_button("edit")) + , m_xBtnRemove(m_xBuilder->weld_button("delete")) + , m_xBtnCopy(m_xBuilder->weld_button("copy")) + , m_xBtnHelp(m_xBuilder->weld_button("help")) + , m_xBtnStartShow(m_xBuilder->weld_button("startshow")) + , m_xBtnOK(m_xBuilder->weld_button("ok")) +{ + m_xLbCustomShows->set_size_request(m_xLbCustomShows->get_approximate_digit_width() * 32, + m_xLbCustomShows->get_height_rows(8)); + + Link<weld::Button&,void> aLink( LINK( this, SdCustomShowDlg, ClickButtonHdl ) ); + m_xBtnNew->connect_clicked( aLink ); + m_xBtnEdit->connect_clicked( aLink ); + m_xBtnRemove->connect_clicked( aLink ); + m_xBtnCopy->connect_clicked( aLink ); + m_xLbCustomShows->connect_changed( LINK( this, SdCustomShowDlg, SelectListBoxHdl ) ); + + m_xBtnStartShow->connect_clicked( LINK( this, SdCustomShowDlg, StartShowHdl ) ); // for test + + // get CustomShow list of docs + pCustomShowList = rDoc.GetCustomShowList(); + if( pCustomShowList ) + { + tools::Long nPosToSelect = pCustomShowList->GetCurPos(); + // fill ListBox with CustomShows + for( SdCustomShow* pCustomShow = pCustomShowList->First(); + pCustomShow != nullptr; + pCustomShow = pCustomShowList->Next() ) + { + m_xLbCustomShows->append_text(pCustomShow->GetName()); + } + m_xLbCustomShows->select(nPosToSelect); + pCustomShowList->Seek( nPosToSelect ); + } + + CheckState(); +} + +SdCustomShowDlg::~SdCustomShowDlg() +{ +} + +void SdCustomShowDlg::CheckState() +{ + int nPos = m_xLbCustomShows->get_selected_index(); + + bool bEnable = nPos != -1; + m_xBtnEdit->set_sensitive( bEnable ); + m_xBtnRemove->set_sensitive( bEnable ); + m_xBtnCopy->set_sensitive( bEnable ); + m_xBtnStartShow->set_sensitive(bEnable); + + if (bEnable && pCustomShowList) + pCustomShowList->Seek( nPos ); +} + +IMPL_LINK( SdCustomShowDlg, ClickButtonHdl, weld::Button&, r, void ) +{ + SelectHdl(&r); +} + +IMPL_LINK( SdCustomShowDlg, SelectListBoxHdl, weld::TreeView&, rListBox, void ) +{ + SelectHdl(&rListBox); +} + +void SdCustomShowDlg::SelectHdl(void const *p) +{ + // new CustomShow + if (p == m_xBtnNew.get()) + { + std::unique_ptr<SdCustomShow> pCustomShow; + SdDefineCustomShowDlg aDlg(m_xDialog.get(), rDoc, pCustomShow); + if (aDlg.run() == RET_OK) + { + if( pCustomShow ) + { + if( !pCustomShowList ) + pCustomShowList = rDoc.GetCustomShowList( true ); + + SdCustomShow* pCustomShowTmp = pCustomShow.get(); + pCustomShowList->push_back( std::move(pCustomShow) ); + pCustomShowList->Last(); + m_xLbCustomShows->append_text( pCustomShowTmp->GetName() ); + m_xLbCustomShows->select_text( pCustomShowTmp->GetName() ); + } + } + } + // edit CustomShow + else if( p == m_xBtnEdit.get() ) + { + int nPos = m_xLbCustomShows->get_selected_index(); + if (nPos != -1) + { + DBG_ASSERT( pCustomShowList, "pCustomShowList does not exist" ); + std::unique_ptr<SdCustomShow>& pCustomShow = (*pCustomShowList)[ nPos ]; + SdDefineCustomShowDlg aDlg(m_xDialog.get(), rDoc, pCustomShow); + + if (aDlg.run() == RET_OK) + { + pCustomShowList->Seek(nPos); + m_xLbCustomShows->remove(nPos); + m_xLbCustomShows->insert_text(nPos, pCustomShow->GetName()); + m_xLbCustomShows->select(nPos); + } + } + } + // delete CustomShow + else if( p == m_xBtnRemove.get() ) + { + int nPos = m_xLbCustomShows->get_selected_index(); + if (nPos != -1) + { + pCustomShowList->erase( pCustomShowList->begin() + nPos ); + m_xLbCustomShows->remove(nPos); + m_xLbCustomShows->select(nPos == 0 ? nPos : nPos - 1); + } + } + // copy CustomShow + else if( p == m_xBtnCopy.get() ) + { + int nPos = m_xLbCustomShows->get_selected_index(); + if (nPos != -1) + { + std::unique_ptr<SdCustomShow> pShow(new SdCustomShow( *(*pCustomShowList)[nPos] )); + OUString aStr( pShow->GetName() ); + OUString aStrCopy( SdResId( STR_COPY_CUSTOMSHOW ) ); + + sal_Int32 nStrPos = aStr.indexOf( aStrCopy ); + sal_Int32 nNum = 1; + if( nStrPos < 0 ) + { + aStr += " (" + aStrCopy + OUString::number( nNum ) + ")"; + nStrPos = aStr.indexOf( aStrCopy ); + } + nStrPos = nStrPos + aStrCopy.getLength(); + // that we do not access into the nirvana (--> endless loop) + if( nStrPos >= aStr.getLength() ) + { + aStr += " " + OUString::number( nNum ); + } + + // check name... + bool bDifferent = false; + //long nPosToSelect = pCustomShowList->GetCurPos(); + while( !bDifferent ) + { + bDifferent = true; + for( SdCustomShow* pCustomShow = pCustomShowList->First(); + pCustomShow != nullptr && bDifferent; + pCustomShow = pCustomShowList->Next() ) + { + if( aStr == pCustomShow->GetName() ) + bDifferent = false; + } + if( !bDifferent ) + { + // replace number by a number increased by 1 + + const CharClass* pCharClass = rDoc.GetCharClass(); + while( pCharClass->isDigit( aStr, nStrPos ) ) + aStr = aStr.replaceAt( nStrPos, 1, u"" ); + aStr = aStr.subView( 0, nStrPos) + OUString::number( ++nNum ) + aStr.subView( nStrPos); + } + + } + //pCustomShowList->Seek( nPosToSelect ); + pShow->SetName( aStr ); + + auto pShowTmp = pShow.get(); + pCustomShowList->push_back( std::move(pShow) ); + pCustomShowList->Last(); + m_xLbCustomShows->append_text(pShowTmp->GetName()); + m_xLbCustomShows->select_text(pShowTmp->GetName()); + } + } + else if( p == m_xLbCustomShows.get() ) + { + int nPos = m_xLbCustomShows->get_selected_index(); + if (nPos != -1) + pCustomShowList->Seek(nPos); + } + + CheckState(); +} + +// StartShow-Hdl +IMPL_LINK_NOARG(SdCustomShowDlg, StartShowHdl, weld::Button&, void) +{ + m_xDialog->response(RET_YES); +} + +// CheckState +bool SdCustomShowDlg::IsCustomShow() const +{ + if (!pCustomShowList->empty()) + return true; + else + return false; +} + +// SdDefineCustomShowDlg +SdDefineCustomShowDlg::SdDefineCustomShowDlg(weld::Window* pWindow, SdDrawDocument& rDrawDoc, std::unique_ptr<SdCustomShow>& rpCS) + : GenericDialogController(pWindow, "modules/simpress/ui/definecustomslideshow.ui", "DefineCustomSlideShow") + , rDoc(rDrawDoc) + , rpCustomShow(rpCS) + , bModified(false) + , m_xEdtName(m_xBuilder->weld_entry("customname")) + , m_xLbPages(m_xBuilder->weld_tree_view("pages")) + , m_xBtnAdd(m_xBuilder->weld_button("add")) + , m_xBtnRemove(m_xBuilder->weld_button("remove")) + , m_xLbCustomPages(m_xBuilder->weld_tree_view("custompages")) + , m_xDropTargetHelper(new weld::ReorderingDropTarget(*m_xLbCustomPages)) + , m_xBtnOK(m_xBuilder->weld_button("ok")) + , m_xBtnCancel(m_xBuilder->weld_button("cancel")) + , m_xBtnHelp(m_xBuilder->weld_button("help")) +{ + Link<weld::Button&,void> aLink = LINK( this, SdDefineCustomShowDlg, ClickButtonHdl ); + m_xBtnAdd->connect_clicked( aLink ); + m_xBtnRemove->connect_clicked( aLink ); + m_xEdtName->connect_changed( LINK( this, SdDefineCustomShowDlg, ClickButtonEditHdl ) ); + m_xLbPages->connect_changed( LINK( this, SdDefineCustomShowDlg, ClickButtonHdl4 ) ); // because of status + m_xLbCustomPages->connect_changed( LINK( this, SdDefineCustomShowDlg, ClickButtonHdl3 ) ); // because of status + + m_xBtnOK->connect_clicked( LINK( this, SdDefineCustomShowDlg, OKHdl ) ); + + m_xLbPages->set_selection_mode(SelectionMode::Multiple); + + // shape 'em a bit + m_xLbPages->set_size_request(m_xLbPages->get_approximate_digit_width() * 24, m_xLbPages->get_height_rows(10)); + m_xLbCustomPages->set_size_request(m_xLbPages->get_approximate_digit_width() * 24, m_xLbCustomPages->get_height_rows(10)); + + // fill Listbox with page names of Docs + for( tools::Long nPage = 0; + nPage < rDoc.GetSdPageCount( PageKind::Standard ); + nPage++ ) + { + SdPage* pPage = rDoc.GetSdPage( static_cast<sal_uInt16>(nPage), PageKind::Standard ); + m_xLbPages->append_text(pPage->GetName()); + } + // aLbPages.SelectEntryPos( 0 ); + + if( rpCustomShow ) + { + aOldName = rpCustomShow->GetName(); + m_xEdtName->set_text( aOldName ); + + // fill ListBox with CustomShow pages + for( const auto& rpPage : rpCustomShow->PagesVector() ) + { + m_xLbCustomPages->append(weld::toId(rpPage), rpPage->GetName(), ""); + } + } + else + { + rpCustomShow.reset(new SdCustomShow); + m_xEdtName->set_text( SdResId( STR_NEW_CUSTOMSHOW ) ); + m_xEdtName->select_region(0, -1); + rpCustomShow->SetName( m_xEdtName->get_text() ); + } + + m_xBtnOK->set_sensitive( false ); + CheckState(); +} + +SdDefineCustomShowDlg::~SdDefineCustomShowDlg() +{ +} + +// CheckState +void SdDefineCustomShowDlg::CheckState() +{ + bool bPages = m_xLbPages->count_selected_rows() > 0; + bool bCSPages = m_xLbCustomPages->get_selected_index() != -1; + bool bCount = m_xLbCustomPages->n_children() > 0; + + m_xBtnOK->set_sensitive( bCount ); + m_xBtnAdd->set_sensitive( bPages ); + m_xBtnRemove->set_sensitive( bCSPages ); +} + +IMPL_LINK( SdDefineCustomShowDlg, ClickButtonHdl, weld::Button&, rWidget, void ) +{ + ClickButtonHdl2(&rWidget); +} + +IMPL_LINK( SdDefineCustomShowDlg, ClickButtonHdl3, weld::TreeView&, rWidget, void ) +{ + ClickButtonHdl2(&rWidget); +} + +IMPL_LINK( SdDefineCustomShowDlg, ClickButtonHdl4, weld::TreeView&, rListBox, void ) +{ + ClickButtonHdl2(&rListBox); +} + +IMPL_LINK( SdDefineCustomShowDlg, ClickButtonEditHdl, weld::Entry&, rEdit, void ) +{ + ClickButtonHdl2(&rEdit); +} + +// ButtonHdl() +void SdDefineCustomShowDlg::ClickButtonHdl2(void const * p) +{ + if( p == m_xBtnAdd.get() ) + { + auto aRows = m_xLbPages->get_selected_rows(); + if (!aRows.empty()) + { + int nPosCP = m_xLbCustomPages->get_selected_index(); + if (nPosCP != -1) + ++nPosCP; + + for (auto i : aRows) + { + OUString aStr = m_xLbPages->get_text(i); + SdPage* pPage = rDoc.GetSdPage(i, PageKind::Standard); + OUString sId(weld::toId(pPage)); + m_xLbCustomPages->insert(nPosCP, aStr, &sId, nullptr, nullptr); + m_xLbCustomPages->select(nPosCP != -1 ? nPosCP : m_xLbCustomPages->n_children() - 1); + + if (nPosCP != -1) + ++nPosCP; + } + bModified = true; + } + } + else if (p == m_xBtnRemove.get()) + { + int nPos = m_xLbCustomPages->get_selected_index(); + if (nPos != -1) + { + m_xLbCustomPages->remove(nPos); + m_xLbCustomPages->select(nPos == 0 ? nPos : nPos - 1); + bModified = true; + } + } + else if( p == m_xEdtName.get() ) + { + bModified = true; + } + + CheckState(); +} + +/** + * Checks the page pointer of the Show since entries can be moved and copied + * by TreeLB. + */ +void SdDefineCustomShowDlg::CheckCustomShow() +{ + bool bDifferent = false; + + // compare count + size_t nCount = m_xLbCustomPages->n_children(); + if (rpCustomShow->PagesVector().size() != nCount) + { + rpCustomShow->PagesVector().clear(); + bDifferent = true; + } + + // compare page pointer + if( !bDifferent ) + { + size_t i = 0; + for (const auto& rpPage : rpCustomShow->PagesVector()) + { + SdPage* pPage = weld::fromId<SdPage*>(m_xLbCustomPages->get_id(i)); + if (rpPage != pPage) + { + rpCustomShow->PagesVector().clear(); + bDifferent = true; + break; + } + + ++i; + } + } + + // set new page pointer + if( bDifferent ) + { + for (size_t i = 0; i < nCount; ++i) + { + SdPage* pPage = weld::fromId<SdPage*>(m_xLbCustomPages->get_id(i)); + rpCustomShow->PagesVector().push_back(pPage); + } + bModified = true; + } + + // compare name and set name if necessary + OUString aStr( m_xEdtName->get_text() ); + if( rpCustomShow->GetName() != aStr ) + { + rpCustomShow->SetName( aStr ); + bModified = true; + } +} + +// OK-Hdl +IMPL_LINK_NOARG(SdDefineCustomShowDlg, OKHdl, weld::Button&, void) +{ + // check name... + bool bDifferent = true; + SdCustomShowList* pCustomShowList = rDoc.GetCustomShowList(); + if( pCustomShowList ) + { + OUString aName( m_xEdtName->get_text() ); + SdCustomShow* pCustomShow; + + tools::Long nPosToSelect = pCustomShowList->GetCurPos(); + for( pCustomShow = pCustomShowList->First(); + pCustomShow != nullptr; + pCustomShow = pCustomShowList->Next() ) + { + if( aName == pCustomShow->GetName() && aName != aOldName ) + bDifferent = false; + } + pCustomShowList->Seek( nPosToSelect ); + } + + if( bDifferent ) + { + CheckCustomShow(); + + m_xDialog->response(RET_OK); + } + else + { + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(), + VclMessageType::Warning, VclButtonsType::Ok, + SdResId(STR_WARN_NAME_DUPLICATE))); + xWarn->run(); + m_xEdtName->grab_focus(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/diactrl.cxx b/sd/source/ui/dlg/diactrl.cxx new file mode 100644 index 000000000..233550809 --- /dev/null +++ b/sd/source/ui/dlg/diactrl.cxx @@ -0,0 +1,185 @@ +/* -*- 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 <sal/config.h> + +#include <comphelper/propertyvalue.hxx> +#include <vcl/fieldvalues.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <svl/intitem.hxx> + +#include <strings.hrc> + +#include <diactrl.hxx> + +#include <sdresid.hxx> +#include <app.hrc> + +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XFrame.hpp> + +using namespace ::com::sun::star; + +SFX_IMPL_TOOLBOX_CONTROL( SdTbxCtlDiaPages, SfxUInt16Item ) + +namespace +{ + OUString format_number(int nSlides) + { + OUString aSlides(SdResId(STR_SLIDES, nSlides)); + return aSlides.replaceFirst("%1", OUString::number(nSlides)); + } +} + +// SdPagesField +SdPagesField::SdPagesField( vcl::Window* pParent, + const uno::Reference< frame::XFrame >& rFrame ) + : InterimItemWindow(pParent, "modules/simpress/ui/pagesfieldbox.ui", "PagesFieldBox") + , m_xWidget(m_xBuilder->weld_spin_button("pagesfield")) + , m_xFrame(rFrame) +{ + InitControlBase(m_xWidget.get()); + + // set parameter of MetricFields + m_xWidget->set_digits(0); + m_xWidget->set_range(1, 15); + m_xWidget->set_increments(1, 5); + m_xWidget->connect_value_changed(LINK(this, SdPagesField, ModifyHdl)); + m_xWidget->connect_output(LINK(this, SdPagesField, OutputHdl)); + m_xWidget->connect_input(LINK(this, SdPagesField, spin_button_input)); + m_xWidget->connect_key_press(LINK(this, SdPagesField, KeyInputHdl)); + + auto width = std::max(m_xWidget->get_pixel_size(format_number(1)).Width(), + m_xWidget->get_pixel_size(format_number(15)).Width()); + int chars = ceil(width / m_xWidget->get_approximate_digit_width()); + m_xWidget->set_width_chars(chars); + + SetSizePixel(m_xWidget->get_preferred_size()); +} + +IMPL_LINK(SdPagesField, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return ChildKeyInput(rKEvt); +} + +void SdPagesField::dispose() +{ + m_xWidget.reset(); + InterimItemWindow::dispose(); +} + +SdPagesField::~SdPagesField() +{ + disposeOnce(); +} + +void SdPagesField::set_sensitive(bool bSensitive) +{ + Enable(bSensitive); + m_xWidget->set_sensitive(bSensitive); + if (!bSensitive) + m_xWidget->set_text(""); +} + +void SdPagesField::UpdatePagesField( const SfxUInt16Item* pItem ) +{ + if (pItem) + m_xWidget->set_value(pItem->GetValue()); + else + m_xWidget->set_text(OUString()); +} + +IMPL_STATIC_LINK(SdPagesField, OutputHdl, weld::SpinButton&, rSpinButton, void) +{ + rSpinButton.set_text(format_number(rSpinButton.get_value())); +} + +IMPL_LINK(SdPagesField, spin_button_input, int*, result, bool) +{ + const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetLocaleDataWrapper(); + double fResult(0.0); + bool bRet = vcl::TextToValue(m_xWidget->get_text(), fResult, 0, m_xWidget->get_digits(), rLocaleData, FieldUnit::NONE); + if (bRet) + { + if (fResult > SAL_MAX_INT32) + fResult = SAL_MAX_INT32; + else if (fResult < SAL_MIN_INT32) + fResult = SAL_MIN_INT32; + *result = fResult; + } + return bRet; +} + +IMPL_LINK_NOARG(SdPagesField, ModifyHdl, weld::SpinButton&, void) +{ + SfxUInt16Item aItem(SID_PAGES_PER_ROW, m_xWidget->get_value()); + + uno::Any a; + aItem.QueryValue( a ); + uno::Sequence< beans::PropertyValue > aArgs{ comphelper::makePropertyValue("PagesPerRow", a) }; + SfxToolBoxControl::Dispatch( ::uno::Reference< ::frame::XDispatchProvider >( m_xFrame->getController(), ::uno::UNO_QUERY ), + ".uno:PagesPerRow", + aArgs ); +} + +SdTbxCtlDiaPages::SdTbxCtlDiaPages( sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx ) : + SfxToolBoxControl( nSlotId, nId, rTbx ) +{ +} + +SdTbxCtlDiaPages::~SdTbxCtlDiaPages() +{ +} + +void SdTbxCtlDiaPages::StateChangedAtToolBoxControl( sal_uInt16, + SfxItemState eState, const SfxPoolItem* pState ) +{ + SdPagesField* pFld = static_cast<SdPagesField*>( GetToolBox().GetItemWindow( GetId() ) ); + DBG_ASSERT( pFld, "Window not found" ); + + if ( eState == SfxItemState::DISABLED ) + { + pFld->set_sensitive(false); + } + else + { + pFld->set_sensitive(true); + + const SfxUInt16Item* pItem = nullptr; + if ( eState == SfxItemState::DEFAULT ) + { + pItem = dynamic_cast< const SfxUInt16Item* >( pState ); + DBG_ASSERT( pItem, "sd::SdTbxCtlDiaPages::StateChanged(), wrong item type!" ); + } + + pFld->UpdatePagesField( pItem ); + } +} + +VclPtr<InterimItemWindow> SdTbxCtlDiaPages::CreateItemWindow( vcl::Window* pParent ) +{ + VclPtr<SdPagesField> pWindow = VclPtr<SdPagesField>::Create(pParent, m_xFrame); + pWindow->Show(); + + return pWindow; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/dlgchar.cxx b/sd/source/ui/dlg/dlgchar.cxx new file mode 100644 index 000000000..df1b24179 --- /dev/null +++ b/sd/source/ui/dlg/dlgchar.cxx @@ -0,0 +1,70 @@ +/* -*- 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 <svx/dialogs.hrc> +#include <editeng/flstitem.hxx> +#include <svx/flagsdef.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/sfxdlg.hxx> + +#include <dlg_char.hxx> +#include <svx/svxids.hrc> +#include <svl/intitem.hxx> + +/** + * Constructor of tab dialog: append pages to dialog + */ +SdCharDlg::SdCharDlg(weld::Window* pParent, const SfxItemSet* pAttr, + const SfxObjectShell* pDocShell) + : SfxTabDialogController(pParent, "modules/sdraw/ui/drawchardialog.ui", + "DrawCharDialog", pAttr) + , rDocShell(*pDocShell) +{ + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + + AddTabPage("RID_SVXPAGE_CHAR_NAME", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_CHAR_NAME), nullptr); + AddTabPage("RID_SVXPAGE_CHAR_EFFECTS", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_CHAR_EFFECTS), nullptr); + AddTabPage("RID_SVXPAGE_CHAR_POSITION", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_CHAR_POSITION), nullptr); + AddTabPage("RID_SVXPAGE_BKG", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_BKG), nullptr); +} + +void SdCharDlg::PageCreated(const OString& rId, SfxTabPage &rPage) +{ + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + if (rId == "RID_SVXPAGE_CHAR_NAME") + { + SvxFontListItem aItem(* static_cast<const SvxFontListItem*>( rDocShell.GetItem( SID_ATTR_CHAR_FONTLIST) ) ); + + aSet.Put (SvxFontListItem( aItem.GetFontList(), SID_ATTR_CHAR_FONTLIST)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_CHAR_EFFECTS") + { + // Opt in for character transparency. + aSet.Put(SfxUInt32Item(SID_FLAG_TYPE, SVX_ENABLE_CHAR_TRANSPARENCY)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_BKG") + { + aSet.Put(SfxUInt32Item(SID_FLAG_TYPE,static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR))); + rPage.PageCreated(aSet); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/dlgfield.cxx b/sd/source/ui/dlg/dlgfield.cxx new file mode 100644 index 000000000..75263a17c --- /dev/null +++ b/sd/source/ui/dlg/dlgfield.cxx @@ -0,0 +1,301 @@ +/* -*- 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 <editeng/eeitem.hxx> +#include <editeng/flditem.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/docfile.hxx> +#include <svl/itemset.hxx> +#include <svx/langbox.hxx> +#include <editeng/langitem.hxx> +#include <unotools/useroptions.hxx> + +#include <strings.hrc> +#include <sdresid.hxx> +#include <sdmod.hxx> +#include <dlgfield.hxx> +#include <DrawDocShell.hxx> + +/** + * dialog to edit field commands + */ +SdModifyFieldDlg::SdModifyFieldDlg(weld::Window* pWindow, const SvxFieldData* pInField, const SfxItemSet& rSet) + : GenericDialogController(pWindow, "modules/simpress/ui/dlgfield.ui", "EditFieldsDialog") + , m_aInputSet(rSet) + , m_pField(pInField) + , m_xRbtFix(m_xBuilder->weld_radio_button("fixedRB")) + , m_xRbtVar(m_xBuilder->weld_radio_button("varRB")) + , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("languageLB"))) + , m_xLbFormat(m_xBuilder->weld_combo_box("formatLB")) +{ + m_xLbLanguage->SetLanguageList( SvxLanguageListFlags::ALL|SvxLanguageListFlags::ONLY_KNOWN, false ); + m_xLbLanguage->connect_changed(LINK(this, SdModifyFieldDlg, LanguageChangeHdl)); + FillControls(); +} + +SdModifyFieldDlg::~SdModifyFieldDlg() +{ +} + +/** + * Returns the new field, owned by caller. + * Returns NULL if nothing has changed. + */ +SvxFieldData* SdModifyFieldDlg::GetField() +{ + SvxFieldData* pNewField = nullptr; + + if( m_xRbtFix->get_state_changed_from_saved() || + m_xRbtVar->get_state_changed_from_saved() || + m_xLbFormat->get_value_changed_from_saved() ) + { + if( auto pDateField = dynamic_cast< const SvxDateField *>( m_pField ) ) + { + SvxDateType eType; + SvxDateFormat eFormat; + + if( m_xRbtFix->get_active() ) + eType = SvxDateType::Fix; + else + eType = SvxDateType::Var; + + eFormat = static_cast<SvxDateFormat>( m_xLbFormat->get_active() + 2 ); + + pNewField = new SvxDateField( *pDateField ); + static_cast<SvxDateField*>( pNewField )->SetType( eType ); + static_cast<SvxDateField*>( pNewField )->SetFormat( eFormat ); + } + else if( auto pTimeField = dynamic_cast< const SvxExtTimeField *>( m_pField ) ) + { + SvxTimeType eType; + SvxTimeFormat eFormat; + + if( m_xRbtFix->get_active() ) + eType = SvxTimeType::Fix; + else + eType = SvxTimeType::Var; + + eFormat = static_cast<SvxTimeFormat>( m_xLbFormat->get_active() + 2 ); + + pNewField = new SvxExtTimeField( *pTimeField ); + static_cast<SvxExtTimeField*>( pNewField )->SetType( eType ); + static_cast<SvxExtTimeField*>( pNewField )->SetFormat( eFormat ); + } + else if( dynamic_cast< const SvxExtFileField *>( m_pField ) != nullptr ) + { + SvxFileType eType; + SvxFileFormat eFormat; + + if( m_xRbtFix->get_active() ) + eType = SvxFileType::Fix; + else + eType = SvxFileType::Var; + + eFormat = static_cast<SvxFileFormat>( m_xLbFormat->get_active() ); + + ::sd::DrawDocShell* pDocSh = dynamic_cast< ::sd::DrawDocShell* >(SfxObjectShell::Current() ); + + if( pDocSh ) + { + OUString aName; + if( pDocSh->HasName() ) + aName = pDocSh->GetMedium()->GetName(); + + // Get current filename, not the one stored in the old field + pNewField = new SvxExtFileField( aName ); + static_cast<SvxExtFileField*>( pNewField )->SetType( eType ); + static_cast<SvxExtFileField*>( pNewField )->SetFormat( eFormat ); + } + } + else if( dynamic_cast< const SvxAuthorField *>( m_pField ) != nullptr ) + { + SvxAuthorType eType; + SvxAuthorFormat eFormat; + + if( m_xRbtFix->get_active() ) + eType = SvxAuthorType::Fix; + else + eType = SvxAuthorType::Var; + + eFormat = static_cast<SvxAuthorFormat>( m_xLbFormat->get_active() ); + + // Get current state of address, not the old one + SvtUserOptions aUserOptions; + pNewField = new SvxAuthorField( aUserOptions.GetFirstName(), aUserOptions.GetLastName(), aUserOptions.GetID() ); + static_cast<SvxAuthorField*>( pNewField )->SetType( eType ); + static_cast<SvxAuthorField*>( pNewField )->SetFormat( eFormat ); + } + } + + return pNewField; +} + +void SdModifyFieldDlg::FillFormatList() +{ + LanguageType eLangType = m_xLbLanguage->get_active_id(); + + m_xLbFormat->clear(); + + if( auto pDateField = dynamic_cast< const SvxDateField *>( m_pField ) ) + { + SvxDateField aDateField( *pDateField ); + + //SvxDateFormat::AppDefault, // not used + //SvxDateFormat::System, // not used + m_xLbFormat->append_text( SdResId( STR_STANDARD_SMALL ) ); + m_xLbFormat->append_text( SdResId( STR_STANDARD_BIG ) ); + + SvNumberFormatter* pNumberFormatter = SD_MOD()->GetNumberFormatter(); + aDateField.SetFormat( SvxDateFormat::A ); // 13.02.96 + m_xLbFormat->append_text( aDateField.GetFormatted( *pNumberFormatter, eLangType ) ); + aDateField.SetFormat( SvxDateFormat::B ); // 13.02.1996 + m_xLbFormat->append_text( aDateField.GetFormatted( *pNumberFormatter, eLangType ) ); + aDateField.SetFormat( SvxDateFormat::C ); // 13.Feb 1996 + m_xLbFormat->append_text( aDateField.GetFormatted( *pNumberFormatter, eLangType ) ); + aDateField.SetFormat( SvxDateFormat::D ); // 13.Februar 1996 + m_xLbFormat->append_text( aDateField.GetFormatted( *pNumberFormatter, eLangType ) ); + aDateField.SetFormat( SvxDateFormat::E ); // Die, 13.Februar 1996 + m_xLbFormat->append_text( aDateField.GetFormatted( *pNumberFormatter, eLangType ) ); + aDateField.SetFormat( SvxDateFormat::F ); // Dienstag, 13.Februar 1996 + m_xLbFormat->append_text( aDateField.GetFormatted( *pNumberFormatter, eLangType ) ); + + m_xLbFormat->set_active( static_cast<sal_uInt16>(pDateField->GetFormat()) - 2 ); + } + else if( auto pTimeField = dynamic_cast< const SvxExtTimeField *>( m_pField ) ) + { + SvxExtTimeField aTimeField( *pTimeField ); + + //SvxTimeFormat::AppDefault, // not used + //SvxTimeFormat::System, // not used + m_xLbFormat->append_text( SdResId( STR_STANDARD_NORMAL ) ); + + SvNumberFormatter* pNumberFormatter = SD_MOD()->GetNumberFormatter(); + aTimeField.SetFormat( SvxTimeFormat::HH24_MM ); // 13:49 + m_xLbFormat->append_text( aTimeField.GetFormatted( *pNumberFormatter, eLangType ) ); + aTimeField.SetFormat( SvxTimeFormat::HH24_MM_SS ); // 13:49:38 + m_xLbFormat->append_text( aTimeField.GetFormatted( *pNumberFormatter, eLangType ) ); + aTimeField.SetFormat( SvxTimeFormat::HH24_MM_SS_00 ); // 13:49:38.78 + m_xLbFormat->append_text( aTimeField.GetFormatted( *pNumberFormatter, eLangType ) ); + aTimeField.SetFormat( SvxTimeFormat::HH12_MM ); // 01:49 + m_xLbFormat->append_text( aTimeField.GetFormatted( *pNumberFormatter, eLangType ) ); + aTimeField.SetFormat( SvxTimeFormat::HH12_MM_SS ); // 01:49:38 + m_xLbFormat->append_text( aTimeField.GetFormatted( *pNumberFormatter, eLangType ) ); + aTimeField.SetFormat( SvxTimeFormat::HH12_MM_SS_00 ); // 01:49:38.78 + m_xLbFormat->append_text( aTimeField.GetFormatted( *pNumberFormatter, eLangType ) ); + //SvxTimeFormat::HH12_MM_AMPM, // 01:49 PM + //SvxTimeFormat::HH12_MM_SS_AMPM, // 01:49:38 PM + //SvxTimeFormat::HH12_MM_SS_00_AMPM // 01:49:38.78 PM + + m_xLbFormat->set_active( static_cast<sal_uInt16>(pTimeField->GetFormat()) - 2 ); + } + else if( auto pFileField = dynamic_cast< const SvxExtFileField *>( m_pField ) ) + { + m_xLbFormat->append_text( SdResId( STR_FILEFORMAT_NAME_EXT ) ); + m_xLbFormat->append_text( SdResId( STR_FILEFORMAT_FULLPATH ) ); + m_xLbFormat->append_text( SdResId( STR_FILEFORMAT_PATH ) ); + m_xLbFormat->append_text( SdResId( STR_FILEFORMAT_NAME ) ); + + m_xLbFormat->set_active( static_cast<sal_uInt16>( pFileField->GetFormat() ) ); + } + else if( auto pAuthorField = dynamic_cast< const SvxAuthorField *>( m_pField ) ) + { + SvxAuthorField aAuthorField( *pAuthorField ); + + for( sal_uInt16 i = 0; i < 4; i++ ) + { + aAuthorField.SetFormat( static_cast<SvxAuthorFormat>(i) ); + m_xLbFormat->append_text( aAuthorField.GetFormatted() ); + } + + m_xLbFormat->set_active( static_cast<sal_uInt16>( pAuthorField->GetFormat() ) ); + + } + +} + +void SdModifyFieldDlg::FillControls() +{ + m_xLbFormat->clear(); + + if( auto pDateField = dynamic_cast< const SvxDateField *>( m_pField ) ) + { + if( pDateField->GetType() == SvxDateType::Fix ) + m_xRbtFix->set_active(true); + else + m_xRbtVar->set_active(true); + } + else if( auto pTimeField = dynamic_cast< const SvxExtTimeField *>( m_pField ) ) + { + if( pTimeField->GetType() == SvxTimeType::Fix ) + m_xRbtFix->set_active(true); + else + m_xRbtVar->set_active(true); + } + else if( auto pFileField = dynamic_cast< const SvxExtFileField *>( m_pField ) ) + { + if( pFileField->GetType() == SvxFileType::Fix ) + m_xRbtFix->set_active(true); + else + m_xRbtVar->set_active(true); + } + else if( auto pAuthorField = dynamic_cast< const SvxAuthorField *>( m_pField ) ) + { + if( pAuthorField->GetType() == SvxAuthorType::Fix ) + m_xRbtFix->set_active(true); + else + m_xRbtVar->set_active(true); + } + m_xRbtFix->save_state(); + m_xRbtVar->save_state(); + + if( const SvxLanguageItem* pItem = m_aInputSet.GetItemIfSet(EE_CHAR_LANGUAGE ) ) + m_xLbLanguage->set_active_id(pItem->GetLanguage()); + + m_xLbLanguage->save_active_id(); + + FillFormatList(); + m_xLbFormat->save_value(); +} + +IMPL_LINK_NOARG(SdModifyFieldDlg, LanguageChangeHdl, weld::ComboBox&, void) +{ + FillFormatList(); +} + +SfxItemSet SdModifyFieldDlg::GetItemSet() const +{ + SfxItemSet aOutput( *m_aInputSet.GetPool(), svl::Items<EE_CHAR_LANGUAGE, EE_CHAR_LANGUAGE_CTL> ); + + if (m_xLbLanguage->get_active_id_changed_from_saved()) + { + LanguageType eLangType = m_xLbLanguage->get_active_id(); + SvxLanguageItem aItem( eLangType, EE_CHAR_LANGUAGE ); + aOutput.Put( aItem ); + + SvxLanguageItem aItemCJK( eLangType, EE_CHAR_LANGUAGE_CJK ); + aOutput.Put( aItemCJK ); + + SvxLanguageItem aItemCTL( eLangType, EE_CHAR_LANGUAGE_CTL ); + aOutput.Put( aItemCTL ); + } + + return aOutput; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/dlgolbul.cxx b/sd/source/ui/dlg/dlgolbul.cxx new file mode 100644 index 000000000..41c00efa8 --- /dev/null +++ b/sd/source/ui/dlg/dlgolbul.cxx @@ -0,0 +1,172 @@ +/* -*- 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 <memory> +#include <OutlineBulletDlg.hxx> + +#include <svx/svxids.hrc> +#include <editeng/eeitem.hxx> + +#include <editeng/numitem.hxx> + +#include <tools/debug.hxx> +#include <svx/dialogs.hrc> +#include <svx/svdmark.hxx> +#include <View.hxx> +#include <svx/svdobj.hxx> +#include <svl/style.hxx> +#include <svl/intitem.hxx> +#include <drawdoc.hxx> + +#include <strings.hxx> +#include <bulmaper.hxx> +#include <DrawDocShell.hxx> + +namespace sd { + +/** + * Constructor of tab dialog: append pages to the dialog + */ +OutlineBulletDlg::OutlineBulletDlg(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView) + : SfxTabDialogController(pParent, "modules/sdraw/ui/bulletsandnumbering.ui", "BulletsAndNumberingDialog") + , m_aInputSet(*pAttr) + , m_bTitle(false) + , m_pSdView(pView) +{ + m_aInputSet.MergeRange(SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL); + m_aInputSet.Put(*pAttr); + + m_xOutputSet.reset( new SfxItemSet( *pAttr ) ); + m_xOutputSet->ClearItem(); + + bool bOutliner = false; + + // special treatment if a title object is selected + if (pView) + { + const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); + const size_t nCount = rMarkList.GetMarkCount(); + for(size_t nNum = 0; nNum < nCount; ++nNum) + { + SdrObject* pObj = rMarkList.GetMark(nNum)->GetMarkedSdrObj(); + if( pObj->GetObjInventor() == SdrInventor::Default ) + { + switch(pObj->GetObjIdentifier()) + { + case SdrObjKind::TitleText: + m_bTitle = true; + break; + case SdrObjKind::OutlineText: + bOutliner = true; + break; + default: + break; + } + } + } + } + + if( SfxItemState::SET != m_aInputSet.GetItemState(EE_PARA_NUMBULLET)) + { + const SvxNumBulletItem *pItem = nullptr; + if(bOutliner) + { + SfxStyleSheetBasePool* pSSPool = pView->GetDocSh()->GetStyleSheetPool(); + SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( STR_LAYOUT_OUTLINE + " 1", SfxStyleFamily::Pseudo); + if( pFirstStyleSheet ) + pItem = pFirstStyleSheet->GetItemSet().GetItemIfSet(EE_PARA_NUMBULLET, false); + } + + if( pItem == nullptr ) + pItem = m_aInputSet.GetPool()->GetSecondaryPool()->GetPoolDefaultItem(EE_PARA_NUMBULLET); + + DBG_ASSERT( pItem, "No EE_PARA_NUMBULLET in Pool! [CL]" ); + + m_aInputSet.Put(pItem->CloneSetWhich(EE_PARA_NUMBULLET)); + } + + if (m_bTitle && m_aInputSet.GetItemState(EE_PARA_NUMBULLET) == SfxItemState::SET ) + { + const SvxNumBulletItem* pItem = m_aInputSet.GetItem<SvxNumBulletItem>(EE_PARA_NUMBULLET); + const SvxNumRule& rRule = pItem->GetNumRule(); + SvxNumRule aNewRule( rRule ); + aNewRule.SetFeatureFlag( SvxNumRuleFlags::NO_NUMBERS ); + + SvxNumBulletItem aNewItem( std::move(aNewRule), EE_PARA_NUMBULLET ); + m_aInputSet.Put(aNewItem); + } + + SetInputSet(&m_aInputSet); + + if (m_bTitle) + RemoveTabPage("singlenum"); + + AddTabPage("customize", RID_SVXPAGE_NUM_OPTIONS); + AddTabPage("position", RID_SVXPAGE_NUM_POSITION); +} + +OutlineBulletDlg::~OutlineBulletDlg() +{ +} + +void OutlineBulletDlg::PageCreated(const OString& rId, SfxTabPage &rPage) +{ + if (!m_pSdView) + return; + if (rId == "customize") + { + FieldUnit eMetric = m_pSdView->GetDoc().GetUIUnit(); + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + aSet.Put ( SfxUInt16Item(SID_METRIC_ITEM,static_cast<sal_uInt16>(eMetric))); + rPage.PageCreated(aSet); + } + else if (rId == "position") + { + FieldUnit eMetric = m_pSdView->GetDoc().GetUIUnit(); + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + aSet.Put ( SfxUInt16Item(SID_METRIC_ITEM,static_cast<sal_uInt16>(eMetric))); + rPage.PageCreated(aSet); + } +} + +const SfxItemSet* OutlineBulletDlg::GetBulletOutputItemSet() const +{ + SfxItemSet aSet(*GetOutputItemSet()); + m_xOutputSet->Put(aSet); + + const SfxPoolItem *pItem = nullptr; + if( SfxItemState::SET == m_xOutputSet->GetItemState(m_xOutputSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE), false, &pItem )) + { + SdBulletMapper::MapFontsInNumRule(const_cast<SvxNumRule&>(static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()), *m_xOutputSet); + // #i35937 - removed EE_PARA_BULLETSTATE setting + } + + if (m_bTitle && m_xOutputSet->GetItemState(EE_PARA_NUMBULLET) == SfxItemState::SET) + { + const SvxNumBulletItem* pBulletItem = m_xOutputSet->GetItem<SvxNumBulletItem>(EE_PARA_NUMBULLET); + SvxNumRule& rRule = const_cast<SvxNumRule&>(pBulletItem->GetNumRule()); + rRule.SetFeatureFlag( SvxNumRuleFlags::NO_NUMBERS, false ); + } + + return m_xOutputSet.get(); +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/dlgpage.cxx b/sd/source/ui/dlg/dlgpage.cxx new file mode 100644 index 000000000..e3bc5978b --- /dev/null +++ b/sd/source/ui/dlg/dlgpage.cxx @@ -0,0 +1,116 @@ +/* -*- 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 <svl/intitem.hxx> +#include <svx/dialogs.hrc> +#include <svx/svxids.hrc> +#include <svx/drawitem.hxx> +#include <i18nutil/paper.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/sfxdlg.hxx> + +#include <dlgpage.hxx> +#include <sdresid.hxx> +#include <strings.hrc> + +#include <svl/eitem.hxx> +#include <svx/flagsdef.hxx> + +/** + * Constructor of tab dialog: appends pages to the dialog + */ +SdPageDlg::SdPageDlg(SfxObjectShell const* pDocSh, weld::Window* pParent, const SfxItemSet* pAttr, + bool bAreaPage, bool bIsImpressDoc, bool bIsImpressMaster) + : SfxTabDialogController(pParent, "modules/sdraw/ui/drawpagedialog.ui", "DrawPageDialog", pAttr) + , mbIsImpressDoc(bIsImpressDoc) +{ + SvxColorListItem const* pColorListItem = pDocSh->GetItem(SID_COLOR_TABLE); + SvxGradientListItem const* pGradientListItem = pDocSh->GetItem(SID_GRADIENT_LIST); + SvxBitmapListItem const* pBitmapListItem = pDocSh->GetItem(SID_BITMAP_LIST); + SvxPatternListItem const* pPatternListItem = pDocSh->GetItem(SID_PATTERN_LIST); + SvxHatchListItem const* pHatchListItem = pDocSh->GetItem(SID_HATCH_LIST); + + mpColorList = pColorListItem->GetColorList(); + mpGradientList = pGradientListItem->GetGradientList(); + mpHatchingList = pHatchListItem->GetHatchList(); + mpBitmapList = pBitmapListItem->GetBitmapList(); + mpPatternList = pPatternListItem->GetPatternList(); + + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + + AddTabPage("RID_SVXPAGE_PAGE", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_PAGE), nullptr); + AddTabPage("RID_SVXPAGE_AREA", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_AREA), nullptr); + AddTabPage("RID_SVXPAGE_TRANSPARENCE", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_TRANSPARENCE), + nullptr); + AddTabPage("RID_SVXPAGE_THEME", pFact->GetTabPageCreatorFunc(RID_SVXPAGE_THEME), nullptr); + + if (!bAreaPage) // I have to add the page before I remove it ! + { + RemoveTabPage("RID_SVXPAGE_AREA"); + RemoveTabPage("RID_SVXPAGE_TRANSPARENCE"); + } + + if (!bIsImpressMaster) + { + // Only slide masters can have a theme. + RemoveTabPage("RID_SVXPAGE_THEME"); + } + + if (mbIsImpressDoc) + { + set_title(SdResId(STR_SLIDE_SETUP_TITLE)); + m_xTabCtrl->set_tab_label_text("RID_SVXPAGE_PAGE", SdResId(STR_SLIDE_NAME)); + } +} + +void SdPageDlg::PageCreated(const OString& rId, SfxTabPage& rPage) +{ + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + if (rId == "RID_SVXPAGE_PAGE") + { + aSet.Put(SfxUInt16Item(sal_uInt16(SID_ENUM_PAGE_MODE), SVX_PAGE_MODE_PRESENTATION)); + aSet.Put(SfxUInt16Item(SID_PAPER_START, PAPER_A0)); + aSet.Put(SfxUInt16Item(SID_PAPER_END, PAPER_E)); + + if (mbIsImpressDoc) + aSet.Put(SfxBoolItem(SID_IMPRESS_DOC, true)); + + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_AREA") + { + aSet.Put(SvxColorListItem(mpColorList, SID_COLOR_TABLE)); + aSet.Put(SvxGradientListItem(mpGradientList, SID_GRADIENT_LIST)); + aSet.Put(SvxHatchListItem(mpHatchingList, SID_HATCH_LIST)); + aSet.Put(SvxBitmapListItem(mpBitmapList, SID_BITMAP_LIST)); + aSet.Put(SvxPatternListItem(mpPatternList, SID_PATTERN_LIST)); + aSet.Put(SfxUInt16Item(SID_PAGE_TYPE, 0)); + aSet.Put(SfxUInt16Item(SID_DLG_TYPE, 1)); + aSet.Put(SfxUInt16Item(SID_TABPAGE_POS, 0)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_TRANSPARENCE") + { + aSet.Put(SfxUInt16Item(SID_PAGE_TYPE, 0)); + aSet.Put(SfxUInt16Item(SID_DLG_TYPE, 1)); + rPage.PageCreated(aSet); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/dlgsnap.cxx b/sd/source/ui/dlg/dlgsnap.cxx new file mode 100644 index 000000000..9b1383089 --- /dev/null +++ b/sd/source/ui/dlg/dlgsnap.cxx @@ -0,0 +1,185 @@ +/* -*- 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 <svx/svxids.hrc> +#include <svx/svdpagv.hxx> +#include <svl/intitem.hxx> +#include <svl/itempool.hxx> +#include <svtools/unitconv.hxx> +#include <tools/debug.hxx> + +#include <sdattr.hrc> +#include <View.hxx> +#include <drawdoc.hxx> +#include <dlgsnap.hxx> +#include <sdenumdef.hxx> + +/** + * dialog to adjust grid (scarcely ESO!) + */ +SdSnapLineDlg::SdSnapLineDlg(weld::Window* pWindow, const SfxItemSet& rInAttrs, ::sd::View const * pView) + : GenericDialogController(pWindow, "modules/sdraw/ui/dlgsnap.ui", "SnapObjectDialog") + , aUIScale(pView->GetDoc().GetUIScale()) + , m_xFtX(m_xBuilder->weld_label("xlabel")) + , m_xMtrFldX(m_xBuilder->weld_metric_spin_button("x", FieldUnit::CM)) + , m_xFtY(m_xBuilder->weld_label("ylabel")) + , m_xMtrFldY(m_xBuilder->weld_metric_spin_button("y", FieldUnit::CM)) + , m_xRadioGroup(m_xBuilder->weld_widget("radiogroup")) + , m_xRbPoint(m_xBuilder->weld_radio_button("point")) + , m_xRbVert(m_xBuilder->weld_radio_button("vert")) + , m_xRbHorz(m_xBuilder->weld_radio_button("horz")) + , m_xBtnDelete(m_xBuilder->weld_button("delete")) +{ + m_xRbHorz->connect_toggled(LINK(this, SdSnapLineDlg, ToggleHdl)); + m_xRbVert->connect_toggled(LINK(this, SdSnapLineDlg, ToggleHdl)); + m_xRbPoint->connect_toggled(LINK(this, SdSnapLineDlg, ToggleHdl)); + + m_xBtnDelete->connect_clicked(LINK(this, SdSnapLineDlg, ClickHdl)); + + FieldUnit eUIUnit = pView->GetDoc().GetUIUnit(); + SetFieldUnit(*m_xMtrFldX, eUIUnit, true); + SetFieldUnit(*m_xMtrFldY, eUIUnit, true); + + // get WorkArea + ::tools::Rectangle aWorkArea = pView->GetWorkArea(); + + // determine PoolUnit + SfxItemPool* pPool = rInAttrs.GetPool(); + DBG_ASSERT( pPool, "Where's the Pool?" ); + MapUnit ePoolUnit = pPool->GetMetric( SID_ATTR_FILL_HATCH ); + + // #i48497# Consider page origin + SdrPageView* pPV = pView->GetSdrPageView(); + Point aLeftTop(aWorkArea.Left()+1, aWorkArea.Top()+1); + pPV->LogicToPagePos(aLeftTop); + Point aRightBottom(aWorkArea.Right()-2, aWorkArea.Bottom()-2); + pPV->LogicToPagePos(aRightBottom); + + // determine max and min values depending on + // WorkArea, PoolUnit and FieldUnit: + auto const map = [ePoolUnit](std::unique_ptr<weld::MetricSpinButton> const & msb, tools::Long value) { + auto const n1 = OutputDevice::LogicToLogic(value, ePoolUnit, MapUnit::Map100thMM); + auto const n2 = msb->normalize(n1); + auto const n3 = msb->convert_value_from(n2, FieldUnit::MM_100TH); + auto const n4 = msb->convert_value_to(n3, FieldUnit::NONE); + return n4; + }; + m_xMtrFldX->set_range(map(m_xMtrFldX, sal_Int32(aLeftTop.X() / aUIScale)), + map(m_xMtrFldX, sal_Int32(aRightBottom.X() / aUIScale)), + FieldUnit::NONE); + m_xMtrFldY->set_range(map(m_xMtrFldY, sal_Int32(aLeftTop.Y() / aUIScale)), + map(m_xMtrFldY, sal_Int32(aRightBottom.Y() / aUIScale)), + FieldUnit::NONE); + + // set values + nXValue = static_cast<const SfxInt32Item&>( rInAttrs.Get(ATTR_SNAPLINE_X)).GetValue(); + nYValue = static_cast<const SfxInt32Item&>( rInAttrs.Get(ATTR_SNAPLINE_Y)).GetValue(); + nXValue = sal_Int32(nXValue / aUIScale); + nYValue = sal_Int32(nYValue / aUIScale); + SetMetricValue(*m_xMtrFldX, nXValue, MapUnit::Map100thMM); + SetMetricValue(*m_xMtrFldY, nYValue, MapUnit::Map100thMM); + + m_xRbPoint->set_active(true); +} + +SdSnapLineDlg::~SdSnapLineDlg() +{ +} + +/** + * fills provided item sets with dialog box attributes + */ +IMPL_LINK(SdSnapLineDlg, ToggleHdl, weld::Toggleable&, rBtn, void) +{ + if (!rBtn.get_active()) + return; + if (m_xRbPoint->get_active()) + SetInputFields(true, true); + else if (m_xRbHorz->get_active()) + SetInputFields(false, true); + else if (m_xRbVert->get_active()) + SetInputFields(true, false); +} + +IMPL_LINK( SdSnapLineDlg, ClickHdl, weld::Button&, rBtn, void ) +{ + if (&rBtn == m_xBtnDelete.get()) + m_xDialog->response(RET_SNAP_DELETE); +} + +/** + * fills provided item sets with dialog box attributes + */ +void SdSnapLineDlg::GetAttr(SfxItemSet& rOutAttrs) +{ + SnapKind eKind; + + if (m_xRbHorz->get_active()) eKind = SnapKind::Horizontal; + else if (m_xRbVert->get_active()) eKind = SnapKind::Vertical; + else eKind = SnapKind::Point; + + nXValue = sal_Int32(GetCoreValue(*m_xMtrFldX, MapUnit::Map100thMM) * aUIScale); + nYValue = sal_Int32(GetCoreValue(*m_xMtrFldY, MapUnit::Map100thMM) * aUIScale); + + rOutAttrs.Put(SfxUInt16Item(ATTR_SNAPLINE_KIND, static_cast<sal_uInt16>(eKind))); + rOutAttrs.Put(SfxInt32Item(ATTR_SNAPLINE_X, nXValue)); + rOutAttrs.Put(SfxInt32Item(ATTR_SNAPLINE_Y, nYValue)); +} + +void SdSnapLineDlg::HideRadioGroup() +{ + m_xRadioGroup->hide(); +} + +/** + * disable X or Y input fields + */ +void SdSnapLineDlg::SetInputFields(bool bEnableX, bool bEnableY) +{ + if ( bEnableX ) + { + if (!m_xMtrFldX->get_sensitive()) + m_xMtrFldX->set_value(nXValue, FieldUnit::NONE); + m_xMtrFldX->set_sensitive(true); + m_xFtX->set_sensitive(true); + } + else if (m_xMtrFldX->get_sensitive()) + { + nXValue = m_xMtrFldX->get_value(FieldUnit::NONE); + m_xMtrFldX->set_text(OUString()); + m_xMtrFldX->set_sensitive(false); + m_xFtX->set_sensitive(false); + } + if ( bEnableY ) + { + if (!m_xMtrFldY->get_sensitive()) + m_xMtrFldY->set_value(nYValue, FieldUnit::NONE); + m_xMtrFldY->set_sensitive(true); + m_xFtY->set_sensitive(true); + } + else if (m_xMtrFldY->get_sensitive()) + { + nYValue = m_xMtrFldY->get_value(FieldUnit::NONE); + m_xMtrFldY->set_text(OUString()); + m_xMtrFldY->set_sensitive(false); + m_xFtY->set_sensitive(false); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/filedlg.cxx b/sd/source/ui/dlg/filedlg.cxx new file mode 100644 index 000000000..b2087c408 --- /dev/null +++ b/sd/source/ui/dlg/filedlg.cxx @@ -0,0 +1,267 @@ +/* -*- 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 <config_features.h> + +#include <com/sun/star/media/XPlayer.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker3.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/FilePickerEvent.hpp> +#include <vcl/idle.hxx> +#include <osl/diagnose.h> +#include <vcl/svapp.hxx> +#include <sfx2/filedlghelper.hxx> +#include <avmedia/mediawindow.hxx> +#include <filedlg.hxx> +#include <sdresid.hxx> +#include <strings.hrc> + +// ----------- SdFileDialog_Imp --------------------------- + +class SdFileDialog_Imp : public sfx2::FileDialogHelper +{ +private: + friend class SdOpenSoundFileDialog; + + css::uno::Reference< css::ui::dialogs::XFilePickerControlAccess > mxControlAccess; + + css::uno::Reference< css::media::XPlayer > mxPlayer; + ImplSVEvent * mnPlaySoundEvent; + bool mbLabelPlaying; + Idle maUpdateIdle; + + DECL_LINK( PlayMusicHdl, void *, void ); + DECL_LINK( IsMusicStoppedHdl, Timer *, void ); + +public: + explicit SdFileDialog_Imp(weld::Window *pParent); + virtual ~SdFileDialog_Imp() override; + + // overwritten from FileDialogHelper, to receive user feedback + virtual void ControlStateChanged( const css::ui::dialogs::FilePickerEvent& aEvent ) override; +}; + +void SdFileDialog_Imp::ControlStateChanged( const css::ui::dialogs::FilePickerEvent& aEvent ) +{ + SolarMutexGuard aGuard; + + switch( aEvent.ElementId ) + { + case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY: + if( mxControlAccess.is() ) + { + if( mnPlaySoundEvent ) + Application::RemoveUserEvent( mnPlaySoundEvent ); + + mnPlaySoundEvent = Application::PostUserEvent( LINK( this, SdFileDialog_Imp, PlayMusicHdl ) ); + } + break; + } +} + +IMPL_LINK_NOARG(SdFileDialog_Imp, PlayMusicHdl, void*, void) +{ + maUpdateIdle.Stop(); + mnPlaySoundEvent = nullptr; + + if (mxPlayer.is()) + { + if (mxPlayer->isPlaying()) + mxPlayer->stop(); + mxPlayer.clear(); + } + +#if HAVE_FEATURE_AVMEDIA + if( mbLabelPlaying ) + { + try + { + mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, + SdResId( STR_PLAY ) ); + mbLabelPlaying = false; + } + catch(const css::lang::IllegalArgumentException&) + { +#ifdef DBG_UTIL + OSL_FAIL( "Cannot access play button" ); +#endif + } + } + else + { + OUString aUrl( GetPath() ); + if ( !aUrl.isEmpty() ) + { + try + { + mxPlayer.set( avmedia::MediaWindow::createPlayer( aUrl, "" ), css::uno::UNO_SET_THROW ); + mxPlayer->start(); + maUpdateIdle.Start(); + } + catch (const css::uno::Exception&) + { + mxPlayer.clear(); + } + + if (mxPlayer.is()) + { + try + { + mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, + SdResId( STR_STOP ) ); + mbLabelPlaying = true; + } + catch (const css::lang::IllegalArgumentException&) + { +#ifdef DBG_UTIL + OSL_FAIL( "Cannot access play button" ); +#endif + } + } + } + } +#endif +} + +IMPL_LINK_NOARG(SdFileDialog_Imp, IsMusicStoppedHdl, Timer *, void) +{ + SolarMutexGuard aGuard; + + if (mxPlayer.is() && mxPlayer->isPlaying() && + mxPlayer->getMediaTime() < mxPlayer->getDuration()) + { + maUpdateIdle.Start(); + return; + } + + if( !mxControlAccess.is() ) + return; + + try + { + mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, + SdResId( STR_PLAY ) ); + mbLabelPlaying = false; + } + catch (const css::lang::IllegalArgumentException&) + { +#ifdef DBG_UTIL + OSL_FAIL( "Cannot access play button" ); +#endif + } +} + +SdFileDialog_Imp::SdFileDialog_Imp(weld::Window* pParent) + : FileDialogHelper(css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY, FileDialogFlags::NONE, pParent) + , mnPlaySoundEvent(nullptr) + , mbLabelPlaying(false) + , maUpdateIdle( "SdFileDialog_Imp maUpdateIdle" ) +{ + maUpdateIdle.SetInvokeHandler(LINK(this, SdFileDialog_Imp, IsMusicStoppedHdl)); + + css::uno::Reference < css::ui::dialogs::XFilePicker3 > xFileDlg = GetFilePicker(); + + // get the control access + mxControlAccess.set( xFileDlg, css::uno::UNO_QUERY ); + + if( !mxControlAccess.is() ) + return; + + try + { + mxControlAccess->setLabel( css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, + SdResId( STR_PLAY ) ); + } + catch (const css::lang::IllegalArgumentException&) + { +#ifdef DBG_UTIL + OSL_FAIL( "Cannot set play button label" ); +#endif + } +} + +SdFileDialog_Imp::~SdFileDialog_Imp() +{ + if( mnPlaySoundEvent ) + Application::RemoveUserEvent( mnPlaySoundEvent ); +} + +// ----------- SdOpenSoundFileDialog ----------------------- + +// these are simple forwarders +SdOpenSoundFileDialog::SdOpenSoundFileDialog(weld::Window *pParent) + : mpImpl(new SdFileDialog_Imp(pParent)) +{ + OUString aDescr = SdResId(STR_ALL_FILES); + mpImpl->AddFilter( aDescr, "*.*"); + mpImpl->SetContext(sfx2::FileDialogHelper::DrawImpressOpenSound); + + // setup filter +#if defined UNX + aDescr = SdResId(STR_AU_FILE); + mpImpl->AddFilter( aDescr, "*.au;*.snd"); + aDescr = SdResId(STR_VOC_FILE); + mpImpl->AddFilter( aDescr, "*.voc"); + aDescr = SdResId(STR_WAV_FILE); + mpImpl->AddFilter( aDescr, "*.wav"); + aDescr = SdResId(STR_AIFF_FILE); + mpImpl->AddFilter( aDescr, "*.aiff"); + aDescr = SdResId(STR_SVX_FILE); + mpImpl->AddFilter( aDescr, "*.svx"); +#else + aDescr = SdResId(STR_WAV_FILE); + mpImpl->AddFilter( aDescr, "*.wav;*.mp3;*.ogg" ); + aDescr = SdResId(STR_MIDI_FILE); + mpImpl->AddFilter( aDescr, "*.mid" ); +#endif +} + +SdOpenSoundFileDialog::~SdOpenSoundFileDialog() +{ +} + +ErrCode SdOpenSoundFileDialog::Execute() +{ + return mpImpl->Execute(); +} + +OUString SdOpenSoundFileDialog::GetPath() const +{ + return mpImpl->GetPath(); +} + +void SdOpenSoundFileDialog::SetPath( const OUString& rPath ) +{ + mpImpl->SetDisplayDirectory( rPath ); +} + +// WIP, please don't remove, dear Clang plugins +bool SdOpenSoundFileDialog::IsInsertAsLinkSelected() const +{ + bool bInsertAsLinkSelected = false; + css::uno::Reference<css::ui::dialogs::XFilePicker3> const xFilePicker(mpImpl->GetFilePicker()); + css::uno::Reference<css::ui::dialogs::XFilePickerControlAccess> const xControlAccess(xFilePicker, css::uno::UNO_QUERY_THROW); + xControlAccess->getValue(css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bInsertAsLinkSelected; + return bInsertAsLinkSelected; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/gluectrl.cxx b/sd/source/ui/dlg/gluectrl.cxx new file mode 100644 index 000000000..a6baf3e92 --- /dev/null +++ b/sd/source/ui/dlg/gluectrl.cxx @@ -0,0 +1,200 @@ +/* -*- 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 <sal/config.h> + +#include <comphelper/propertyvalue.hxx> +#include <svx/svdglue.hxx> +#include <svl/intitem.hxx> +#include <vcl/toolbox.hxx> + +#include <strings.hrc> +#include <gluectrl.hxx> +#include <sdresid.hxx> +#include <app.hrc> + +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XFrame.hpp> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; + +// at the moment, Joe only supports the methods specified below +#define ESCDIR_COUNT 5 +const SdrEscapeDirection aEscDirArray[] = +{ + SdrEscapeDirection::SMART, + SdrEscapeDirection::LEFT, + SdrEscapeDirection::RIGHT, + SdrEscapeDirection::TOP, + SdrEscapeDirection::BOTTOM +}; + +SFX_IMPL_TOOLBOX_CONTROL( SdTbxCtlGlueEscDir, SfxUInt16Item ) + +/** + * Constructor for gluepoint escape direction Listbox + */ +GlueEscDirLB::GlueEscDirLB(vcl::Window* pParent, const Reference<XFrame>& rFrame) + : InterimItemWindow(pParent, "modules/simpress/ui/gluebox.ui", "GlueBox") + , m_xFrame(rFrame) + , m_xWidget(m_xBuilder->weld_combo_box("gluetype")) +{ + InitControlBase(m_xWidget.get()); + + Fill(); + + m_xWidget->connect_changed(LINK(this, GlueEscDirLB, SelectHdl)); + m_xWidget->connect_key_press(LINK(this, GlueEscDirLB, KeyInputHdl)); + + SetSizePixel(m_xWidget->get_preferred_size()); + + Show(); +} + +void GlueEscDirLB::dispose() +{ + m_xWidget.reset(); + InterimItemWindow::dispose(); +} + +GlueEscDirLB::~GlueEscDirLB() +{ + disposeOnce(); +} + +void GlueEscDirLB::set_sensitive(bool bSensitive) +{ + Enable(bSensitive); + m_xWidget->set_sensitive(bSensitive); +} + +IMPL_LINK(GlueEscDirLB, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + return ChildKeyInput(rKEvt); +} + +/** + * Determines the escape direction and sends the corresponding slot + */ +IMPL_LINK(GlueEscDirLB, SelectHdl, weld::ComboBox&, rBox, void) +{ + sal_Int32 nPos = rBox.get_active(); + SfxUInt16Item aItem( SID_GLUE_ESCDIR, static_cast<sal_uInt16>(aEscDirArray[ nPos ]) ); + + if ( m_xFrame.is() ) + { + Any a; + aItem.QueryValue( a ); + Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue("GlueEscapeDirection", a) }; + SfxToolBoxControl::Dispatch( Reference< XDispatchProvider >( m_xFrame->getController(), UNO_QUERY ), + ".uno:GlueEscapeDirection", + aArgs ); + } +} + +/** + * Fills the Listbox with strings + */ +void GlueEscDirLB::Fill() +{ + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_SMART ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_LEFT ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_RIGHT ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_TOP ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_BOTTOM ) ); + /* + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_LO ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_LU ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_RO ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_RU ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_HORZ ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_VERT ) ); + m_xWidget->append_text( SdResId( STR_GLUE_ESCDIR_ALL ) ); + */ +} + +/** + * Constructor for gluepoint escape direction toolbox control + */ +SdTbxCtlGlueEscDir::SdTbxCtlGlueEscDir( + sal_uInt16 nSlotId, ToolBoxItemId nId, ToolBox& rTbx ) : + SfxToolBoxControl( nSlotId, nId, rTbx ) +{ +} + +/** + * Represents state in the listbox of the controller + */ +void SdTbxCtlGlueEscDir::StateChangedAtToolBoxControl( sal_uInt16 nSId, + SfxItemState eState, const SfxPoolItem* pState ) +{ + if( eState == SfxItemState::DEFAULT ) + { + GlueEscDirLB* pGlueEscDirLB = static_cast<GlueEscDirLB*> ( GetToolBox(). + GetItemWindow( GetId() ) ); + if( pGlueEscDirLB ) + { + if( pState ) + { + pGlueEscDirLB->set_sensitive(true); + if ( IsInvalidItem( pState ) ) + { + pGlueEscDirLB->set_active(-1); + } + else + { + SdrEscapeDirection nEscDir = static_cast<SdrEscapeDirection>(static_cast<const SfxUInt16Item*>( pState )->GetValue()); + pGlueEscDirLB->set_active( GetEscDirPos( nEscDir ) ); + } + } + else + { + pGlueEscDirLB->set_sensitive(false); + pGlueEscDirLB->set_active(-1); + } + } + } + + SfxToolBoxControl::StateChangedAtToolBoxControl( nSId, eState, pState ); +} + +VclPtr<InterimItemWindow> SdTbxCtlGlueEscDir::CreateItemWindow( vcl::Window *pParent ) +{ + if( GetSlotId() == SID_GLUE_ESCDIR ) + return VclPtr<GlueEscDirLB>::Create( pParent, m_xFrame ).get(); + + return VclPtr<InterimItemWindow>(); +} + +/** + * Returns position in the array for EscDir (Mapping for Listbox) + */ +sal_uInt16 SdTbxCtlGlueEscDir::GetEscDirPos( SdrEscapeDirection nEscDir ) +{ + for( sal_uInt16 i = 0; i < ESCDIR_COUNT; i++ ) + { + if( aEscDirArray[ i ] == nEscDir ) + return i; + } + return 99; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/headerfooterdlg.cxx b/sd/source/ui/dlg/headerfooterdlg.cxx new file mode 100644 index 000000000..703f2f598 --- /dev/null +++ b/sd/source/ui/dlg/headerfooterdlg.cxx @@ -0,0 +1,759 @@ +/* -*- 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 <editeng/eeitem.hxx> +#include <editeng/flditem.hxx> +#include <editeng/langitem.hxx> +#include <svx/langbox.hxx> +#include <svx/svdotext.hxx> +#include <editeng/editeng.hxx> +#include <editeng/outlobj.hxx> +#include <sfx2/viewfrm.hxx> +#include <tools/debug.hxx> + +#include <Outliner.hxx> +#include <headerfooterdlg.hxx> +#include <DrawDocShell.hxx> +#include <drawdoc.hxx> +#include <ViewShell.hxx> +#include <sdmod.hxx> + +// preview control for presentation layout +#include <tools/color.hxx> +#include <i18nlangtag/mslangid.hxx> +#include <svtools/colorcfg.hxx> +#include <vcl/customweld.hxx> +#include <vcl/decoview.hxx> +#include <vcl/svapp.hxx> + +#include <undoheaderfooter.hxx> +#include <sdundogr.hxx> + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> + +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<weld::Builder> mxBuilder; + std::unique_ptr<weld::Container> mxContainer; + std::unique_ptr<weld::Label> mxFTIncludeOn; + std::unique_ptr<weld::CheckButton> mxCBHeader; + std::unique_ptr<weld::Widget> mxHeaderBox; + std::unique_ptr<weld::Entry> mxTBHeader; + std::unique_ptr<weld::CheckButton> mxCBDateTime; + std::unique_ptr<weld::RadioButton> mxRBDateTimeFixed; + std::unique_ptr<weld::RadioButton> mxRBDateTimeAutomatic; + std::unique_ptr<weld::Entry> mxTBDateTimeFixed; + std::unique_ptr<weld::ComboBox> mxCBDateTimeFormat; + std::unique_ptr<weld::Label> mxFTDateTimeLanguage; + std::unique_ptr<SvxLanguageBox> mxCBDateTimeLanguage; + std::unique_ptr<weld::CheckButton> mxCBFooter; + std::unique_ptr<weld::Widget> mxFooterBox; + std::unique_ptr<weld::Entry> mxTBFooter; + std::unique_ptr<weld::CheckButton> mxCBSlideNumber; + std::unique_ptr<weld::CheckButton> mxCBNotOnTitle; + std::unique_ptr<weld::Label> mxReplacementA; + std::unique_ptr<weld::Label> mxReplacementB; + std::unique_ptr<PresLayoutPreview> mxCTPreview; + std::unique_ptr<weld::CustomWeld> 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<SdPage*>(pDoc->GetPage( pCurrentPage->GetPageNum() + 1 )); + } + else if( pCurrentPage->GetPageKind() == PageKind::Notes ) + { + pNotes = pCurrentPage; + pSlide = static_cast<SdPage*>(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<SdUndoGroup> 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<sal_uInt16>(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<sal_uInt16>(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<SdPage*>(&(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<SdrTextObj*>(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<const SvxDateTimeField*>(pFieldData) != nullptr || + dynamic_cast<const SvxDateField*>(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<double>(maOutRect.getWidth()) / static_cast<double>(maPageSize.Width())); + const double fScaleY(static_cast<double>(maOutRect.getHeight()) / static_cast<double>(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<double> 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<double>(nWidth * maPageSize.Height()) / static_cast<double>(maPageSize.Width()) ); + } + else + { + nHeight = maOutRect.GetHeight(); + nWidth = maPageSize.Height() == 0 ? 0 : tools::Long( static_cast<double>(nHeight * maPageSize.Width()) / static_cast<double>(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<SdrTextObj*>(mpMaster->GetPresObj(PresObjKind::Title)); + SdrTextObj* pMasterOutline = static_cast<SdrTextObj*>(mpMaster->GetPresObj(mpMaster->GetPageKind() == PageKind::Notes ? PresObjKind::Notes : PresObjKind::Outline)); + SdrTextObj* pHeader = static_cast<SdrTextObj*>(mpMaster->GetPresObj(PresObjKind::Header)); + SdrTextObj* pFooter = static_cast<SdrTextObj*>(mpMaster->GetPresObj(PresObjKind::Footer)); + SdrTextObj* pDate = static_cast<SdrTextObj*>(mpMaster->GetPresObj(PresObjKind::DateTime)); + SdrTextObj* pNumber = static_cast<SdrTextObj*>(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: */ diff --git a/sd/source/ui/dlg/ins_paste.cxx b/sd/source/ui/dlg/ins_paste.cxx new file mode 100644 index 000000000..f1020c0cb --- /dev/null +++ b/sd/source/ui/dlg/ins_paste.cxx @@ -0,0 +1,34 @@ +/* -*- 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 <ins_paste.hxx> + +SdInsertPasteDlg::SdInsertPasteDlg(weld::Window* pWindow) + : GenericDialogController(pWindow, "modules/simpress/ui/insertslides.ui", "InsertSlidesDialog") + , m_xRbBefore(m_xBuilder->weld_radio_button("before")) + , m_xRbAfter(m_xBuilder->weld_radio_button("after")) +{ + m_xRbAfter->set_active(true); +} + +SdInsertPasteDlg::~SdInsertPasteDlg() {} + +bool SdInsertPasteDlg::IsInsertBefore() const { return m_xRbBefore->get_active(); } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/inspagob.cxx b/sd/source/ui/dlg/inspagob.cxx new file mode 100644 index 000000000..5c984dd23 --- /dev/null +++ b/sd/source/ui/dlg/inspagob.cxx @@ -0,0 +1,126 @@ +/* -*- 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 <inspagob.hxx> +#include <sdtreelb.hxx> + +#include <strings.hrc> + +#include <bitmaps.hlst> +#include <sdresid.hxx> +#include <drawdoc.hxx> +#include <DrawDocShell.hxx> +#include <ViewShell.hxx> + +SdInsertPagesObjsDlg::SdInsertPagesObjsDlg( + weld::Window* pWindow, const SdDrawDocument* pInDoc, + SfxMedium* pSfxMedium, const OUString& rFileName ) + : GenericDialogController(pWindow, "modules/sdraw/ui/insertslidesdialog.ui", "InsertSlidesDialog") + , m_pMedium(pSfxMedium) + , m_pDoc(pInDoc) + , m_rName(rFileName) + , m_xLbTree(new SdPageObjsTLV(m_xBuilder->weld_tree_view("tree"))) + , m_xCbxLink(m_xBuilder->weld_check_button("links")) + , m_xCbxMasters(m_xBuilder->weld_check_button("backgrounds")) +{ + m_xLbTree->set_size_request(m_xLbTree->get_approximate_digit_width() * 48, + m_xLbTree->get_height_rows(12)); + + m_xLbTree->SetViewFrame( pInDoc->GetDocSh()->GetViewShell()->GetViewFrame() ); + + m_xLbTree->connect_changed(LINK(this, SdInsertPagesObjsDlg, SelectObjectHdl)); + + // insert text + if (!m_pMedium) + m_xDialog->set_title(SdResId(STR_INSERT_TEXT)); + else if (m_pDoc && m_pDoc->GetDocumentType() == DocumentType::Draw) + m_xDialog->set_title(SdResId(STR_INSERT_PAGES)); + + Reset(); +} + +SdInsertPagesObjsDlg::~SdInsertPagesObjsDlg() +{ +} + +/** + * Fills the TreeLB dependent on the medium. Is not medium available, then + * it is a text and not a draw document. + */ +void SdInsertPagesObjsDlg::Reset() +{ + if( m_pMedium ) + { + m_xLbTree->set_selection_mode(SelectionMode::Multiple); + + // transfer ownership of Medium + m_xLbTree->Fill( m_pDoc, m_pMedium, m_rName ); + } + else + { + m_xLbTree->InsertEntry(m_rName, BMP_DOC_TEXT); + } + + m_xCbxMasters->set_active(true); +} + +std::vector<OUString> SdInsertPagesObjsDlg::GetList( const sal_uInt16 nType ) +{ + // With Draw documents, we have to return NULL on selection of the document + if( m_pMedium ) + { + // to ensure that bookmarks are opened + // (when the whole document is selected) + m_xLbTree->GetBookmarkDoc(); + + // If the document is selected (too) or nothing is selected, + // the whole document is inserted (but not more!) + std::unique_ptr<weld::TreeIter> xIter(m_xLbTree->make_iterator()); + if (!m_xLbTree->get_iter_first(*xIter) || m_xLbTree->is_selected(*xIter)) + return std::vector<OUString>(); + } + + return m_xLbTree->GetSelectEntryList( nType ); +} + +/** + * is link checked + */ +bool SdInsertPagesObjsDlg::IsLink() const +{ + return m_xCbxLink->get_active(); +} + +/** + * is link checked + */ +bool SdInsertPagesObjsDlg::IsRemoveUnnecessaryMasterPages() const +{ + return m_xCbxMasters->get_active(); +} + +/** + * Enabled and selects end-color-LB + */ +IMPL_LINK_NOARG(SdInsertPagesObjsDlg, SelectObjectHdl, weld::TreeView&, void) +{ + m_xCbxLink->set_sensitive(m_xLbTree->IsLinkableSelected()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/layeroptionsdlg.cxx b/sd/source/ui/dlg/layeroptionsdlg.cxx new file mode 100644 index 000000000..a70c71f47 --- /dev/null +++ b/sd/source/ui/dlg/layeroptionsdlg.cxx @@ -0,0 +1,62 @@ +/* -*- 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 <svl/itemset.hxx> + +#include <sdattr.hxx> +#include <layeroptionsdlg.hxx> + +SdInsertLayerDlg::SdInsertLayerDlg(weld::Window* pWindow, const SfxItemSet& rInAttrs, + bool bDeletable, const OUString& rStr) + : GenericDialogController(pWindow, "modules/sdraw/ui/insertlayer.ui", "InsertLayerDialog") + , m_xEdtName(m_xBuilder->weld_entry("name")) + , m_xEdtTitle(m_xBuilder->weld_entry("title")) + , m_xEdtDesc(m_xBuilder->weld_text_view("textview")) + , m_xCbxVisible(m_xBuilder->weld_check_button("visible")) + , m_xCbxPrintable(m_xBuilder->weld_check_button("printable")) + , m_xCbxLocked(m_xBuilder->weld_check_button("locked")) + , m_xNameFrame(m_xBuilder->weld_widget("nameframe")) +{ + m_xDialog->set_title(rStr); + + m_xEdtName->set_text( static_cast<const SfxStringItem&>( rInAttrs.Get( ATTR_LAYER_NAME ) ).GetValue() ); + m_xEdtTitle->set_text( static_cast<const SfxStringItem&>( rInAttrs.Get( ATTR_LAYER_TITLE ) ).GetValue() ); + m_xEdtDesc->set_text( static_cast<const SfxStringItem&>( rInAttrs.Get( ATTR_LAYER_DESC ) ).GetValue() ); + m_xEdtDesc->set_size_request(-1, m_xEdtDesc->get_height_rows(4)); + m_xCbxVisible->set_active( static_cast<const SfxBoolItem&>( rInAttrs.Get( ATTR_LAYER_VISIBLE ) ).GetValue() ); + m_xCbxPrintable->set_active( static_cast<const SfxBoolItem&>( rInAttrs.Get( ATTR_LAYER_PRINTABLE ) ).GetValue() ); + m_xCbxLocked->set_active( static_cast<const SfxBoolItem&>( rInAttrs.Get( ATTR_LAYER_LOCKED ) ).GetValue() ); + m_xNameFrame->set_sensitive(bDeletable); +} + +SdInsertLayerDlg::~SdInsertLayerDlg() +{ +} + +void SdInsertLayerDlg::GetAttr( SfxItemSet& rAttrs ) +{ + rAttrs.Put( makeSdAttrLayerName( m_xEdtName->get_text() ) ); + rAttrs.Put( makeSdAttrLayerTitle( m_xEdtTitle->get_text() ) ); + rAttrs.Put( makeSdAttrLayerDesc( m_xEdtDesc->get_text() ) ); + rAttrs.Put( makeSdAttrLayerVisible( m_xCbxVisible->get_active() ) ); + rAttrs.Put( makeSdAttrLayerPrintable( m_xCbxPrintable->get_active() ) ); + rAttrs.Put( makeSdAttrLayerLocked( m_xCbxLocked->get_active() ) ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/masterlayoutdlg.cxx b/sd/source/ui/dlg/masterlayoutdlg.cxx new file mode 100644 index 000000000..ce4e069b0 --- /dev/null +++ b/sd/source/ui/dlg/masterlayoutdlg.cxx @@ -0,0 +1,133 @@ +/* -*- 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 <masterlayoutdlg.hxx> +#include <drawdoc.hxx> +#include <sdpage.hxx> +#include <osl/diagnose.h> + +using namespace ::sd; + +MasterLayoutDialog::MasterLayoutDialog(weld::Window* pParent, SdDrawDocument* pDoc, SdPage* pCurrentPage) + : GenericDialogController(pParent, "modules/simpress/ui/masterlayoutdlg.ui", "MasterLayoutDialog") + , mpDoc(pDoc) + , mpCurrentPage(pCurrentPage) + , mxCBDate(m_xBuilder->weld_check_button("datetime")) + , mxCBPageNumber(m_xBuilder->weld_check_button("pagenumber")) + , mxCBSlideNumber(m_xBuilder->weld_check_button("slidenumber")) + , mxCBHeader(m_xBuilder->weld_check_button("header")) + , mxCBFooter(m_xBuilder->weld_check_button("footer")) +{ + if( mpCurrentPage && !mpCurrentPage->IsMasterPage() ) + { + mpCurrentPage = static_cast<SdPage*>(&(mpCurrentPage->TRG_GetMasterPage())); + } + + if( mpCurrentPage == nullptr ) + { + mpCurrentPage = pDoc->GetMasterSdPage( 0, PageKind::Standard ); + OSL_FAIL( "MasterLayoutDialog::MasterLayoutDialog() - no current page?" ); + } + + switch( mpCurrentPage->GetPageKind() ) + { + case PageKind::Standard: + { + mxCBHeader->set_sensitive(false); + mxCBPageNumber->set_label(mxCBSlideNumber->get_label()); + break; + } + case PageKind::Notes: + break; + case PageKind::Handout: + break; + } + + mbOldHeader = mpCurrentPage->GetPresObj( PresObjKind::Header ) != nullptr; + mbOldDate = mpCurrentPage->GetPresObj( PresObjKind::DateTime ) != nullptr; + mbOldFooter = mpCurrentPage->GetPresObj( PresObjKind::Footer ) != nullptr; + mbOldPageNumber = mpCurrentPage->GetPresObj( PresObjKind::SlideNumber ) != nullptr; + + mxCBHeader->set_active( mbOldHeader ); + mxCBDate->set_active( mbOldDate ); + mxCBFooter->set_active( mbOldFooter ); + mxCBPageNumber->set_active( mbOldPageNumber ); +} + +MasterLayoutDialog::~MasterLayoutDialog() +{ +} + +short MasterLayoutDialog::run() +{ + if (GenericDialogController::run() == RET_OK) + applyChanges(); + return RET_OK; +} + +void MasterLayoutDialog::applyChanges() +{ + mpDoc->BegUndo(m_xDialog->get_title()); + + if( (mpCurrentPage->GetPageKind() != PageKind::Standard) && (mbOldHeader != mxCBHeader->get_active() ) ) + { + if( mbOldHeader ) + remove( PresObjKind::Header ); + else + create( PresObjKind::Header ); + } + + if( mbOldFooter != mxCBFooter->get_active() ) + { + if( mbOldFooter ) + remove( PresObjKind::Footer ); + else + create( PresObjKind::Footer ); + } + + if( mbOldDate != mxCBDate->get_active() ) + { + if( mbOldDate ) + remove( PresObjKind::DateTime ); + else + create( PresObjKind::DateTime ); + } + + if( mbOldPageNumber != mxCBPageNumber->get_active() ) + { + if( mbOldPageNumber ) + remove( PresObjKind::SlideNumber ); + else + create( PresObjKind::SlideNumber ); + } + + mpDoc->EndUndo(); +} + +void MasterLayoutDialog::create(PresObjKind eKind) +{ + mpCurrentPage->CreateDefaultPresObj(eKind); +} + +void MasterLayoutDialog::remove( PresObjKind eKind ) +{ + mpCurrentPage->DestroyDefaultPresObj(eKind); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/morphdlg.cxx b/sd/source/ui/dlg/morphdlg.cxx new file mode 100644 index 000000000..c0d7f4e5a --- /dev/null +++ b/sd/source/ui/dlg/morphdlg.cxx @@ -0,0 +1,107 @@ +/* -*- 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 <morphdlg.hxx> + +#include <sdmod.hxx> +#include <sdiocmpt.hxx> +#include <svx/xdef.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xlineit0.hxx> +#include <svx/svdobj.hxx> +#include <svl/itemset.hxx> +#include <com/sun/star/drawing/LineStyle.hpp> + +using namespace com::sun::star; + +namespace sd { + +MorphDlg::MorphDlg(weld::Window* pParent, const SdrObject* pObj1, const SdrObject* pObj2 ) + : GenericDialogController(pParent, "modules/sdraw/ui/crossfadedialog.ui", "CrossFadeDialog") + , m_xMtfSteps(m_xBuilder->weld_spin_button("increments")) + , m_xCbxAttributes(m_xBuilder->weld_check_button("attributes")) + , m_xCbxOrientation(m_xBuilder->weld_check_button("orientation")) +{ + LoadSettings(); + + SfxItemPool & rPool = pObj1->GetObjectItemPool(); + SfxItemSet aSet1( rPool ); + SfxItemSet aSet2( rPool ); + + aSet1.Put(pObj1->GetMergedItemSet()); + aSet2.Put(pObj2->GetMergedItemSet()); + + const drawing::LineStyle eLineStyle1 = aSet1.Get( XATTR_LINESTYLE ).GetValue(); + const drawing::LineStyle eLineStyle2 = aSet2.Get( XATTR_LINESTYLE ).GetValue(); + const drawing::FillStyle eFillStyle1 = aSet1.Get( XATTR_FILLSTYLE ).GetValue(); + const drawing::FillStyle eFillStyle2 = aSet2.Get( XATTR_FILLSTYLE ).GetValue(); + + if ( ( ( eLineStyle1 == drawing::LineStyle_NONE ) || ( eLineStyle2 == drawing::LineStyle_NONE ) ) && + ( ( eFillStyle1 != drawing::FillStyle_SOLID ) || ( eFillStyle2 != drawing::FillStyle_SOLID ) ) ) + { + m_xCbxAttributes->set_sensitive(false); + } +} + +MorphDlg::~MorphDlg() +{ +} + +void MorphDlg::LoadSettings() +{ + tools::SvRef<SotStorageStream> xIStm( SD_MOD()->GetOptionStream( SD_OPTION_MORPHING , + SdOptionStreamMode::Load ) ); + sal_uInt16 nSteps; + bool bOrient, bAttrib; + + if( xIStm.is() ) + { + SdIOCompat aCompat( *xIStm, StreamMode::READ ); + + xIStm->ReadUInt16( nSteps ).ReadCharAsBool( bOrient ).ReadCharAsBool( bAttrib ); + } + else + { + nSteps = 16; + bOrient = bAttrib = true; + } + + m_xMtfSteps->set_value(nSteps); + m_xCbxOrientation->set_active(bOrient); + m_xCbxAttributes->set_active(bAttrib); +} + +void MorphDlg::SaveSettings() const +{ + tools::SvRef<SotStorageStream> xOStm( SD_MOD()->GetOptionStream( SD_OPTION_MORPHING , + SdOptionStreamMode::Store ) ); + + if( xOStm.is() ) + { + SdIOCompat aCompat( *xOStm, StreamMode::WRITE, 1 ); + + xOStm->WriteUInt16( m_xMtfSteps->get_value() ) + .WriteBool( m_xCbxOrientation->get_active() ) + .WriteBool( m_xCbxAttributes->get_active() ); + } +} + +} // end of namespace sd + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx new file mode 100644 index 000000000..78525efe5 --- /dev/null +++ b/sd/source/ui/dlg/navigatr.cxx @@ -0,0 +1,735 @@ +/* -*- 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 <memory> +#include <sal/config.h> + +#include <osl/file.hxx> +#include <tools/urlobj.hxx> +#include <sfx2/fcontnr.hxx> +#include <svl/stritem.hxx> +#include <sfx2/docfile.hxx> +#include <svl/intitem.hxx> +#include <sfx2/dispatch.hxx> + +#include <sfx2/viewfrm.hxx> + +#include <pres.hxx> +#include <navigatr.hxx> +#include <pgjump.hxx> +#include <app.hrc> + +#include <bitmaps.hlst> +#include <drawdoc.hxx> +#include <DrawDocShell.hxx> +#include <ViewShell.hxx> +#include <ViewShellBase.hxx> +#include <slideshow.hxx> +#include <FrameView.hxx> +#include <Window.hxx> + +#include <DrawViewShell.hxx> + +/** + * SdNavigatorWin - FloatingWindow + */ +SdNavigatorWin::SdNavigatorWin(weld::Widget* pParent, SfxBindings* pInBindings, SfxNavigator* pNavigatorDlg) + : PanelLayout(pParent, "NavigatorPanel", "modules/simpress/ui/navigatorpanel.ui") + , mxToolbox(m_xBuilder->weld_toolbar("toolbox")) + , mxTlbObjects(new SdPageObjsTLV(m_xBuilder->weld_tree_view("tree"))) + , mxLbDocs(m_xBuilder->weld_combo_box("documents")) + , mxDragModeMenu(m_xBuilder->weld_menu("dragmodemenu")) + , mxShapeMenu(m_xBuilder->weld_menu("shapemenu")) + , mxNavigatorDlg(pNavigatorDlg) + , mbDocImported ( false ) + // On changes of the DragType: adjust SelectionMode of TLB! + , meDragType ( NAVIGATOR_DRAGTYPE_EMBEDDED ) + , mpBindings ( pInBindings ) +{ + mxTlbObjects->SetViewFrame( mpBindings->GetDispatcher()->GetFrame() ); + + mxTlbObjects->connect_row_activated(LINK(this, SdNavigatorWin, ClickObjectHdl)); + mxTlbObjects->set_selection_mode(SelectionMode::Single); + + mxToolbox->connect_clicked(LINK(this, SdNavigatorWin, SelectToolboxHdl)); + mxToolbox->connect_menu_toggled(LINK(this, SdNavigatorWin, DropdownClickToolBoxHdl)); + + mxToolbox->set_item_menu("dragmode", mxDragModeMenu.get()); + mxDragModeMenu->connect_activate(LINK(this, SdNavigatorWin, MenuSelectHdl)); + + // Shape filter drop down menu. + mxToolbox->set_item_menu("shapes", mxShapeMenu.get()); + mxShapeMenu->connect_activate(LINK(this, SdNavigatorWin, ShapeFilterCallback)); + + mxTlbObjects->SetSdNavigator(this); + + // DragTypeListBox + mxLbDocs->set_size_request(42, -1); // set a nominal width so it takes width of surroundings + mxLbDocs->connect_changed(LINK(this, SdNavigatorWin, SelectDocumentHdl)); + + SetDragImage(); + + mxToolbox->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl)); + mxTlbObjects->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl)); + mxLbDocs->connect_key_press(LINK(this, SdNavigatorWin, KeyInputHdl)); +} + +void SdNavigatorWin::FirstFocus() +{ + // set focus to listbox, otherwise it is in the toolbox which is only useful + // for keyboard navigation + mxTlbObjects->grab_focus(); +} + +weld::Window* SdNavigatorWin::GetFrameWeld() const +{ + if (mxNavigatorDlg) + return mxNavigatorDlg->GetFrameWeld(); + return PanelLayout::GetFrameWeld(); +} + +void SdNavigatorWin::SetUpdateRequestFunctor(const UpdateRequestFunctor& rUpdateRequest) +{ + mpNavigatorCtrlItem.reset( new SdNavigatorControllerItem(SID_NAVIGATOR_STATE, this, mpBindings, rUpdateRequest) ); + mpPageNameCtrlItem.reset( new SdPageNameControllerItem(SID_NAVIGATOR_PAGENAME, this, mpBindings) ); + + // InitTlb; is initiated over Slot + if (rUpdateRequest) + rUpdateRequest(); +} + +SdNavigatorWin::~SdNavigatorWin() +{ + mpNavigatorCtrlItem.reset(); + mpPageNameCtrlItem.reset(); + mxDragModeMenu.reset(); + mxShapeMenu.reset(); + mxToolbox.reset(); + mxTlbObjects.reset(); + mxLbDocs.reset(); +} + +//when object is marked , fresh the corresponding entry tree . +void SdNavigatorWin::FreshTree( const SdDrawDocument* pDoc ) +{ + SdDrawDocument* pNonConstDoc = const_cast<SdDrawDocument*>(pDoc); // const as const can... + sd::DrawDocShell* pDocShell = pNonConstDoc->GetDocSh(); + const OUString& aDocShName( pDocShell->GetName() ); + OUString aDocName = pDocShell->GetMedium()->GetName(); + mxTlbObjects->Fill( pDoc, false, aDocName ); // Only normal pages + RefreshDocumentLB(); + mxLbDocs->set_active_text(aDocShName); +} + +void SdNavigatorWin::InitTreeLB( const SdDrawDocument* pDoc ) +{ + SdDrawDocument* pNonConstDoc = const_cast<SdDrawDocument*>(pDoc); // const as const can... + ::sd::DrawDocShell* pDocShell = pNonConstDoc->GetDocSh(); + OUString aDocShName( pDocShell->GetName() ); + ::sd::ViewShell* pViewShell = pDocShell->GetViewShell(); + + // Restore the 'ShowAllShapes' flag from the last time (in this session) + // that the navigator was shown. + if (pViewShell != nullptr) + { + ::sd::FrameView* pFrameView = pViewShell->GetFrameView(); + if (pFrameView != nullptr) + mxTlbObjects->SetShowAllShapes(pFrameView->IsNavigatorShowingAllShapes(), false); + } + + // Disable the shape filter drop down menu when there is a running slide + // show. + if (pViewShell!=nullptr && sd::SlideShow::IsRunning( pViewShell->GetViewShellBase() )) + mxToolbox->set_item_sensitive("shapes", false); + else + mxToolbox->set_item_sensitive("shapes", true); + + if( !mxTlbObjects->IsEqualToDoc( pDoc ) ) + { + OUString aDocName = pDocShell->GetMedium()->GetName(); + mxTlbObjects->clear(); + mxTlbObjects->Fill( pDoc, false, aDocName ); // only normal pages + + RefreshDocumentLB(); + mxLbDocs->set_active_text(aDocShName); + } + else + { + mxLbDocs->set_active(-1); + mxLbDocs->set_active_text(aDocShName); + +// commented in order to fix 30246 +// if( mxLbDocs->get_active() == -1 ) + { + RefreshDocumentLB(); + mxLbDocs->set_active_text(aDocShName); + } + } + + SfxViewFrame* pViewFrame = ( ( pViewShell && pViewShell->GetViewFrame() ) ? pViewShell->GetViewFrame() : SfxViewFrame::Current() ); + if( pViewFrame ) + pViewFrame->GetBindings().Invalidate(SID_NAVIGATOR_PAGENAME, true, true); +} + +/** + * DragType is set on dependence if a Drag is even possible. For example, + * under certain circumstances, it is not allowed to drag graphics (#31038#). + */ +NavigatorDragType SdNavigatorWin::GetNavigatorDragType() +{ + NavigatorDragType eDT = meDragType; + NavDocInfo* pInfo = GetDocInfo(); + + if( ( eDT == NAVIGATOR_DRAGTYPE_LINK ) && ( ( pInfo && !pInfo->HasName() ) || !mxTlbObjects->IsLinkableSelected() ) ) + eDT = NAVIGATOR_DRAGTYPE_NONE; + + return eDT; +} + +SdPageObjsTLV& SdNavigatorWin::GetObjects() +{ + return *mxTlbObjects; +} + +IMPL_LINK(SdNavigatorWin, SelectToolboxHdl, const OString&, rCommand, void) +{ + PageJump ePage = PAGE_NONE; + + if (rCommand == "first") + ePage = PAGE_FIRST; + else if (rCommand == "previous") + ePage = PAGE_PREVIOUS; + else if (rCommand == "next") + ePage = PAGE_NEXT; + else if (rCommand == "last") + ePage = PAGE_LAST; + else if (rCommand == "dragmode") + mxToolbox->set_menu_item_active("dragmode", !mxToolbox->get_menu_item_active("dragmode")); + else if (rCommand == "shapes") + mxToolbox->set_menu_item_active("shapes", !mxToolbox->get_menu_item_active("shapes")); + + if (ePage != PAGE_NONE) + { + SfxUInt16Item aItem( SID_NAVIGATOR_PAGE, static_cast<sal_uInt16>(ePage) ); + mpBindings->GetDispatcher()->ExecuteList(SID_NAVIGATOR_PAGE, + SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); + } +} + +IMPL_LINK(SdNavigatorWin, DropdownClickToolBoxHdl, const OString&, rCommand, void) +{ + if (!mxToolbox->get_menu_item_active(rCommand)) + return; + + if (rCommand == "dragmode") + { + NavDocInfo* pInfo = GetDocInfo(); + if( ( pInfo && !pInfo->HasName() ) || !mxTlbObjects->IsLinkableSelected() ) + { + mxDragModeMenu->set_sensitive(OString::number(NAVIGATOR_DRAGTYPE_LINK), false); + mxDragModeMenu->set_sensitive(OString::number(NAVIGATOR_DRAGTYPE_URL), false); + meDragType = NAVIGATOR_DRAGTYPE_EMBEDDED; + } + + mxDragModeMenu->set_active(OString::number(meDragType), true); + } + else if (rCommand == "shapes") + { + bool bAll = mxTlbObjects->GetShowAllShapes(); + mxShapeMenu->set_active("named", !bAll); + mxShapeMenu->set_active("all", bAll); + } +} + +IMPL_LINK_NOARG(SdNavigatorWin, ClickObjectHdl, weld::TreeView&, bool) +{ + if( !mbDocImported || mxLbDocs->get_active() != 0 ) + { + NavDocInfo* pInfo = GetDocInfo(); + + // if it is the active window, we jump to the page + if( pInfo && pInfo->IsActive() ) + { + OUString aStr(mxTlbObjects->get_selected_text()); + + if( !aStr.isEmpty() ) + { + SfxStringItem aItem( SID_NAVIGATOR_OBJECT, aStr ); + mpBindings->GetDispatcher()->ExecuteList( + SID_NAVIGATOR_OBJECT, + SfxCallMode::SLOT | SfxCallMode::RECORD, { &aItem }); + + // moved here from SetGetFocusHdl. Reset the + // focus only if something has been selected in the + // document. + SfxViewShell* pCurSh = SfxViewShell::Current(); + + if ( pCurSh ) + { + vcl::Window* pShellWnd = pCurSh->GetWindow(); + if ( pShellWnd ) + pShellWnd->GrabFocus(); + } + + // We navigated to an object, but the current shell may be + // still the slide sorter. Explicitly try to grab the draw + // shell focus, so follow-up operations work with the object + // and not with the whole slide. + sd::DrawDocShell* pDocShell = pInfo->mpDocShell; + if (pDocShell) + { + sd::ViewShell* pViewShell = pDocShell->GetViewShell(); + if (pViewShell) + { + vcl::Window* pWindow = pViewShell->GetActiveWindow(); + if (pWindow) + pWindow->GrabFocus(); + } + } + + if (!mxTlbObjects->IsNavigationGrabsFocus()) + // This is the case when keyboard navigation inside the + // navigator should continue to work. + mxTlbObjects->grab_focus(); + } + } + } + return false; +} + +IMPL_LINK_NOARG(SdNavigatorWin, SelectDocumentHdl, weld::ComboBox&, void) +{ + OUString aStrLb = mxLbDocs->get_active_text(); + tools::Long nPos = mxLbDocs->get_active(); + bool bFound = false; + ::sd::DrawDocShell* pDocShell = nullptr; + NavDocInfo* pInfo = GetDocInfo(); + + // is it a dragged object? + if( mbDocImported && nPos == 0 ) + { + // construct document in TLB + InsertFile( aStrLb ); + } + else if (pInfo) + { + pDocShell = pInfo->mpDocShell; + + bFound = true; + } + + if( bFound ) + { + SdDrawDocument* pDoc = pDocShell->GetDoc(); + if( !mxTlbObjects->IsEqualToDoc( pDoc ) ) + { + SdDrawDocument* pNonConstDoc = pDoc; // const as const can... + ::sd::DrawDocShell* pNCDocShell = pNonConstDoc->GetDocSh(); + OUString aDocName = pNCDocShell->GetMedium()->GetName(); + mxTlbObjects->clear(); + mxTlbObjects->Fill( pDoc, false, aDocName ); // only normal pages + } + } + + // check if link or url is possible + if( ( pInfo && !pInfo->HasName() ) || !mxTlbObjects->IsLinkableSelected() || ( meDragType != NAVIGATOR_DRAGTYPE_EMBEDDED ) ) + { + meDragType = NAVIGATOR_DRAGTYPE_EMBEDDED; + SetDragImage(); + } +} + +/** + * Set DrageType and set image accordingly to it. + */ +IMPL_LINK(SdNavigatorWin, MenuSelectHdl, const OString&, rIdent, void) +{ + sal_uInt32 nMenuId = rIdent.toUInt32(); + + NavigatorDragType eDT = static_cast<NavigatorDragType>(nMenuId); + if( meDragType == eDT ) + return; + + meDragType = eDT; + SetDragImage(); + + if( meDragType == NAVIGATOR_DRAGTYPE_URL ) + { + // patch, prevents endless loop + if (mxTlbObjects->count_selected_rows() > 1) + mxTlbObjects->unselect_all(); + + mxTlbObjects->set_selection_mode(SelectionMode::Single); + } + else + mxTlbObjects->set_selection_mode(SelectionMode::Multiple); +} + +IMPL_LINK( SdNavigatorWin, ShapeFilterCallback, const OString&, rIdent, void ) +{ + bool bShowAllShapes(mxTlbObjects->GetShowAllShapes()); + if (rIdent == "named") + bShowAllShapes = false; + else if (rIdent == "all") + bShowAllShapes = true; + else + OSL_FAIL("SdNavigatorWin::ShapeFilterCallback called for unknown menu entry"); + + mxTlbObjects->SetShowAllShapes(bShowAllShapes, true); + + // Remember the selection in the FrameView. + NavDocInfo* pInfo = GetDocInfo(); + if (pInfo == nullptr) + return; + + ::sd::DrawDocShell* pDocShell = pInfo->mpDocShell; + if (pDocShell != nullptr) + { + ::sd::ViewShell* pViewShell = pDocShell->GetViewShell(); + if (pViewShell != nullptr) + { + ::sd::FrameView* pFrameView = pViewShell->GetFrameView(); + if (pFrameView != nullptr) + { + pFrameView->SetIsNavigatorShowingAllShapes(bShowAllShapes); + } + } + } +} + +bool SdNavigatorWin::InsertFile(const OUString& rFileName) +{ + INetURLObject aURL( rFileName ); + + if( aURL.GetProtocol() == INetProtocol::NotValid ) + { + OUString aURLStr; + osl::FileBase::getFileURLFromSystemPath( rFileName, aURLStr ); + aURL = INetURLObject( aURLStr ); + } + + // get adjusted FileName + OUString aFileName( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ); + + if (aFileName.isEmpty()) + { + // show actual document again + maDropFileName = aFileName; + } + else + { + // show dragged-in document + std::shared_ptr<const SfxFilter> pFilter; + ErrCode nErr = ERRCODE_NONE; + + if (aFileName != maDropFileName) + { + SfxMedium aMed(aFileName, (StreamMode::READ | StreamMode::SHARE_DENYNONE)); + SfxFilterMatcher aMatch( "simpress" ); + aMed.UseInteractionHandler( true ); + nErr = aMatch.GuessFilter(aMed, pFilter); + } + + if ((pFilter && !nErr) || aFileName == maDropFileName) + { + // The medium may be opened with READ/WRITE. Therefore, we first + // check if it contains a Storage. + std::unique_ptr<SfxMedium> xMedium(new SfxMedium(aFileName, + StreamMode::READ | StreamMode::NOCREATE)); + + if (xMedium->IsStorage()) + { + // Now depending on mode: + // mxTlbObjects->set_selection_mode(SelectionMode::Multiple); + // handover of ownership of xMedium; + SdDrawDocument* pDropDoc = mxTlbObjects->GetBookmarkDoc(xMedium.release()); + + if (pDropDoc) + { + mxTlbObjects->clear(); + maDropFileName = aFileName; + + if( !mxTlbObjects->IsEqualToDoc( pDropDoc ) ) + { + // only normal pages + mxTlbObjects->Fill(pDropDoc, false, maDropFileName); + RefreshDocumentLB( &maDropFileName ); + } + } + } + else + { + return false; + } + } + else + { + return false; + } + } + + return true; +} + +void SdNavigatorWin::RefreshDocumentLB( const OUString* pDocName ) +{ + sal_Int32 nPos = 0; + + if( pDocName ) + { + if( mbDocImported ) + mxLbDocs->remove(0); + + mxLbDocs->insert_text(0, *pDocName); + mbDocImported = true; + } + else + { + nPos = mxLbDocs->get_active(); + if (nPos == -1) + nPos = 0; + + OUString aStr; + if( mbDocImported ) + aStr = mxLbDocs->get_text(0); + + mxLbDocs->clear(); + + // delete list of DocInfos + maDocList.clear(); + + if( mbDocImported ) + mxLbDocs->insert_text(0, aStr); + + ::sd::DrawDocShell* pCurrentDocShell = + dynamic_cast< ::sd::DrawDocShell *>( SfxObjectShell::Current() ); + SfxObjectShell* pSfxDocShell = SfxObjectShell::GetFirst([](const SfxObjectShell*){return true;}, false); + while( pSfxDocShell ) + { + ::sd::DrawDocShell* pDocShell = dynamic_cast< ::sd::DrawDocShell *>( pSfxDocShell ); + if( pDocShell && !pDocShell->IsInDestruction() && ( pDocShell->GetCreateMode() != SfxObjectCreateMode::EMBEDDED ) ) + { + NavDocInfo aInfo ; + aInfo.mpDocShell = pDocShell; + + SfxMedium *pMedium = pDocShell->GetMedium(); + aStr = pMedium ? pMedium->GetName() : OUString(); + if( !aStr.isEmpty() ) + aInfo.SetName( true ); + else + aInfo.SetName( false ); + // at the moment, we use the name of the shell again (i.e. + // without path) since Koose thinks it is an error if the path + // is shown in url notation! + aStr = pDocShell->GetName(); + + mxLbDocs->append_text(aStr); + + if( pDocShell == pCurrentDocShell ) + aInfo.SetActive( true ); + else + aInfo.SetActive( false ); + + maDocList.push_back( aInfo ); + } + pSfxDocShell = SfxObjectShell::GetNext( *pSfxDocShell, [](const SfxObjectShell*){return true;}, false ); + } + } + mxLbDocs->set_active(nPos); +} + +OUString SdNavigatorWin::GetDragTypeSdBmpId(NavigatorDragType eDT) +{ + switch( eDT ) + { + case NAVIGATOR_DRAGTYPE_NONE: + return OUString(); + case NAVIGATOR_DRAGTYPE_URL: + return BMP_HYPERLINK; + case NAVIGATOR_DRAGTYPE_EMBEDDED: + return BMP_EMBEDDED; + case NAVIGATOR_DRAGTYPE_LINK: + return BMP_LINK; + default: OSL_FAIL( "No resource for DragType available!" ); + } + return OUString(); +} + +NavDocInfo* SdNavigatorWin::GetDocInfo() +{ + sal_uInt32 nPos = mxLbDocs->get_active(); + + if( mbDocImported ) + { + if( nPos == 0 ) + { + return nullptr; + } + nPos--; + } + + return nPos < maDocList.size() ? &(maDocList[ nPos ]) : nullptr; +} + +/** + * catch ESCAPE in order to end show + */ +IMPL_LINK(SdNavigatorWin, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + bool bConsumed = false; + + if (KEY_ESCAPE == rKEvt.GetKeyCode().GetCode()) + { + // during drag'n'drop we just stop the drag but do not close the navigator + if (!SdPageObjsTLV::IsInDrag()) + { + ::sd::ViewShellBase* pBase = ::sd::ViewShellBase::GetViewShellBase( mpBindings->GetDispatcher()->GetFrame()); + if (pBase) + sd::SlideShow::Stop(*pBase); + bConsumed = true; + } + } + + return bConsumed; +} + +void SdNavigatorWin::SetDragImage() +{ + mxToolbox->set_item_icon_name("dragmode", GetDragTypeSdBmpId(meDragType)); +} + +/** + * ControllerItem for Navigator + */ +SdNavigatorControllerItem::SdNavigatorControllerItem( + sal_uInt16 _nId, + SdNavigatorWin* pNavWin, + SfxBindings* _pBindings, + const SdNavigatorWin::UpdateRequestFunctor& rUpdateRequest) + : SfxControllerItem( _nId, *_pBindings ), + pNavigatorWin( pNavWin ), + maUpdateRequest(rUpdateRequest) +{ +} + +void SdNavigatorControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId, + SfxItemState eState, const SfxPoolItem* pItem ) +{ + if( eState < SfxItemState::DEFAULT || nSId != SID_NAVIGATOR_STATE ) + return; + + // only if doc in LB is the active + NavDocInfo* pInfo = pNavigatorWin->GetDocInfo(); + if( !(pInfo && pInfo->IsActive()) ) + return; + + if (::sd::DrawDocShell* pDrawDocShell = pInfo->GetDrawDocShell()) + { + const auto pDrawViewShell = + static_cast<::sd::DrawViewShell *>(pDrawDocShell->GetViewShell()); + if (pDrawViewShell) + { + bool bEditModePage(pDrawViewShell->GetEditMode() == EditMode::Page); + pNavigatorWin->mxToolbox->set_sensitive(bEditModePage); + pNavigatorWin->mxLbDocs->set_sensitive(bEditModePage); + pNavigatorWin->mxTlbObjects->set_sensitive(bEditModePage); + } + } + + const SfxUInt32Item& rStateItem = dynamic_cast<const SfxUInt32Item&>(*pItem); + NavState nState = static_cast<NavState>(rStateItem.GetValue()); + + // First + if (nState & NavState::BtnFirstEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("first")) + pNavigatorWin->mxToolbox->set_item_sensitive("first", true); + if (nState & NavState::BtnFirstDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("first")) + pNavigatorWin->mxToolbox->set_item_sensitive("first", false); + + // Prev + if (nState & NavState::BtnPrevEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("previous")) + pNavigatorWin->mxToolbox->set_item_sensitive("previous", true); + if (nState & NavState::BtnPrevDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("previous")) + pNavigatorWin->mxToolbox->set_item_sensitive("previous", false); + + // Last + if (nState & NavState::BtnLastEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("last")) + pNavigatorWin->mxToolbox->set_item_sensitive("last", true); + if (nState & NavState::BtnLastDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("last")) + pNavigatorWin->mxToolbox->set_item_sensitive("last", false); + + // Next + if (nState & NavState::BtnNextEnabled && + !pNavigatorWin->mxToolbox->get_item_sensitive("next")) + pNavigatorWin->mxToolbox->set_item_sensitive("next", true); + if (nState & NavState::BtnNextDisabled && + pNavigatorWin->mxToolbox->get_item_sensitive("next")) + pNavigatorWin->mxToolbox->set_item_sensitive("next", false); + + if (nState & NavState::TableUpdate) + { + // InitTlb; is initiated by Slot + if (maUpdateRequest) + maUpdateRequest(); + } +} + +/** + * ControllerItem for Navigator to show page in TreeLB + */ +SdPageNameControllerItem::SdPageNameControllerItem( + sal_uInt16 _nId, + SdNavigatorWin* pNavWin, + SfxBindings* _pBindings) + : SfxControllerItem( _nId, *_pBindings ), + pNavigatorWin( pNavWin ) +{ +} + +void SdPageNameControllerItem::StateChangedAtToolBoxControl( sal_uInt16 nSId, + SfxItemState eState, const SfxPoolItem* pItem ) +{ + if( eState < SfxItemState::DEFAULT || nSId != SID_NAVIGATOR_PAGENAME ) + return; + + // only if doc in LB is the active + NavDocInfo* pInfo = pNavigatorWin->GetDocInfo(); + if( !(pInfo && pInfo->IsActive()) ) + return; + + const SfxStringItem& rStateItem = dynamic_cast<const SfxStringItem&>(*pItem); + const OUString& aPageName = rStateItem.GetValue(); + + if( !pNavigatorWin->mxTlbObjects->HasSelectedChildren( aPageName ) ) + { + if (pNavigatorWin->mxTlbObjects->get_selection_mode() == SelectionMode::Multiple) + { + // because otherwise it is always additional select + pNavigatorWin->mxTlbObjects->unselect_all(); + } + pNavigatorWin->mxTlbObjects->SelectEntry( aPageName ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/paragr.cxx b/sd/source/ui/dlg/paragr.cxx new file mode 100644 index 000000000..be9df558e --- /dev/null +++ b/sd/source/ui/dlg/paragr.cxx @@ -0,0 +1,169 @@ +/* -*- 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 <svl/cjkoptions.hxx> +#include <svl/eitem.hxx> +#include <svl/intitem.hxx> + +#include <svx/dialogs.hrc> +#include <svx/svxids.hrc> +#include <svx/flagsdef.hxx> +#include <svx/xcolit.hxx> + +#include <paragr.hxx> +#include <sdattr.hrc> + +namespace { + +class SdParagraphNumTabPage : public SfxTabPage +{ +public: + SdParagraphNumTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet); + static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet ); + + static WhichRangesContainer GetRanges(); + + virtual bool FillItemSet( SfxItemSet* rSet ) override; + virtual void Reset( const SfxItemSet* rSet ) override; + +private: + bool mbModified; + std::unique_ptr<weld::CheckButton> m_xNewStartCB; + std::unique_ptr<weld::CheckButton> m_xNewStartNumberCB; + std::unique_ptr<weld::SpinButton> m_xNewStartNF; + + DECL_LINK( ImplNewStartHdl, weld::Toggleable&, void ); +}; + +} + +SdParagraphNumTabPage::SdParagraphNumTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr) + : SfxTabPage(pPage, pController, "modules/sdraw/ui/paranumberingtab.ui", "DrawParaNumbering", &rAttr) + , mbModified(false) + , m_xNewStartCB(m_xBuilder->weld_check_button("checkbuttonCB_NEW_START")) + , m_xNewStartNumberCB(m_xBuilder->weld_check_button("checkbuttonCB_NUMBER_NEW_START")) + , m_xNewStartNF(m_xBuilder->weld_spin_button("spinbuttonNF_NEW_START")) +{ + m_xNewStartCB->connect_toggled(LINK(this, SdParagraphNumTabPage, ImplNewStartHdl)); + m_xNewStartNumberCB->connect_toggled(LINK(this, SdParagraphNumTabPage, ImplNewStartHdl)); +} + +std::unique_ptr<SfxTabPage> SdParagraphNumTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet * rAttrSet) +{ + return std::make_unique<SdParagraphNumTabPage>(pPage, pController, *rAttrSet); +} + +WhichRangesContainer SdParagraphNumTabPage::GetRanges() +{ + return WhichRangesContainer(svl::Items<ATTR_PARANUMBERING_START, ATTR_PARANUMBERING_END>); +} + +bool SdParagraphNumTabPage::FillItemSet( SfxItemSet* rSet ) +{ + if (m_xNewStartCB->get_state_changed_from_saved() || + m_xNewStartNumberCB->get_state_changed_from_saved()|| + m_xNewStartNF->get_value_changed_from_saved()) + { + mbModified = true; + bool bNewStartChecked = TRISTATE_TRUE == m_xNewStartCB->get_state(); + bool bNumberNewStartChecked = TRISTATE_TRUE == m_xNewStartNumberCB->get_state(); + rSet->Put(SfxBoolItem(ATTR_NUMBER_NEWSTART, bNewStartChecked)); + + const sal_Int16 nStartAt = static_cast<sal_Int16>(m_xNewStartNF->get_value()); + rSet->Put(SfxInt16Item(ATTR_NUMBER_NEWSTART_AT, bNumberNewStartChecked && bNewStartChecked ? nStartAt : -1)); + } + + return mbModified; +} + +void SdParagraphNumTabPage::Reset( const SfxItemSet* rSet ) +{ + SfxItemState eItemState = rSet->GetItemState( ATTR_NUMBER_NEWSTART ); + if(eItemState > SfxItemState::DEFAULT ) + { + const SfxBoolItem& rStart = rSet->Get(ATTR_NUMBER_NEWSTART); + m_xNewStartCB->set_state( rStart.GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE ); + } + else + { + m_xNewStartCB->set_state(TRISTATE_INDET); + m_xNewStartCB->set_sensitive(false); + } + m_xNewStartCB->save_state(); + + eItemState = rSet->GetItemState( ATTR_NUMBER_NEWSTART_AT); + if( eItemState > SfxItemState::DEFAULT ) + { + sal_Int16 nNewStart = rSet->Get(ATTR_NUMBER_NEWSTART_AT).GetValue(); + m_xNewStartNumberCB->set_active(-1 != nNewStart); + if(-1 == nNewStart) + nNewStart = 1; + + m_xNewStartNF->set_value(nNewStart); + } + else + { + m_xNewStartCB->set_state(TRISTATE_INDET); + } + ImplNewStartHdl(*m_xNewStartCB); + m_xNewStartNF->save_value(); + m_xNewStartNumberCB->save_state(); + mbModified = false; +} + +IMPL_LINK_NOARG(SdParagraphNumTabPage, ImplNewStartHdl, weld::Toggleable&, void) +{ + bool bEnable = m_xNewStartCB->get_active(); + m_xNewStartNumberCB->set_sensitive(bEnable); + m_xNewStartNF->set_sensitive(bEnable && m_xNewStartNumberCB->get_active()); +} + +SdParagraphDlg::SdParagraphDlg(weld::Window* pParent, const SfxItemSet* pAttr) + : SfxTabDialogController(pParent, "modules/sdraw/ui/drawparadialog.ui", + "DrawParagraphPropertiesDialog", pAttr) +{ + AddTabPage( "labelTP_PARA_STD", RID_SVXPAGE_STD_PARAGRAPH); + + if( SvtCJKOptions::IsAsianTypographyEnabled() ) + AddTabPage( "labelTP_PARA_ASIAN", RID_SVXPAGE_PARA_ASIAN); + else + RemoveTabPage( "labelTP_PARA_ASIAN" ); + + AddTabPage( "labelTP_PARA_ALIGN", RID_SVXPAGE_ALIGN_PARAGRAPH); + + static const bool bShowParaNumbering = ( getenv( "SD_SHOW_NUMBERING_PAGE" ) != nullptr ); + if( bShowParaNumbering ) + AddTabPage( "labelNUMBERING", SdParagraphNumTabPage::Create, SdParagraphNumTabPage::GetRanges ); + else + RemoveTabPage( "labelNUMBERING" ); + + AddTabPage("labelTP_TABULATOR", RID_SVXPAGE_TABULATOR); +} + +void SdParagraphDlg::PageCreated(const OString& rId, SfxTabPage &rPage) +{ + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + if (rId == "labelTP_PARA_STD") + { + aSet.Put(SfxUInt32Item(SID_SVXSTDPARAGRAPHTABPAGE_ABSLINEDIST, MM50/2)); + rPage.PageCreated(aSet); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/present.cxx b/sd/source/ui/dlg/present.cxx new file mode 100644 index 000000000..73932ba62 --- /dev/null +++ b/sd/source/ui/dlg/present.cxx @@ -0,0 +1,323 @@ +/* -*- 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 <svl/itemset.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <svl/stritem.hxx> +#include <vcl/svapp.hxx> + +#include <sdattr.hrc> +#include <present.hxx> +#include <cusshow.hxx> +#include <customshowlist.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +SdStartPresentationDlg::SdStartPresentationDlg(weld::Window* pWindow, const SfxItemSet& rInAttrs, + const std::vector<OUString> &rPageNames, SdCustomShowList* pCSList) + : GenericDialogController(pWindow, "modules/simpress/ui/presentationdialog.ui", "PresentationDialog") + , pCustomShowList(pCSList) + , rOutAttrs(rInAttrs) + , mnMonitors(0) + , m_xRbtAll(m_xBuilder->weld_radio_button("allslides")) + , m_xRbtAtDia(m_xBuilder->weld_radio_button("from")) + , m_xRbtCustomshow(m_xBuilder->weld_radio_button("customslideshow")) + , m_xLbDias(m_xBuilder->weld_combo_box("from_cb")) + , m_xLbCustomshow(m_xBuilder->weld_combo_box("customslideshow_cb")) + , m_xRbtStandard(m_xBuilder->weld_radio_button("default")) + , m_xRbtWindow(m_xBuilder->weld_radio_button("window")) + , m_xRbtAuto(m_xBuilder->weld_radio_button("auto")) + , m_xTmfPause(m_xBuilder->weld_formatted_spin_button("pauseduration")) + , m_xFormatter(new weld::TimeFormatter(*m_xTmfPause)) + , m_xCbxAutoLogo(m_xBuilder->weld_check_button("showlogo")) + , m_xCbxManuel(m_xBuilder->weld_check_button("manualslides")) + , m_xCbxMousepointer(m_xBuilder->weld_check_button("pointervisible")) + , m_xCbxPen(m_xBuilder->weld_check_button("pointeraspen")) + , m_xCbxAnimationAllowed(m_xBuilder->weld_check_button("animationsallowed")) + , m_xCbxChangePage(m_xBuilder->weld_check_button("changeslidesbyclick")) + , m_xCbxAlwaysOnTop(m_xBuilder->weld_check_button("alwaysontop")) + , m_xFtMonitor(m_xBuilder->weld_label("presdisplay_label")) + , m_xLBMonitor(m_xBuilder->weld_combo_box("presdisplay_cb")) + , m_xMonitor(m_xBuilder->weld_label("monitor_str")) + , m_xAllMonitors(m_xBuilder->weld_label("allmonitors_str")) + , m_xMonitorExternal(m_xBuilder->weld_label("externalmonitor_str")) + , m_xExternal(m_xBuilder->weld_label("external_str")) +{ + m_xFormatter->SetExtFormat(ExtTimeFieldFormat::LongDuration); + m_xFormatter->EnableEmptyField(false); + + Link<weld::Toggleable&,void> aLink( LINK( this, SdStartPresentationDlg, ChangeRangeHdl ) ); + + m_xRbtAll->connect_toggled( aLink ); + m_xRbtAtDia->connect_toggled( aLink ); + m_xRbtCustomshow->connect_toggled( aLink ); + + aLink = LINK( this, SdStartPresentationDlg, ClickWindowPresentationHdl ); + m_xRbtStandard->connect_toggled( aLink ); + m_xRbtWindow->connect_toggled( aLink ); + m_xRbtAuto->connect_toggled( aLink ); + + m_xTmfPause->connect_value_changed( LINK( this, SdStartPresentationDlg, ChangePauseHdl ) ); + + // fill Listbox with page names + for (const auto& rPageName : rPageNames) + m_xLbDias->append_text(rPageName); + + if( pCustomShowList ) + { + sal_uInt16 nPosToSelect = pCustomShowList->GetCurPos(); + SdCustomShow* pCustomShow; + // fill Listbox with CustomShows + for( pCustomShow = pCustomShowList->First(); + pCustomShow != nullptr; + pCustomShow = pCustomShowList->Next() ) + { + m_xLbCustomshow->append_text( pCustomShow->GetName() ); + } + m_xLbCustomshow->set_active( nPosToSelect ); + pCustomShowList->Seek( nPosToSelect ); + } + else + m_xRbtCustomshow->set_sensitive(false); + + if( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_CUSTOMSHOW ) ).GetValue() && pCSList ) + m_xRbtCustomshow->set_active(true); + else if( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_ALL ) ).GetValue() ) + m_xRbtAll->set_active(true); + else + m_xRbtAtDia->set_active(true); + + m_xLbDias->set_active_text( static_cast<const SfxStringItem&>( rOutAttrs.Get( ATTR_PRESENT_DIANAME ) ).GetValue() ); + m_xCbxManuel->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_MANUEL ) ).GetValue() ); + m_xCbxMousepointer->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_MOUSE ) ).GetValue() ); + m_xCbxPen->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_PEN ) ).GetValue() ); + m_xCbxAnimationAllowed->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_ANIMATION_ALLOWED ) ).GetValue() ); + m_xCbxChangePage->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_CHANGE_PAGE ) ).GetValue() ); + m_xCbxAlwaysOnTop->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_ALWAYS_ON_TOP ) ).GetValue() ); + + const bool bEndless = static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_ENDLESS ) ).GetValue(); + const bool bWindow = !static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_FULLSCREEN ) ).GetValue(); + const tools::Long nPause = static_cast<const SfxUInt32Item&>( rOutAttrs.Get( ATTR_PRESENT_PAUSE_TIMEOUT ) ).GetValue(); + + m_xFormatter->SetTime( tools::Time( 0, 0, nPause ) ); + // set cursor in timefield to end + m_xTmfPause->set_position(-1); + + m_xCbxAutoLogo->set_active( static_cast<const SfxBoolItem&>( rOutAttrs.Get( ATTR_PRESENT_SHOW_PAUSELOGO ) ).GetValue() ); + + if( bWindow ) + m_xRbtWindow->set_active(true); + else if( bEndless ) + m_xRbtAuto->set_active(true); + else + m_xRbtStandard->set_active(true); + + InitMonitorSettings(); + + ChangeRangeHdl(*m_xRbtCustomshow); + + ClickWindowPresentationHdl(*m_xRbtStandard); + ChangePause(); +} + +SdStartPresentationDlg::~SdStartPresentationDlg() +{ +} + +OUString SdStartPresentationDlg::GetDisplayName( sal_Int32 nDisplay, + DisplayType eType ) +{ + OUString aName; + + switch ( eType ) + { + case EXTERNAL_IS_NUMBER: + aName = m_xExternal->get_label(); + break; + case MONITOR_IS_EXTERNAL: + aName = m_xMonitorExternal->get_label(); + break; + default: + case MONITOR_NORMAL: + aName = m_xMonitor->get_label(); + break; + } + aName = aName.replaceFirst( "%1", OUString::number( nDisplay ) ); + + return aName; +} + +/// Store display index together with name in user data +sal_Int32 SdStartPresentationDlg::InsertDisplayEntry(const OUString &aName, + sal_Int32 nDisplay) +{ + m_xLBMonitor->append(OUString::number(nDisplay), aName); + return m_xLBMonitor->get_count() - 1; +} + +void SdStartPresentationDlg::InitMonitorSettings() +{ + try + { + m_xFtMonitor->show(); + m_xLBMonitor->show(); + + mnMonitors = Application::GetScreenCount(); + + if( mnMonitors <= 1 ) + { + m_xFtMonitor->set_sensitive( false ); + m_xLBMonitor->set_sensitive( false ); + } + else + { + bool bUnifiedDisplay = Application::IsUnifiedDisplay(); + sal_Int32 nExternalIndex = Application::GetDisplayExternalScreen(); + + sal_Int32 nSelectedIndex (-1); + sal_Int32 nDefaultExternalIndex (-1); + const sal_Int32 nDefaultSelectedDisplay ( + static_cast<const SfxInt32Item&>( rOutAttrs.Get( ATTR_PRESENT_DISPLAY ) ).GetValue()); + + // Un-conditionally add a version for '0' the default external display + sal_Int32 nInsertedEntry; + + // Initial entry - the auto-detected external monitor + OUString aName = GetDisplayName( nExternalIndex + 1, EXTERNAL_IS_NUMBER); + nInsertedEntry = InsertDisplayEntry( aName, 0 ); + if( nDefaultSelectedDisplay == 0) + nSelectedIndex = nInsertedEntry; + + // The user data contains the real setting + for( sal_Int32 nDisplay = 0; nDisplay < mnMonitors; nDisplay++ ) + { + aName = GetDisplayName( nDisplay + 1, + nDisplay == nExternalIndex ? + MONITOR_IS_EXTERNAL : MONITOR_NORMAL ); + nInsertedEntry = InsertDisplayEntry( aName, nDisplay + 1 ); + + // Remember the index of the default selection. + if( nDisplay + 1 == nDefaultSelectedDisplay ) + nSelectedIndex = nInsertedEntry; + + // Remember index of the default display. + if( nDisplay == nExternalIndex ) + nDefaultExternalIndex = nInsertedEntry; + } + + if( bUnifiedDisplay ) + { + nInsertedEntry = InsertDisplayEntry( m_xAllMonitors->get_label(), -1 ); + if( nDefaultSelectedDisplay == -1 ) + nSelectedIndex = nInsertedEntry; + } + + if (nSelectedIndex < 0) + { + if (nExternalIndex < 0) + nSelectedIndex = 0; + else + nSelectedIndex = nDefaultExternalIndex; + } + + m_xLBMonitor->set_active(nSelectedIndex); + } + } + catch( Exception& ) + { + } +} + +/** + * sets the selected attributes of the dialog + */ +void SdStartPresentationDlg::GetAttr( SfxItemSet& rAttr ) +{ + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_ALL, m_xRbtAll->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_CUSTOMSHOW, m_xRbtCustomshow->get_active() ) ); + rAttr.Put( SfxStringItem ( ATTR_PRESENT_DIANAME, m_xLbDias->get_active_text() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_MANUEL, m_xCbxManuel->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_MOUSE, m_xCbxMousepointer->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_PEN, m_xCbxPen->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_ANIMATION_ALLOWED, m_xCbxAnimationAllowed->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_CHANGE_PAGE, m_xCbxChangePage->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_ALWAYS_ON_TOP, m_xCbxAlwaysOnTop->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_FULLSCREEN, !m_xRbtWindow->get_active() ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_ENDLESS, m_xRbtAuto->get_active() ) ); + rAttr.Put( SfxUInt32Item ( ATTR_PRESENT_PAUSE_TIMEOUT, m_xFormatter->GetTime().GetMSFromTime() / 1000 ) ); + rAttr.Put( SfxBoolItem ( ATTR_PRESENT_SHOW_PAUSELOGO, m_xCbxAutoLogo->get_active() ) ); + + int nPos = m_xLBMonitor->get_active(); + if (nPos != -1) + rAttr.Put(SfxInt32Item(ATTR_PRESENT_DISPLAY, m_xLBMonitor->get_id(nPos).toInt32())); + + nPos = m_xLbCustomshow->get_active(); + if (nPos != -1) + pCustomShowList->Seek( nPos ); +} + +/** + * Handler: Enabled/Disabled Listbox "Dias" + */ +IMPL_LINK_NOARG(SdStartPresentationDlg, ChangeRangeHdl, weld::Toggleable&, void) +{ + m_xLbDias->set_sensitive( m_xRbtAtDia->get_active() ); + m_xLbCustomshow->set_sensitive( m_xRbtCustomshow->get_active() ); +} + +/** + * Handler: Enabled/Disabled Checkbox "AlwaysOnTop" + */ +IMPL_LINK_NOARG(SdStartPresentationDlg, ClickWindowPresentationHdl, weld::Toggleable&, void) +{ + const bool bAuto = m_xRbtAuto->get_active(); + const bool bWindow = m_xRbtWindow->get_active(); + + m_xTmfPause->set_sensitive( bAuto ); + m_xCbxAutoLogo->set_sensitive( bAuto && ( m_xFormatter->GetTime().GetMSFromTime() > 0 ) ); + + const bool bDisplay = !bWindow && ( mnMonitors > 1 ); + m_xFtMonitor->set_sensitive( bDisplay ); + m_xLBMonitor->set_sensitive( bDisplay ); + + if( bWindow ) + { + m_xCbxAlwaysOnTop->set_sensitive(false); + m_xCbxAlwaysOnTop->set_active(false); + } + else + m_xCbxAlwaysOnTop->set_sensitive(true); +} + +/** + * Handler: Enabled/Disabled Checkbox "AlwaysOnTop" + */ +IMPL_LINK_NOARG(SdStartPresentationDlg, ChangePauseHdl, weld::FormattedSpinButton&, void) +{ + ChangePause(); +} + +void SdStartPresentationDlg::ChangePause() +{ + m_xCbxAutoLogo->set_sensitive(m_xRbtAuto->get_active() && ( m_xFormatter->GetTime().GetMSFromTime() > 0 )); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/prltempl.cxx b/sd/source/ui/dlg/prltempl.cxx new file mode 100644 index 000000000..869f13c83 --- /dev/null +++ b/sd/source/ui/dlg/prltempl.cxx @@ -0,0 +1,305 @@ +/* -*- 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 <sal/log.hxx> +#include <svx/dialogs.hrc> +#include <svx/svxids.hrc> +#include <editeng/flstitem.hxx> +#include <svx/drawitem.hxx> +#include <svl/style.hxx> +#include <svx/svdobjkind.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/numitem.hxx> +#include <svl/cjkoptions.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/sfxdlg.hxx> + +#include <strings.hrc> +#include <sdresid.hxx> +#include <prltempl.hxx> +#include <bulmaper.hxx> +#include <svl/intitem.hxx> +#include <svx/flagsdef.hxx> + +#define IS_OUTLINE(x) (x >= PresentationObjects::Outline_1 && x <= PresentationObjects::Outline_9) + +/** + * Constructor of Tab dialog: appends pages to the dialog + */ +SdPresLayoutTemplateDlg::SdPresLayoutTemplateDlg(SfxObjectShell const * pDocSh, + weld::Window* pParent, + bool bBackground, + SfxStyleSheetBase& rStyleBase, + PresentationObjects _ePO, + SfxStyleSheetBasePool* pSSPool) + : SfxTabDialogController(pParent, "modules/sdraw/ui/drawprtldialog.ui", "DrawPRTLDialog") + , mpDocShell(pDocSh) + , ePO(_ePO) + , aInputSet(*rStyleBase.GetItemSet().GetPool(), svl::Items<SID_PARAM_NUM_PRESET, SID_PARAM_CUR_NUM_LEVEL>) +{ + const SfxItemSet* pOrgSet(&rStyleBase.GetItemSet()); + + if( IS_OUTLINE(ePO)) + { + // Unfortunately, the Itemsets of our style sheets are not discrete... + const WhichRangesContainer& pPtr = pOrgSet->GetRanges(); + sal_uInt16 p1, p2; + for( sal_Int32 i = 0; i < pPtr.size(); ++i ) + { + p1 = pPtr[i].first; + p2 = pPtr[i].second; + + // first, we make it discrete + while(i < pPtr.size() - 1 && (pPtr[i+1].first - p2 == 1)) + { + p2 = pPtr[i+1].second; + ++i; + } + aInputSet.MergeRange( p1, p2 ); + } + + aInputSet.Put( rStyleBase.GetItemSet() ); + + // need parent-relationship + const SfxItemSet* pParentItemSet = rStyleBase.GetItemSet().GetParent(); + if( pParentItemSet ) + aInputSet.SetParent( pParentItemSet ); + + pOutSet.reset( new SfxItemSet( rStyleBase.GetItemSet() ) ); + pOutSet->ClearItem(); + + // If there is no bullet item in this stylesheet, we get it + // from 'Outline 1' style sheet. + const SfxPoolItem *pItem = nullptr; + if( SfxItemState::SET != aInputSet.GetItemState(EE_PARA_NUMBULLET, false, &pItem )) + { + OUString aStyleName(SdResId(STR_PSEUDOSHEET_OUTLINE) + " 1"); + SfxStyleSheetBase* pFirstStyleSheet = pSSPool->Find( aStyleName, SfxStyleFamily::Pseudo); + + if(pFirstStyleSheet) + if( SfxItemState::SET == pFirstStyleSheet->GetItemSet().GetItemState(EE_PARA_NUMBULLET, false, &pItem) ) + aInputSet.Put( *pItem ); + } + + // preselect selected layer in dialog + aInputSet.Put( SfxUInt16Item( SID_PARAM_CUR_NUM_LEVEL, 1<<GetOutlineLevel())); + + SetInputSet(&aInputSet); + } + else { + SetInputSet(pOrgSet); + } + + SvxColorListItem const *pColorListItem = mpDocShell->GetItem( SID_COLOR_TABLE ); + SvxGradientListItem const *pGradientListItem = mpDocShell->GetItem( SID_GRADIENT_LIST ); + SvxBitmapListItem const *pBitmapListItem = mpDocShell->GetItem( SID_BITMAP_LIST ); + SvxPatternListItem const *pPatternListItem = mpDocShell->GetItem( SID_PATTERN_LIST ); + SvxHatchListItem const *pHatchListItem = mpDocShell->GetItem( SID_HATCH_LIST ); + SvxDashListItem const *pDashListItem = mpDocShell->GetItem( SID_DASH_LIST ); + SvxLineEndListItem const *pLineEndListItem = mpDocShell->GetItem( SID_LINEEND_LIST ); + + pColorTab = pColorListItem->GetColorList(); + pDashList = pDashListItem->GetDashList(); + pLineEndList = pLineEndListItem->GetLineEndList(); + pGradientList = pGradientListItem->GetGradientList(); + pHatchingList = pHatchListItem->GetHatchList(); + pBitmapList = pBitmapListItem->GetBitmapList(); + pPatternList = pPatternListItem->GetPatternList(); + + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + + AddTabPage( "RID_SVXPAGE_LINE", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_LINE ), nullptr ); + AddTabPage( "RID_SVXPAGE_AREA", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_AREA ), nullptr ); + AddTabPage( "RID_SVXPAGE_SHADOW", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_SHADOW ), nullptr ); + AddTabPage( "RID_SVXPAGE_TRANSPARENCE", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TRANSPARENCE ), nullptr ); + AddTabPage( "RID_SVXPAGE_CHAR_NAME", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_NAME ), nullptr ); + AddTabPage( "RID_SVXPAGE_CHAR_EFFECTS", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_CHAR_EFFECTS ), nullptr ); + AddTabPage( "RID_SVXPAGE_STD_PARAGRAPH", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_STD_PARAGRAPH ), nullptr ); + AddTabPage( "RID_SVXPAGE_TEXTATTR", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TEXTATTR ), nullptr ); + AddTabPage( "RID_SVXPAGE_PICK_BULLET", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PICK_BULLET ), nullptr ); + AddTabPage( "RID_SVXPAGE_PICK_SINGLE_NUM", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PICK_SINGLE_NUM ), nullptr ); + AddTabPage( "RID_SVXPAGE_PICK_BMP", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PICK_BMP ), nullptr ); + AddTabPage( "RID_SVXPAGE_NUM_OPTIONS", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUM_OPTIONS ), nullptr ); + AddTabPage( "RID_SVXPAGE_TABULATOR", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_TABULATOR ), nullptr ); + AddTabPage( "RID_SVXPAGE_PARA_ASIAN", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_PARA_ASIAN ), nullptr ); + AddTabPage( "RID_SVXPAGE_ALIGN_PARAGRAPH", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_ALIGN_PARAGRAPH ), nullptr ); + AddTabPage( "RID_SVXPAGE_BKG", pFact->GetTabPageCreatorFunc( RID_SVXPAGE_BKG ), nullptr); + + if( !SvtCJKOptions::IsAsianTypographyEnabled() ) + RemoveTabPage( "RID_SVXPAGE_PARA_ASIAN" ); + + if (bBackground) + { + RemoveTabPage( "RID_SVXPAGE_LINE"); + + RemoveTabPage( "RID_SVXPAGE_SHADOW"); + RemoveTabPage( "RID_SVXPAGE_TRANSPARENCE"); + RemoveTabPage( "RID_SVXPAGE_CHAR_NAME"); + RemoveTabPage( "RID_SVXPAGE_CHAR_EFFECTS"); + RemoveTabPage( "RID_SVXPAGE_STD_PARAGRAPH"); + RemoveTabPage( "RID_SVXPAGE_TEXTATTR"); + RemoveTabPage( "RID_SVXPAGE_PICK_BULLET"); + RemoveTabPage( "RID_SVXPAGE_PICK_SINGLE_NUM"); + RemoveTabPage( "RID_SVXPAGE_PICK_BMP"); + RemoveTabPage( "RID_SVXPAGE_NUM_OPTIONS"); + RemoveTabPage( "RID_SVXPAGE_TABULATOR"); + RemoveTabPage( "RID_SVXPAGE_ALIGN_PARAGRAPH"); + RemoveTabPage( "RID_SVXPAGE_PARA_ASIAN" ); + RemoveTabPage( "RID_SVXPAGE_BKG" ); + } + + // set title and add corresponding pages to dialog + OUString aTitle; + + switch( ePO ) + { + case PresentationObjects::Title: + aTitle = SdResId(STR_PSEUDOSHEET_TITLE); + break; + + case PresentationObjects::Subtitle: + aTitle = SdResId(STR_PSEUDOSHEET_SUBTITLE); + break; + + case PresentationObjects::Background: + aTitle = SdResId(STR_PSEUDOSHEET_BACKGROUND); + break; + + case PresentationObjects::BackgroundObjects: + aTitle = SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS); + break; + + case PresentationObjects::Outline_1: + case PresentationObjects::Outline_2: + case PresentationObjects::Outline_3: + case PresentationObjects::Outline_4: + case PresentationObjects::Outline_5: + case PresentationObjects::Outline_6: + case PresentationObjects::Outline_7: + case PresentationObjects::Outline_8: + case PresentationObjects::Outline_9: + aTitle = SdResId(STR_PSEUDOSHEET_OUTLINE) + " " + + OUString::number( static_cast<int>(ePO) - static_cast<int>(PresentationObjects::Outline_1) + 1 ); + break; + + case PresentationObjects::Notes: + aTitle = SdResId(STR_PSEUDOSHEET_NOTES); + break; + } + m_xDialog->set_title(aTitle); +} + +SdPresLayoutTemplateDlg::~SdPresLayoutTemplateDlg() +{ +} + +void SdPresLayoutTemplateDlg::PageCreated(const OString& rId, SfxTabPage &rPage) +{ + SfxAllItemSet aSet(*(aInputSet.GetPool())); + + if (rId == "RID_SVXPAGE_LINE") + { + aSet.Put (SvxColorListItem(pColorTab,SID_COLOR_TABLE)); + aSet.Put (SvxDashListItem(pDashList,SID_DASH_LIST)); + aSet.Put (SvxLineEndListItem(pLineEndList,SID_LINEEND_LIST)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_AREA") + { + aSet.Put (SvxColorListItem(pColorTab,SID_COLOR_TABLE)); + aSet.Put (SvxGradientListItem(pGradientList,SID_GRADIENT_LIST)); + aSet.Put (SvxHatchListItem(pHatchingList,SID_HATCH_LIST)); + aSet.Put (SvxBitmapListItem(pBitmapList,SID_BITMAP_LIST)); + aSet.Put (SvxPatternListItem(pPatternList,SID_PATTERN_LIST)); + aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + aSet.Put (SfxUInt16Item(SID_TABPAGE_POS,0)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_SHADOW") + { + aSet.Put (SvxColorListItem(pColorTab,SID_COLOR_TABLE)); + aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_TRANSPARENCE") + { + aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_CHAR_NAME") + { + SvxFontListItem aItem(*static_cast<const SvxFontListItem*>(mpDocShell->GetItem( SID_ATTR_CHAR_FONTLIST) ) ); + aSet.Put (SvxFontListItem( aItem.GetFontList(), SID_ATTR_CHAR_FONTLIST)); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_CHAR_EFFECTS") + { + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_TEXTATTR") + { + aSet.Put(CntUInt16Item(SID_SVXTEXTATTRPAGE_OBJKIND, static_cast<sal_uInt16>(SdrObjKind::Text))); + rPage.PageCreated(aSet); + } + else if (rId == "RID_SVXPAGE_BKG") + { + aSet.Put(SfxUInt32Item(SID_FLAG_TYPE,static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR))); + rPage.PageCreated(aSet); + } +} + +const SfxItemSet* SdPresLayoutTemplateDlg::GetOutputItemSet() const +{ + if (pOutSet) + { + pOutSet->Put(*SfxTabDialogController::GetOutputItemSet()); + + const SvxNumBulletItem *pSvxNumBulletItem = pOutSet->GetItemIfSet(EE_PARA_NUMBULLET, false); + if (pSvxNumBulletItem) + SdBulletMapper::MapFontsInNumRule( const_cast<SvxNumRule&>(pSvxNumBulletItem->GetNumRule()), *pOutSet ); + return pOutSet.get(); + } + else + return SfxTabDialogController::GetOutputItemSet(); +} + +sal_uInt16 SdPresLayoutTemplateDlg::GetOutlineLevel() const +{ + switch( ePO ) + { + case PresentationObjects::Outline_1: return 0; + case PresentationObjects::Outline_2: return 1; + case PresentationObjects::Outline_3: return 2; + case PresentationObjects::Outline_4: return 3; + case PresentationObjects::Outline_5: return 4; + case PresentationObjects::Outline_6: return 5; + case PresentationObjects::Outline_7: return 6; + case PresentationObjects::Outline_8: return 7; + case PresentationObjects::Outline_9: return 8; + default: + SAL_WARN( "sd", "Wrong Po! [CL]"); + } + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/prntopts.cxx b/sd/source/ui/dlg/prntopts.cxx new file mode 100644 index 000000000..4b50875bb --- /dev/null +++ b/sd/source/ui/dlg/prntopts.cxx @@ -0,0 +1,235 @@ +/* -*- 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 <sdattr.hrc> +#include <optsitem.hxx> +#include <prntopts.hxx> +#include <app.hrc> +#include <svl/intitem.hxx> + +/** + * dialog to adjust print options + */ +SdPrintOptions::SdPrintOptions(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs) + : SfxTabPage(pPage, pController, "modules/simpress/ui/prntopts.ui", "prntopts", &rInAttrs) + , m_xFrmContent(m_xBuilder->weld_frame("contentframe")) + , m_xCbxDraw(m_xBuilder->weld_check_button("drawingcb")) + , m_xCbxNotes(m_xBuilder->weld_check_button("notecb")) + , m_xCbxHandout(m_xBuilder->weld_check_button("handoutcb")) + , m_xCbxOutline(m_xBuilder->weld_check_button("outlinecb")) + , m_xRbtColor(m_xBuilder->weld_radio_button("defaultrb")) + , m_xRbtGrayscale(m_xBuilder->weld_radio_button("grayscalerb")) + , m_xRbtBlackWhite(m_xBuilder->weld_radio_button("blackwhiterb")) + , m_xCbxPagename(m_xBuilder->weld_check_button("pagenmcb")) + , m_xCbxDate(m_xBuilder->weld_check_button("datecb")) + , m_xCbxTime(m_xBuilder->weld_check_button("timecb")) + , m_xCbxHiddenPages(m_xBuilder->weld_check_button("hiddenpgcb")) + , m_xRbtDefault(m_xBuilder->weld_radio_button("pagedefaultrb")) + , m_xRbtPagesize(m_xBuilder->weld_radio_button("fittopgrb")) + , m_xRbtPagetile(m_xBuilder->weld_radio_button("tilepgrb")) + , m_xRbtBooklet(m_xBuilder->weld_radio_button("brouchrb")) + , m_xCbxFront(m_xBuilder->weld_check_button("frontcb")) + , m_xCbxBack(m_xBuilder->weld_check_button("backcb")) + , m_xCbxPaperbin(m_xBuilder->weld_check_button("papertryfrmprntrcb")) +{ + Link<weld::Toggleable&,void> aLink = LINK( this, SdPrintOptions, ClickBookletHdl ); + m_xRbtDefault->connect_toggled( aLink ); + m_xRbtPagesize->connect_toggled( aLink ); + m_xRbtPagetile->connect_toggled( aLink ); + m_xRbtBooklet->connect_toggled( aLink ); + + aLink = LINK( this, SdPrintOptions, ClickCheckboxHdl ); + m_xCbxDraw->connect_toggled( aLink ); + m_xCbxNotes->connect_toggled( aLink ); + m_xCbxHandout->connect_toggled( aLink ); + m_xCbxOutline->connect_toggled( aLink ); + +#ifndef MACOSX + SetDrawMode(); +#endif +} + +SdPrintOptions::~SdPrintOptions() +{ +} + +bool SdPrintOptions::FillItemSet( SfxItemSet* rAttrs ) +{ + if( m_xCbxDraw->get_state_changed_from_saved() || + m_xCbxNotes->get_state_changed_from_saved() || + m_xCbxHandout->get_state_changed_from_saved() || + m_xCbxOutline->get_state_changed_from_saved() || + m_xCbxDate->get_state_changed_from_saved() || + m_xCbxTime->get_state_changed_from_saved() || + m_xCbxPagename->get_state_changed_from_saved() || + m_xCbxHiddenPages->get_state_changed_from_saved() || + m_xRbtPagesize->get_state_changed_from_saved() || + m_xRbtPagetile->get_state_changed_from_saved() || + m_xRbtBooklet->get_state_changed_from_saved() || + m_xCbxFront->get_state_changed_from_saved() || + m_xCbxBack->get_state_changed_from_saved() || + m_xCbxPaperbin->get_state_changed_from_saved() || + m_xRbtColor->get_state_changed_from_saved() || + m_xRbtGrayscale->get_state_changed_from_saved()|| + m_xRbtBlackWhite->get_state_changed_from_saved()) + { + SdOptionsPrintItem aOptions; + + aOptions.GetOptionsPrint().SetDraw( m_xCbxDraw->get_active() ); + aOptions.GetOptionsPrint().SetNotes( m_xCbxNotes->get_active() ); + aOptions.GetOptionsPrint().SetHandout( m_xCbxHandout->get_active() ); + aOptions.GetOptionsPrint().SetOutline( m_xCbxOutline->get_active() ); + aOptions.GetOptionsPrint().SetDate( m_xCbxDate->get_active() ); + aOptions.GetOptionsPrint().SetTime( m_xCbxTime->get_active() ); + aOptions.GetOptionsPrint().SetPagename( m_xCbxPagename->get_active() ); + aOptions.GetOptionsPrint().SetHiddenPages( m_xCbxHiddenPages->get_active() ); + aOptions.GetOptionsPrint().SetPagesize( m_xRbtPagesize->get_active() ); + aOptions.GetOptionsPrint().SetPagetile( m_xRbtPagetile->get_active() ); + aOptions.GetOptionsPrint().SetBooklet( m_xRbtBooklet->get_active() ); + aOptions.GetOptionsPrint().SetFrontPage( m_xCbxFront->get_active() ); + aOptions.GetOptionsPrint().SetBackPage( m_xCbxBack->get_active() ); + aOptions.GetOptionsPrint().SetPaperbin( m_xCbxPaperbin->get_active() ); + + sal_uInt16 nQuality = 0; // Standard, also Color + if( m_xRbtGrayscale->get_active() ) + nQuality = 1; + if( m_xRbtBlackWhite->get_active() ) + nQuality = 2; + aOptions.GetOptionsPrint().SetOutputQuality( nQuality ); + + rAttrs->Put( aOptions ); + + return true; + } + return false; +} + +void SdPrintOptions::Reset( const SfxItemSet* rAttrs ) +{ + const SdOptionsPrintItem* pPrintOpts = rAttrs->GetItemIfSet( ATTR_OPTIONS_PRINT, false); + if( pPrintOpts ) + { + m_xCbxDraw->set_active( pPrintOpts->GetOptionsPrint().IsDraw() ); + m_xCbxNotes->set_active( pPrintOpts->GetOptionsPrint().IsNotes() ); + m_xCbxHandout->set_active( pPrintOpts->GetOptionsPrint().IsHandout() ); + m_xCbxOutline->set_active( pPrintOpts->GetOptionsPrint().IsOutline() ); + m_xCbxDate->set_active( pPrintOpts->GetOptionsPrint().IsDate() ); + m_xCbxTime->set_active( pPrintOpts->GetOptionsPrint().IsTime() ); + m_xCbxPagename->set_active( pPrintOpts->GetOptionsPrint().IsPagename() ); + m_xCbxHiddenPages->set_active( pPrintOpts->GetOptionsPrint().IsHiddenPages() ); + m_xRbtPagesize->set_active( pPrintOpts->GetOptionsPrint().IsPagesize() ); + m_xRbtPagetile->set_active( pPrintOpts->GetOptionsPrint().IsPagetile() ); + m_xRbtBooklet->set_active( pPrintOpts->GetOptionsPrint().IsBooklet() ); + m_xCbxFront->set_active( pPrintOpts->GetOptionsPrint().IsFrontPage() ); + m_xCbxBack->set_active( pPrintOpts->GetOptionsPrint().IsBackPage() ); + m_xCbxPaperbin->set_active( pPrintOpts->GetOptionsPrint().IsPaperbin() ); + + if( !m_xRbtPagesize->get_active() && + !m_xRbtPagetile->get_active() && + !m_xRbtBooklet->get_active() ) + { + m_xRbtDefault->set_active(true); + } + + sal_uInt16 nQuality = pPrintOpts->GetOptionsPrint().GetOutputQuality(); + if( nQuality == 0 ) + m_xRbtColor->set_active(true); + else if( nQuality == 1 ) + m_xRbtGrayscale->set_active(true); + else + m_xRbtBlackWhite->set_active(true); + } + m_xCbxDraw->save_state(); + m_xCbxNotes->save_state(); + m_xCbxHandout->save_state(); + m_xCbxOutline->save_state(); + m_xCbxDate->save_state(); + m_xCbxTime->save_state(); + m_xCbxPagename->save_state(); + m_xCbxHiddenPages->save_state(); + m_xRbtPagesize->save_state(); + m_xRbtPagetile->save_state(); + m_xRbtBooklet->save_state(); + m_xCbxPaperbin->save_state(); + m_xRbtColor->save_state(); + m_xRbtGrayscale->save_state(); + m_xRbtBlackWhite->save_state(); + + updateControls(); +} + +std::unique_ptr<SfxTabPage> SdPrintOptions::Create( weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet* rOutAttrs ) +{ + return std::make_unique<SdPrintOptions>( pPage, pController, *rOutAttrs ); +} + +IMPL_LINK(SdPrintOptions, ClickCheckboxHdl, weld::Toggleable&, rCbx, void) +{ + // there must be at least one of them checked + if( !m_xCbxDraw->get_active() && !m_xCbxNotes->get_active() && !m_xCbxOutline->get_active() && !m_xCbxHandout->get_active() ) + rCbx.set_active(true); + + updateControls(); +} + +IMPL_LINK_NOARG(SdPrintOptions, ClickBookletHdl, weld::Toggleable&, void) +{ + updateControls(); +} + +void SdPrintOptions::updateControls() +{ + m_xCbxFront->set_sensitive(m_xRbtBooklet->get_active()); + m_xCbxBack->set_sensitive(m_xRbtBooklet->get_active()); + + m_xCbxDate->set_sensitive( !m_xRbtBooklet->get_active() ); + m_xCbxTime->set_sensitive( !m_xRbtBooklet->get_active() ); + + m_xCbxPagename->set_sensitive( !m_xRbtBooklet->get_active() && (m_xCbxDraw->get_active() || m_xCbxNotes->get_active() || m_xCbxOutline->get_active()) ); +} + +void SdPrintOptions::SetDrawMode() +{ + if (m_xCbxNotes->get_visible()) + { + m_xFrmContent->hide(); + } +} + +void SdPrintOptions::PageCreated (const SfxAllItemSet& +#ifdef MACOSX + aSet +#endif + ) +{ +#ifdef MACOSX + const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_SDMODE_FLAG, false); + if (pFlagItem) + { + sal_uInt32 nFlags=pFlagItem->GetValue(); + if ( ( nFlags & SD_DRAW_MODE ) == SD_DRAW_MODE ) + SetDrawMode(); + } +#else + SetDrawMode(); +#endif +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/sdabstdlg.cxx b/sd/source/ui/dlg/sdabstdlg.cxx new file mode 100644 index 000000000..2b686a3e8 --- /dev/null +++ b/sd/source/ui/dlg/sdabstdlg.cxx @@ -0,0 +1,55 @@ +/* -*- 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 <sdabstdlg.hxx> + +#include <osl/module.hxx> + +typedef SdAbstractDialogFactory* (*SdFuncPtrCreateDialogFactory)(); + +#ifndef DISABLE_DYNLOADING + +extern "C" { +static void thisModule() {} +} + +#else + +extern "C" SdAbstractDialogFactory* SdCreateDialogFactory(); + +#endif + +SdAbstractDialogFactory* SdAbstractDialogFactory::Create() +{ + SdFuncPtrCreateDialogFactory fp = nullptr; +#ifndef DISABLE_DYNLOADING + static ::osl::Module aDialogLibrary; + static constexpr OUStringLiteral sLibName(u"" SDUI_DLL_NAME); + if (aDialogLibrary.is() || aDialogLibrary.loadRelative(&thisModule, sLibName)) + fp = reinterpret_cast<SdAbstractDialogFactory*(SAL_CALL*)()>( + aDialogLibrary.getFunctionSymbol("SdCreateDialogFactory")); +#else + fp = SdCreateDialogFactory; +#endif + if (fp) + return fp(); + return nullptr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/sddlgfact.cxx b/sd/source/ui/dlg/sddlgfact.cxx new file mode 100644 index 000000000..c526df75d --- /dev/null +++ b/sd/source/ui/dlg/sddlgfact.cxx @@ -0,0 +1,739 @@ +/* -*- 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 "sddlgfact.hxx" +#include <BreakDlg.hxx> +#include <copydlg.hxx> +#include <custsdlg.hxx> +#include <dlg_char.hxx> +#include <dlgpage.hxx> +#include <dlgfield.hxx> +#include <dlgsnap.hxx> +#include <layeroptionsdlg.hxx> +#include <inspagob.hxx> +#include <morphdlg.hxx> +#include <OutlineBulletDlg.hxx> +#include <paragr.hxx> +#include <present.hxx> +#include "RemoteDialog.hxx" +#include <prltempl.hxx> +#include <sdpreslt.hxx> +#include <tabtempl.hxx> +#include <tpaction.hxx> +#include <vectdlg.hxx> +#include <tpoption.hxx> +#include <prntopts.hxx> +#include <pubdlg.hxx> +#include <masterlayoutdlg.hxx> +#include <headerfooterdlg.hxx> +#include "PhotoAlbumDialog.hxx" +#include <vcl/virdev.hxx> + +short AbstractSvxBulletAndPositionDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short SdAbstractGenericDialog_Impl::Execute() +{ + return m_xDlg->run(); +} + +BitmapEx SdAbstractGenericDialog_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString SdAbstractGenericDialog_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +const SfxItemSet* AbstractSvxBulletAndPositionDlg_Impl::GetOutputItemSet( SfxItemSet* pSet ) const +{ + return m_xDlg->GetOutputItemSet( pSet ); +} + +bool AbstractSvxBulletAndPositionDlg_Impl::IsApplyToMaster() +{ + return m_xDlg->IsApplyToMaster(); +} + +bool AbstractSvxBulletAndPositionDlg_Impl::IsSlideScope() +{ + return m_xDlg->IsSlideScope(); +} + +short AbstractCopyDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdCustomShowDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short SdPresLayoutTemplateDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +bool SdPresLayoutTemplateDlg_Impl::StartExecuteAsync(AsyncContext &rCtx) +{ + return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn); +} + +short AbstractSdModifyFieldDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdSnapLineDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdInsertLayerDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdInsertPagesObjsDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractMorphDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdStartPresDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdPresLayoutDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short SdAbstractSfxDialog_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdVectorizeDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractSdPublishingDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +short AbstractHeaderFooterDialog_Impl::Execute() +{ + return m_xDlg->run(); +} + +bool AbstractHeaderFooterDialog_Impl::StartExecuteAsync(AsyncContext &rCtx) +{ + return weld::DialogController::runAsync(m_xDlg, rCtx.maEndDialogFn); +} + +BitmapEx AbstractHeaderFooterDialog_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractHeaderFooterDialog_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +short AbstractBulletDialog_Impl::Execute() +{ + return m_xDlg->run(); +} + +bool AbstractBulletDialog_Impl::StartExecuteAsync(AsyncContext &rCtx) +{ + return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn); +} + +AbstractBreakDlg_Impl::AbstractBreakDlg_Impl(std::unique_ptr<::sd::BreakDlg> pDlg) + : m_xDlg(std::move(pDlg)) +{ +} + +short AbstractBreakDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + +BitmapEx AbstractBreakDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractBreakDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +AbstractMasterLayoutDialog_Impl::AbstractMasterLayoutDialog_Impl(std::unique_ptr<::sd::MasterLayoutDialog> pDlg) + : m_xDlg(std::move(pDlg)) +{ +} + +short AbstractMasterLayoutDialog_Impl::Execute() +{ + return m_xDlg->run(); +} + +BitmapEx AbstractMasterLayoutDialog_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractMasterLayoutDialog_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractCopyDlg_Impl::GetAttr( SfxItemSet& rOutAttrs ) +{ + m_xDlg->GetAttr( rOutAttrs ); +} + +BitmapEx AbstractCopyDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractCopyDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +bool AbstractSdCustomShowDlg_Impl::IsCustomShow() const +{ + return m_xDlg->IsCustomShow(); +} + +BitmapEx AbstractSdCustomShowDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdCustomShowDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +short SdAbstractTabController_Impl::Execute() +{ + return m_xDlg->run(); +} + +void SdAbstractTabController_Impl::SetCurPageId( const OString &rName ) +{ + m_xDlg->SetCurPageId( rName ); +} + +const SfxItemSet* SdAbstractTabController_Impl::GetOutputItemSet() const +{ + return m_xDlg->GetOutputItemSet(); +} + +WhichRangesContainer SdAbstractTabController_Impl::GetInputRanges(const SfxItemPool& pItem ) +{ + return m_xDlg->GetInputRanges( pItem ); +} + +void SdAbstractTabController_Impl::SetInputSet( const SfxItemSet* pInSet ) +{ + m_xDlg->SetInputSet( pInSet ); +} + +bool SdAbstractTabController_Impl::StartExecuteAsync(AsyncContext &rCtx) +{ + return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn); +} + +//From class Window. +void SdAbstractTabController_Impl::SetText( const OUString& rStr ) +{ + m_xDlg->set_title(rStr); +} + +BitmapEx SdAbstractTabController_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString SdAbstractTabController_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractBulletDialog_Impl::SetCurPageId( const OString& rName ) +{ + m_xDlg->SetCurPageId( rName ); +} + +const SfxItemSet* AbstractBulletDialog_Impl::GetOutputItemSet() const +{ + return static_cast< ::sd::OutlineBulletDlg*>(m_xDlg.get())->GetBulletOutputItemSet(); +} + +WhichRangesContainer AbstractBulletDialog_Impl::GetInputRanges(const SfxItemPool& pItem ) +{ + return m_xDlg->GetInputRanges(pItem); +} + +void AbstractBulletDialog_Impl::SetInputSet( const SfxItemSet* pInSet ) +{ + m_xDlg->SetInputSet(pInSet); +} + +void AbstractBulletDialog_Impl::SetText( const OUString& rStr ) +{ + m_xDlg->set_title(rStr); +} + +BitmapEx AbstractBulletDialog_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractBulletDialog_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void SdPresLayoutTemplateDlg_Impl::SetCurPageId( const OString& rName ) +{ + m_xDlg->SetCurPageId( rName ); +} + +const SfxItemSet* SdPresLayoutTemplateDlg_Impl::GetOutputItemSet() const +{ + return m_xDlg->GetOutputItemSet(); +} + +WhichRangesContainer SdPresLayoutTemplateDlg_Impl::GetInputRanges(const SfxItemPool& pItem ) +{ + return m_xDlg->GetInputRanges( pItem ); +} + +void SdPresLayoutTemplateDlg_Impl::SetInputSet( const SfxItemSet* pInSet ) +{ + m_xDlg->SetInputSet( pInSet ); +} + +void SdPresLayoutTemplateDlg_Impl::SetText( const OUString& rStr ) +{ + m_xDlg->set_title(rStr); +} + +BitmapEx SdPresLayoutTemplateDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString SdPresLayoutTemplateDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +SvxFieldData* AbstractSdModifyFieldDlg_Impl::GetField() +{ + return m_xDlg->GetField(); +} + +SfxItemSet AbstractSdModifyFieldDlg_Impl::GetItemSet() +{ + return m_xDlg->GetItemSet(); +} + +BitmapEx AbstractSdModifyFieldDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdModifyFieldDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractSdSnapLineDlg_Impl::GetAttr(SfxItemSet& rOutAttrs) +{ + m_xDlg->GetAttr(rOutAttrs); +} + +void AbstractSdSnapLineDlg_Impl::HideRadioGroup() +{ + m_xDlg->HideRadioGroup(); +} + +void AbstractSdSnapLineDlg_Impl::HideDeleteBtn() +{ + m_xDlg->HideDeleteBtn(); +} + +void AbstractSdSnapLineDlg_Impl::SetInputFields(bool bEnableX, bool bEnableY) +{ + m_xDlg->SetInputFields(bEnableX, bEnableY); +} + +void AbstractSdSnapLineDlg_Impl::SetText( const OUString& rStr ) +{ + m_xDlg->set_title(rStr); +} + +BitmapEx AbstractSdSnapLineDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdSnapLineDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractSdInsertLayerDlg_Impl::GetAttr( SfxItemSet& rOutAttrs ) +{ + m_xDlg->GetAttr(rOutAttrs); +} + +void AbstractSdInsertLayerDlg_Impl::SetHelpId( const OString& rHelpId ) +{ + m_xDlg->set_help_id(rHelpId); +} + +BitmapEx AbstractSdInsertLayerDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdInsertLayerDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +std::vector<OUString> AbstractSdInsertPagesObjsDlg_Impl::GetList(const sal_uInt16 nType) +{ + return m_xDlg->GetList(nType); +} + +bool AbstractSdInsertPagesObjsDlg_Impl::IsLink() +{ + return m_xDlg->IsLink(); +} + +bool AbstractSdInsertPagesObjsDlg_Impl::IsRemoveUnnecessaryMasterPages() const +{ + return m_xDlg->IsRemoveUnnecessaryMasterPages(); +} + +BitmapEx AbstractSdInsertPagesObjsDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdInsertPagesObjsDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractMorphDlg_Impl::SaveSettings() const +{ + m_xDlg->SaveSettings(); +} + +sal_uInt16 AbstractMorphDlg_Impl::GetFadeSteps() const +{ + return m_xDlg->GetFadeSteps(); +} + +bool AbstractMorphDlg_Impl::IsAttributeFade() const +{ + return m_xDlg->IsAttributeFade(); +} + +bool AbstractMorphDlg_Impl::IsOrientationFade() const +{ + return m_xDlg->IsOrientationFade(); +} + +BitmapEx AbstractMorphDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractMorphDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractSdStartPresDlg_Impl::GetAttr( SfxItemSet& rOutAttrs ) +{ + m_xDlg->GetAttr(rOutAttrs); +} + +BitmapEx AbstractSdStartPresDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdStartPresDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractSdPresLayoutDlg_Impl::GetAttr( SfxItemSet& rOutAttrs ) +{ + m_xDlg->GetAttr(rOutAttrs); +} + +BitmapEx AbstractSdPresLayoutDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdPresLayoutDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +const SfxItemSet* SdAbstractSfxDialog_Impl::GetOutputItemSet() const +{ + return m_xDlg->GetOutputItemSet(); +} + +void SdAbstractSfxDialog_Impl::SetText( const OUString& rStr ) +{ + m_xDlg->set_title(rStr); +} + +const GDIMetaFile& AbstractSdVectorizeDlg_Impl::GetGDIMetaFile() const +{ + return m_xDlg->GetGDIMetaFile(); +} + +BitmapEx AbstractSdVectorizeDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdVectorizeDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +void AbstractSdPublishingDlg_Impl::GetParameterSequence( css::uno::Sequence< css::beans::PropertyValue >& rParams ) +{ + m_xDlg->GetParameterSequence( rParams ); +} + +BitmapEx AbstractSdPublishingDlg_Impl::createScreenshot() const +{ + VclPtr<VirtualDevice> xDialogSurface(m_xDlg->getDialog()->screenshot()); + return xDialogSurface->GetBitmapEx(Point(), xDialogSurface->GetOutputSizePixel()); +} + +OString AbstractSdPublishingDlg_Impl::GetScreenshotId() const +{ + return m_xDlg->get_help_id(); +} + +//-------------- SdAbstractDialogFactory implementation-------------- + +VclPtr<AbstractSvxBulletAndPositionDlg> SdAbstractDialogFactory_Impl::CreateSvxBulletAndPositionDlg(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView) +{ + return VclPtr<AbstractSvxBulletAndPositionDlg_Impl>::Create(std::make_unique<SvxBulletAndPositionDlg>(pParent, *pAttr, pView)); +} + +VclPtr<VclAbstractDialog> SdAbstractDialogFactory_Impl::CreateBreakDlg( + weld::Window* pParent, + ::sd::DrawView* pDrView, + ::sd::DrawDocShell* pShell, + sal_uLong nSumActionCount, + sal_uLong nObjCount ) +{ + return VclPtr<AbstractBreakDlg_Impl>::Create(std::make_unique<::sd::BreakDlg>(pParent, pDrView, pShell, nSumActionCount, nObjCount)); +} + +VclPtr<AbstractCopyDlg> SdAbstractDialogFactory_Impl::CreateCopyDlg(weld::Window* pParent, + const SfxItemSet& rInAttrs, + ::sd::View* pView ) +{ + return VclPtr<AbstractCopyDlg_Impl>::Create(std::make_unique<::sd::CopyDlg>(pParent, rInAttrs, pView)); +} + +VclPtr<AbstractSdCustomShowDlg> SdAbstractDialogFactory_Impl::CreateSdCustomShowDlg(weld::Window* pParent, SdDrawDocument& rDrawDoc ) +{ + return VclPtr<AbstractSdCustomShowDlg_Impl>::Create(std::make_unique<SdCustomShowDlg>(pParent, rDrawDoc)); +} + +VclPtr<SfxAbstractTabDialog> SdAbstractDialogFactory_Impl::CreateSdTabCharDialog(weld::Window* pParent, const SfxItemSet* pAttr, SfxObjectShell* pDocShell) +{ + return VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdCharDlg>(pParent, pAttr, pDocShell)); +} + +VclPtr<SfxAbstractTabDialog> SdAbstractDialogFactory_Impl::CreateSdTabPageDialog(weld::Window* pParent, const SfxItemSet* pAttr, SfxObjectShell* pDocShell, bool bAreaPage, bool bIsImpressDoc, bool bIsImpressMaster ) +{ + return VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdPageDlg>(pDocShell, pParent, pAttr, bAreaPage, bIsImpressDoc, bIsImpressMaster)); +} + +VclPtr<AbstractSdModifyFieldDlg> SdAbstractDialogFactory_Impl::CreateSdModifyFieldDlg(weld::Window* pParent, const SvxFieldData* pInField, const SfxItemSet& rSet) +{ + return VclPtr<AbstractSdModifyFieldDlg_Impl>::Create(std::make_unique<SdModifyFieldDlg>(pParent, pInField, rSet)); +} + +VclPtr<AbstractSdSnapLineDlg> SdAbstractDialogFactory_Impl::CreateSdSnapLineDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, ::sd::View* pView) +{ + return VclPtr<AbstractSdSnapLineDlg_Impl>::Create(std::make_unique<SdSnapLineDlg>(pParent, rInAttrs, pView)); +} + +VclPtr<AbstractSdInsertLayerDlg> SdAbstractDialogFactory_Impl::CreateSdInsertLayerDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, bool bDeletable, const OUString& aStr) +{ + return VclPtr<AbstractSdInsertLayerDlg_Impl>::Create(std::make_unique<SdInsertLayerDlg>(pParent, rInAttrs, bDeletable, aStr)); +} + +VclPtr<AbstractSdInsertPagesObjsDlg> SdAbstractDialogFactory_Impl::CreateSdInsertPagesObjsDlg(weld::Window* pParent, const SdDrawDocument* pDoc, SfxMedium* pSfxMedium, const OUString& rFileName) +{ + return VclPtr<AbstractSdInsertPagesObjsDlg_Impl>::Create(std::make_unique<SdInsertPagesObjsDlg>(pParent, pDoc, pSfxMedium, rFileName)); +} + +VclPtr<AbstractMorphDlg> SdAbstractDialogFactory_Impl::CreateMorphDlg(weld::Window* pParent, const SdrObject* pObj1, const SdrObject* pObj2) +{ + return VclPtr<AbstractMorphDlg_Impl>::Create(std::make_unique<::sd::MorphDlg>(pParent, pObj1, pObj2)); +} + +VclPtr<SfxAbstractTabDialog> SdAbstractDialogFactory_Impl::CreateSdOutlineBulletTabDlg(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView) +{ + return VclPtr<AbstractBulletDialog_Impl>::Create(std::make_shared<::sd::OutlineBulletDlg>(pParent, pAttr, pView)); +} + +VclPtr<SfxAbstractTabDialog> SdAbstractDialogFactory_Impl::CreateSdParagraphTabDlg(weld::Window* pParent, const SfxItemSet* pAttr ) +{ + return VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdParagraphDlg>(pParent, pAttr)); +} + +VclPtr<AbstractSdStartPresDlg> SdAbstractDialogFactory_Impl::CreateSdStartPresentationDlg(weld::Window* pParent, + const SfxItemSet& rInAttrs, const std::vector<OUString> &rPageNames, SdCustomShowList* pCSList) +{ + return VclPtr<AbstractSdStartPresDlg_Impl>::Create(std::make_unique<SdStartPresentationDlg>(pParent, rInAttrs, rPageNames, pCSList)); +} + +VclPtr<VclAbstractDialog> SdAbstractDialogFactory_Impl::CreateRemoteDialog(weld::Window* pParent) +{ + return VclPtr<SdAbstractGenericDialog_Impl>::Create(std::make_unique<::sd::RemoteDialog>(pParent)); +} + +VclPtr<SfxAbstractTabDialog> SdAbstractDialogFactory_Impl::CreateSdPresLayoutTemplateDlg(SfxObjectShell* pDocSh, weld::Window* pParent, bool bBackgroundDlg, SfxStyleSheetBase& rStyleBase, PresentationObjects ePO, SfxStyleSheetBasePool* pSSPool) +{ + return VclPtr<SdPresLayoutTemplateDlg_Impl>::Create(std::make_shared<SdPresLayoutTemplateDlg>(pDocSh, pParent, bBackgroundDlg, rStyleBase, ePO, pSSPool)); +} + +VclPtr<AbstractSdPresLayoutDlg> SdAbstractDialogFactory_Impl::CreateSdPresLayoutDlg(weld::Window* pParent, ::sd::DrawDocShell* pDocShell, const SfxItemSet& rInAttrs) +{ + return VclPtr<AbstractSdPresLayoutDlg_Impl>::Create(std::make_unique<SdPresLayoutDlg>(pDocShell, pParent, rInAttrs)); +} + +VclPtr<SfxAbstractTabDialog> SdAbstractDialogFactory_Impl::CreateSdTabTemplateDlg(weld::Window* pParent, const SfxObjectShell* pDocShell, SfxStyleSheetBase& rStyleBase, SdrModel* pModel, SdrView* pView) +{ + return VclPtr<SdAbstractTabController_Impl>::Create(std::make_shared<SdTabTemplateDlg>(pParent, pDocShell, rStyleBase, pModel, pView)); +} + +VclPtr<SfxAbstractDialog> SdAbstractDialogFactory_Impl::CreatSdActionDialog(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView ) +{ + return VclPtr<SdAbstractSfxDialog_Impl>::Create(std::make_unique<SdActionDlg>(pParent, pAttr, pView)); +} + +VclPtr<AbstractSdVectorizeDlg> SdAbstractDialogFactory_Impl::CreateSdVectorizeDlg(weld::Window* pParent, const Bitmap& rBmp, ::sd::DrawDocShell* pDocShell) +{ + return VclPtr<AbstractSdVectorizeDlg_Impl>::Create(std::make_unique<SdVectorizeDlg>(pParent, rBmp, pDocShell)); +} + +VclPtr<AbstractSdPublishingDlg> SdAbstractDialogFactory_Impl::CreateSdPublishingDlg(weld::Window* pParent, DocumentType eDocType) +{ + return VclPtr<AbstractSdPublishingDlg_Impl>::Create(std::make_unique<SdPublishingDlg>(pParent, eDocType)); +} + +// Factories for TabPages +CreateTabPage SdAbstractDialogFactory_Impl::GetSdOptionsContentsTabPageCreatorFunc() +{ + return SdTpOptionsContents::Create; +} + +CreateTabPage SdAbstractDialogFactory_Impl::GetSdPrintOptionsTabPageCreatorFunc() +{ + return SdPrintOptions::Create; +} + +CreateTabPage SdAbstractDialogFactory_Impl::GetSdOptionsMiscTabPageCreatorFunc() +{ + return SdTpOptionsMisc::Create; +} + +CreateTabPage SdAbstractDialogFactory_Impl::GetSdOptionsSnapTabPageCreatorFunc() +{ + return SdTpOptionsSnap::Create; +} + +VclPtr<VclAbstractDialog> SdAbstractDialogFactory_Impl::CreateMasterLayoutDialog(weld::Window* pParent, SdDrawDocument* pDoc, SdPage* pCurrentPage) +{ + return VclPtr<AbstractMasterLayoutDialog_Impl>::Create(std::make_unique<::sd::MasterLayoutDialog>(pParent, pDoc, pCurrentPage)); +} + +VclPtr<AbstractHeaderFooterDialog> SdAbstractDialogFactory_Impl::CreateHeaderFooterDialog(sd::ViewShell* pViewShell, + weld::Window* pParent, SdDrawDocument* pDoc, SdPage* pCurrentPage) +{ + return VclPtr<AbstractHeaderFooterDialog_Impl>::Create(std::make_shared<::sd::HeaderFooterDialog>(pViewShell, pParent, pDoc, pCurrentPage)); +} + +VclPtr<VclAbstractDialog> SdAbstractDialogFactory_Impl::CreateSdPhotoAlbumDialog(weld::Window* pParent, SdDrawDocument* pDoc) +{ + return VclPtr<SdAbstractGenericDialog_Impl>::Create(std::make_unique<sd::SdPhotoAlbumDialog>(pParent, pDoc)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/sddlgfact.hxx b/sd/source/ui/dlg/sddlgfact.hxx new file mode 100644 index 000000000..8da5c74dd --- /dev/null +++ b/sd/source/ui/dlg/sddlgfact.hxx @@ -0,0 +1,448 @@ +/* -*- 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 . + */ +#pragma once + +#include <sdabstdlg.hxx> +#include <sfx2/basedlgs.hxx> +#include <sfx2/sfxdlg.hxx> +#include <svx/svxdlg.hxx> + +#include <morphdlg.hxx> +#include <copydlg.hxx> +#include <BreakDlg.hxx> +#include <headerfooterdlg.hxx> +#include <masterlayoutdlg.hxx> +#include <custsdlg.hxx> +#include <layeroptionsdlg.hxx> +#include <inspagob.hxx> +#include <dlgfield.hxx> +#include <sdpreslt.hxx> +#include <prltempl.hxx> +#include <pubdlg.hxx> +#include <dlgsnap.hxx> +#include <present.hxx> +#include <vectdlg.hxx> +#include <BulletAndPositionDlg.hxx> + +//namespace sd { +// class MorphDlg; +// class CopyDlg; +// class BreakDlg; +// class HeaderFooterDialog; +// class MasterLayoutDialog; +//} + +class SvxBulletAndPositionDlg; + +/// Provides managing and getting information from the numbering and position dialog. +class AbstractSvxBulletAndPositionDlg_Impl :public AbstractSvxBulletAndPositionDlg +{ + std::unique_ptr<SvxBulletAndPositionDlg> m_xDlg; +public: + explicit AbstractSvxBulletAndPositionDlg_Impl(std::unique_ptr<SvxBulletAndPositionDlg> p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + virtual const SfxItemSet* GetOutputItemSet( SfxItemSet* ) const override ; + virtual bool IsApplyToMaster() override; + virtual bool IsSlideScope() override; +}; + +class SdAbstractGenericDialog_Impl : public VclAbstractDialog +{ + std::unique_ptr<weld::GenericDialogController> m_xDlg; +public: + explicit SdAbstractGenericDialog_Impl(std::unique_ptr<weld::GenericDialogController> p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractMasterLayoutDialog_Impl : public VclAbstractDialog +{ +private: + std::unique_ptr<sd::MasterLayoutDialog> m_xDlg; +public: + AbstractMasterLayoutDialog_Impl(std::unique_ptr<::sd::MasterLayoutDialog> pDlg); + virtual short Execute() override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractBreakDlg_Impl : public VclAbstractDialog +{ +private: + std::unique_ptr<sd::BreakDlg> m_xDlg; +public: + AbstractBreakDlg_Impl(std::unique_ptr<::sd::BreakDlg> pDlg); + virtual short Execute() override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractCopyDlg_Impl : public AbstractCopyDlg +{ +private: + std::unique_ptr<sd::CopyDlg> m_xDlg; +public: + AbstractCopyDlg_Impl(std::unique_ptr<::sd::CopyDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void GetAttr( SfxItemSet& rOutAttrs ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdCustomShowDlg_Impl : public AbstractSdCustomShowDlg +{ +private: + std::unique_ptr<SdCustomShowDlg> m_xDlg; +public: + AbstractSdCustomShowDlg_Impl(std::unique_ptr<SdCustomShowDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual bool IsCustomShow() const override ; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class SdAbstractTabController_Impl : public SfxAbstractTabDialog +{ + std::shared_ptr<SfxTabDialogController> m_xDlg; +public: + explicit SdAbstractTabController_Impl(std::shared_ptr<SfxTabDialogController> p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + virtual bool StartExecuteAsync(AsyncContext &rCtx) override; + virtual void SetCurPageId( const OString &rName ) override; + virtual const SfxItemSet* GetOutputItemSet() const override; + virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override; + virtual void SetInputSet( const SfxItemSet* pInSet ) override; + virtual void SetText( const OUString& rStr ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractBulletDialog_Impl : public SfxAbstractTabDialog +{ + std::shared_ptr<SfxTabDialogController> m_xDlg; +public: + explicit AbstractBulletDialog_Impl(std::shared_ptr<SfxTabDialogController> p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + virtual bool StartExecuteAsync(AsyncContext &rCtx) override; + virtual void SetCurPageId( const OString& rName ) override; + virtual const SfxItemSet* GetOutputItemSet() const override; + virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override; + virtual void SetInputSet( const SfxItemSet* pInSet ) override; + virtual void SetText( const OUString& rStr ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class SdPresLayoutTemplateDlg_Impl : public SfxAbstractTabDialog +{ + std::shared_ptr<SdPresLayoutTemplateDlg> m_xDlg; +public: + explicit SdPresLayoutTemplateDlg_Impl(std::shared_ptr<SdPresLayoutTemplateDlg> p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + virtual bool StartExecuteAsync(AsyncContext &rCtx) override; + virtual void SetCurPageId( const OString& rName ) override; + virtual const SfxItemSet* GetOutputItemSet() const override; + virtual WhichRangesContainer GetInputRanges( const SfxItemPool& pItem ) override; + virtual void SetInputSet( const SfxItemSet* pInSet ) override; + virtual void SetText( const OUString& rStr ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdModifyFieldDlg_Impl : public AbstractSdModifyFieldDlg +{ +private: + std::unique_ptr<SdModifyFieldDlg> m_xDlg; +public: + AbstractSdModifyFieldDlg_Impl(std::unique_ptr<SdModifyFieldDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual SvxFieldData* GetField() override; + virtual SfxItemSet GetItemSet() override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdSnapLineDlg_Impl : public AbstractSdSnapLineDlg +{ +private: + std::unique_ptr<SdSnapLineDlg> m_xDlg; +public: + AbstractSdSnapLineDlg_Impl(std::unique_ptr<SdSnapLineDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void GetAttr(SfxItemSet& rOutAttrs) override; + virtual void HideRadioGroup() override; + virtual void HideDeleteBtn() override; + virtual void SetInputFields(bool bEnableX, bool bEnableY) override; + virtual void SetText( const OUString& rStr ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdInsertLayerDlg_Impl : public AbstractSdInsertLayerDlg +{ +private: + std::unique_ptr<SdInsertLayerDlg> m_xDlg; +public: + AbstractSdInsertLayerDlg_Impl(std::unique_ptr<SdInsertLayerDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void GetAttr( SfxItemSet& rOutAttrs ) override ; + virtual void SetHelpId( const OString& rHelpId ) override ; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdInsertPagesObjsDlg_Impl : public AbstractSdInsertPagesObjsDlg +{ +private: + std::unique_ptr<SdInsertPagesObjsDlg> m_xDlg; +public: + AbstractSdInsertPagesObjsDlg_Impl(std::unique_ptr<SdInsertPagesObjsDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual std::vector<OUString> GetList ( const sal_uInt16 nType ) override; + virtual bool IsLink() override; + virtual bool IsRemoveUnnecessaryMasterPages() const override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractMorphDlg_Impl : public AbstractMorphDlg +{ +private: + std::unique_ptr<sd::MorphDlg> m_xDlg; +public: + AbstractMorphDlg_Impl(std::unique_ptr<::sd::MorphDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void SaveSettings() const override; + virtual sal_uInt16 GetFadeSteps() const override; + virtual bool IsAttributeFade() const override ; + virtual bool IsOrientationFade() const override ; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdStartPresDlg_Impl : public AbstractSdStartPresDlg +{ +private: + std::unique_ptr<SdStartPresentationDlg> m_xDlg; +public: + AbstractSdStartPresDlg_Impl(std::unique_ptr<SdStartPresentationDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void GetAttr( SfxItemSet& rOutAttrs ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdPresLayoutDlg_Impl : public AbstractSdPresLayoutDlg +{ +private: + std::unique_ptr<SdPresLayoutDlg> m_xDlg; +public: + AbstractSdPresLayoutDlg_Impl(std::unique_ptr<SdPresLayoutDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void GetAttr(SfxItemSet& rOutAttrs) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class SdAbstractSfxDialog_Impl : public SfxAbstractDialog +{ +private: + std::unique_ptr<SfxSingleTabDialogController> m_xDlg; +public: + SdAbstractSfxDialog_Impl(std::unique_ptr<SfxSingleTabDialogController> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual const SfxItemSet* GetOutputItemSet() const override; + virtual void SetText( const OUString& rStr ) override; +}; + +class AbstractSdVectorizeDlg_Impl :public AbstractSdVectorizeDlg +{ +private: + std::unique_ptr<SdVectorizeDlg> m_xDlg; +public: + AbstractSdVectorizeDlg_Impl(std::unique_ptr<SdVectorizeDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual const GDIMetaFile& GetGDIMetaFile() const override ; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractSdPublishingDlg_Impl :public AbstractSdPublishingDlg +{ +private: + std::unique_ptr<SdPublishingDlg> m_xDlg; +public: + AbstractSdPublishingDlg_Impl(std::unique_ptr<SdPublishingDlg> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual void GetParameterSequence( css::uno::Sequence< css::beans::PropertyValue >& rParams ) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +class AbstractHeaderFooterDialog_Impl :public AbstractHeaderFooterDialog +{ +private: + std::shared_ptr<::sd::HeaderFooterDialog> m_xDlg; +public: + AbstractHeaderFooterDialog_Impl(std::shared_ptr<::sd::HeaderFooterDialog> pDlg) + : m_xDlg(std::move(pDlg)) + { + } + virtual short Execute() override; + virtual bool StartExecuteAsync(AsyncContext &rCtx) override; + + // screenshotting + virtual BitmapEx createScreenshot() const override; + virtual OString GetScreenshotId() const override; +}; + +//AbstractDialogFactory_Impl implementations +class SdAbstractDialogFactory_Impl : public SdAbstractDialogFactory +{ + +public: + virtual ~SdAbstractDialogFactory_Impl() {} + + virtual VclPtr<AbstractSvxBulletAndPositionDlg> CreateSvxBulletAndPositionDlg(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView) override; + virtual VclPtr<VclAbstractDialog> CreateBreakDlg(weld::Window* pWindow, ::sd::DrawView* pDrView, ::sd::DrawDocShell* pShell, sal_uLong nSumActionCount, sal_uLong nObjCount) override; + virtual VclPtr<AbstractCopyDlg> CreateCopyDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, ::sd::View* pView) override; + virtual VclPtr<AbstractSdCustomShowDlg> CreateSdCustomShowDlg(weld::Window* pParent, SdDrawDocument& rDrawDoc) override; + virtual VclPtr<SfxAbstractTabDialog> CreateSdTabCharDialog(weld::Window* pWindow, const SfxItemSet* pAttr, SfxObjectShell* pDocShell) override; + virtual VclPtr<SfxAbstractTabDialog> CreateSdTabPageDialog(weld::Window* pWindow, const SfxItemSet* pAttr, SfxObjectShell* pDocShell, bool bAreaPage, bool bIsImpressDoc, bool bIsImpressMaster) override; + virtual VclPtr<AbstractSdModifyFieldDlg> CreateSdModifyFieldDlg(weld::Window* pWindow, const SvxFieldData* pInField, const SfxItemSet& rSet) override; + virtual VclPtr<AbstractSdSnapLineDlg> CreateSdSnapLineDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, ::sd::View* pView) override; + virtual VclPtr<AbstractSdInsertLayerDlg> CreateSdInsertLayerDlg(weld::Window* pParent, const SfxItemSet& rInAttrs, bool bDeletable, const OUString& aStr) override; + virtual VclPtr<AbstractSdInsertPagesObjsDlg> CreateSdInsertPagesObjsDlg(weld::Window* pParent, const SdDrawDocument* pDoc, SfxMedium* pSfxMedium, const OUString& rFileName ) override; + virtual VclPtr<AbstractMorphDlg> CreateMorphDlg(weld::Window* pParent, const SdrObject* pObj1, const SdrObject* pObj2) override; + virtual VclPtr<SfxAbstractTabDialog> CreateSdOutlineBulletTabDlg(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView) override; + virtual VclPtr<SfxAbstractTabDialog> CreateSdParagraphTabDlg(weld::Window* pParent, const SfxItemSet* pAttr) override; + virtual VclPtr<AbstractSdStartPresDlg> CreateSdStartPresentationDlg(weld::Window* pWindow, const SfxItemSet& rInAttrs, + const std::vector<OUString> &rPageNames, SdCustomShowList* pCSList ) override; + virtual VclPtr<VclAbstractDialog> CreateRemoteDialog(weld::Window* pWindow) override; // add for RemoteDialog + virtual VclPtr<SfxAbstractTabDialog> CreateSdPresLayoutTemplateDlg(SfxObjectShell* pDocSh, weld::Window* pParent, bool bBackgroundDlg, SfxStyleSheetBase& rStyleBase, PresentationObjects ePO, SfxStyleSheetBasePool* pSSPool) override; + virtual VclPtr<AbstractSdPresLayoutDlg> CreateSdPresLayoutDlg(weld::Window* pParent, ::sd::DrawDocShell* pDocShell, const SfxItemSet& rInAttrs) override; + virtual VclPtr<SfxAbstractTabDialog> CreateSdTabTemplateDlg(weld::Window* pParent, const SfxObjectShell* pDocShell, SfxStyleSheetBase& rStyleBase, SdrModel* pModel, SdrView* pView ) override; + virtual VclPtr<SfxAbstractDialog> CreatSdActionDialog(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View* pView) override; + virtual VclPtr<AbstractSdVectorizeDlg> CreateSdVectorizeDlg(weld::Window* pParent, const Bitmap& rBmp, ::sd::DrawDocShell* pDocShell) override; + virtual VclPtr<AbstractSdPublishingDlg> CreateSdPublishingDlg(weld::Window* pWindow, DocumentType eDocType) override; + + virtual VclPtr<VclAbstractDialog> CreateSdPhotoAlbumDialog(weld::Window* pWindow, SdDrawDocument* pDoc) override; + + virtual VclPtr<VclAbstractDialog> CreateMasterLayoutDialog(weld::Window* pParent, SdDrawDocument* pDoc, SdPage*) override; + + virtual VclPtr<AbstractHeaderFooterDialog> CreateHeaderFooterDialog(sd::ViewShell* pViewShell, + weld::Window* pParent, + SdDrawDocument* pDoc, + SdPage* pCurrentPage) override; + + // For TabPage + virtual CreateTabPage GetSdOptionsContentsTabPageCreatorFunc() override; + virtual CreateTabPage GetSdPrintOptionsTabPageCreatorFunc() override; + virtual CreateTabPage GetSdOptionsMiscTabPageCreatorFunc() override; + virtual CreateTabPage GetSdOptionsSnapTabPageCreatorFunc() override; + +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/sdpreslt.cxx b/sd/source/ui/dlg/sdpreslt.cxx new file mode 100644 index 000000000..dd54611e2 --- /dev/null +++ b/sd/source/ui/dlg/sdpreslt.cxx @@ -0,0 +1,267 @@ +/* -*- 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 <svl/itemset.hxx> +#include <svl/eitem.hxx> +#include <svl/stritem.hxx> +#include <sfx2/new.hxx> +#include <svtools/valueset.hxx> +#include <tools/debug.hxx> +#include <vcl/image.hxx> + +#include <strings.hrc> + +#include <bitmaps.hlst> +#include <sdpreslt.hxx> +#include <sdattr.hrc> +#include <sdresid.hxx> +#include <drawdoc.hxx> +#include <sdpage.hxx> +#include <DrawDocShell.hxx> +#include <memory> + +SdPresLayoutDlg::SdPresLayoutDlg(::sd::DrawDocShell* pDocShell, + weld::Window* pWindow, const SfxItemSet& rInAttrs) + : GenericDialogController(pWindow, "modules/simpress/ui/slidedesigndialog.ui", "SlideDesignDialog") + , mpDocSh(pDocShell) + , mrOutAttrs(rInAttrs) + , maStrNone(SdResId(STR_NULL)) + , m_xCbxMasterPage(m_xBuilder->weld_check_button("masterpage")) + , m_xCbxCheckMasters(m_xBuilder->weld_check_button("checkmasters")) + , m_xBtnLoad(m_xBuilder->weld_button("load")) + , m_xVS(new ValueSet(m_xBuilder->weld_scrolled_window("selectwin", true))) + , m_xVSWin(new weld::CustomWeld(*m_xBuilder, "select", *m_xVS)) +{ + m_xVSWin->set_size_request(m_xBtnLoad->get_approximate_digit_width() * 60, + m_xBtnLoad->get_text_height() * 20); + + m_xVS->SetDoubleClickHdl(LINK(this, SdPresLayoutDlg, ClickLayoutHdl)); + m_xBtnLoad->connect_clicked(LINK(this, SdPresLayoutDlg, ClickLoadHdl)); + + Reset(); +} + +SdPresLayoutDlg::~SdPresLayoutDlg() +{ +} + +/** + * Initialize + */ +void SdPresLayoutDlg::Reset() +{ + tools::Long nName; + + // replace master page + if( const SfxBoolItem* pPoolItem = mrOutAttrs.GetItemIfSet( ATTR_PRESLAYOUT_MASTER_PAGE, false ) ) + { + bool bMasterPage = pPoolItem->GetValue(); + m_xCbxMasterPage->set_sensitive( !bMasterPage ); + m_xCbxMasterPage->set_active( bMasterPage ); + } + + // remove not used master pages + m_xCbxCheckMasters->set_active(false); + + if( const SfxStringItem* pPoolItem = mrOutAttrs.GetItemIfSet(ATTR_PRESLAYOUT_NAME) ) + maName = pPoolItem->GetValue(); + else + maName.clear(); + + FillValueSet(); + + mnLayoutCount = maLayoutNames.size(); + for( nName = 0; nName < mnLayoutCount; nName++ ) + { + if (maLayoutNames[nName] == maName) + break; + } + DBG_ASSERT(nName < mnLayoutCount, "Layout not found"); + + m_xVS->SelectItem(static_cast<sal_uInt16>(nName) + 1); // Indices of the ValueSets start at 1 + +} + +/** + * Fills the provided Item-Set with dialog box attributes + */ +void SdPresLayoutDlg::GetAttr(SfxItemSet& rOutAttrs) +{ + short nId = m_xVS->GetSelectedItemId(); + bool bLoad = nId > mnLayoutCount; + rOutAttrs.Put( SfxBoolItem( ATTR_PRESLAYOUT_LOAD, bLoad ) ); + + OUString aLayoutName; + + if( bLoad ) + { + aLayoutName = maName + "#" + maLayoutNames[ nId - 1 ]; + } + else if (nId) + { + aLayoutName = maLayoutNames[ nId - 1 ]; + if( aLayoutName == maStrNone ) + aLayoutName.clear(); // that way we encode "- nothing -" (see below) + } + + rOutAttrs.Put( SfxStringItem( ATTR_PRESLAYOUT_NAME, aLayoutName ) ); + rOutAttrs.Put( SfxBoolItem( ATTR_PRESLAYOUT_MASTER_PAGE, m_xCbxMasterPage->get_active() ) ); + rOutAttrs.Put( SfxBoolItem( ATTR_PRESLAYOUT_CHECK_MASTERS, m_xCbxCheckMasters->get_active() ) ); +} + +/** + * Fills ValueSet with bitmaps + */ +void SdPresLayoutDlg::FillValueSet() +{ + m_xVS->SetStyle(m_xVS->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER + | WB_VSCROLL | WB_NAMEFIELD); + + m_xVS->SetColCount(2); + m_xVS->SetLineCount(2); + m_xVS->SetExtraSpacing(2); + + SdDrawDocument* pDoc = mpDocSh->GetDoc(); + + sal_uInt16 nCount = pDoc->GetMasterPageCount(); + + for (sal_uInt16 nLayout = 0; nLayout < nCount; nLayout++) + { + SdPage* pMaster = static_cast<SdPage*>(pDoc->GetMasterPage(nLayout)); + if (pMaster->GetPageKind() == PageKind::Standard) + { + OUString aLayoutName(pMaster->GetLayoutName()); + aLayoutName = aLayoutName.copy(0, aLayoutName.indexOf(SD_LT_SEPARATOR)); + maLayoutNames.push_back(aLayoutName); + + Image aBitmap(mpDocSh->GetPagePreviewBitmap(pMaster)); + m_xVS->InsertItem(static_cast<sal_uInt16>(maLayoutNames.size()), aBitmap, aLayoutName); + } + } + + m_xVS->Show(); +} + +/** + * DoubleClick handler + */ +IMPL_LINK_NOARG(SdPresLayoutDlg, ClickLayoutHdl, ValueSet*, void) +{ + m_xDialog->response(RET_OK); +} + +/** + * Click handler for load button + */ +IMPL_LINK_NOARG(SdPresLayoutDlg, ClickLoadHdl, weld::Button&, void) +{ + SfxNewFileDialog aDlg(m_xDialog.get(), SfxNewFileDialogMode::Preview); + aDlg.set_title(SdResId(STR_LOAD_PRESENTATION_LAYOUT)); + sal_uInt16 nResult = aDlg.run(); + + bool bCancel = false; + + switch (nResult) + { + case RET_OK: + { + if (aDlg.IsTemplate()) + { + maName = aDlg.GetTemplateFileName(); + } + else + { + // that way we encode "- nothing -" + maName.clear(); + } + } + break; + + default: + bCancel = true; + } + + if( bCancel ) + return; + + // check if template already exists + OUString aCompareStr(maName); + if (aCompareStr.isEmpty()) + aCompareStr = maStrNone; + + auto it = std::find(maLayoutNames.begin(), maLayoutNames.end(), aCompareStr); + if (it != maLayoutNames.end()) + { + sal_uInt16 aPos = static_cast<sal_uInt16>(std::distance(maLayoutNames.begin(), it)); + // select template + m_xVS->SelectItem( aPos + 1 ); + } + else + { + // load document in order to determine preview bitmap (if template is selected) + if (!maName.isEmpty()) + { + // determine document in order to call OpenBookmarkDoc + SdDrawDocument* pDoc = mpDocSh->GetDoc(); + SdDrawDocument* pTemplDoc = pDoc->OpenBookmarkDoc( maName ); + + if (pTemplDoc) + { + ::sd::DrawDocShell* pTemplDocSh= pTemplDoc->GetDocSh(); + + sal_uInt16 nCount = pTemplDoc->GetMasterPageCount(); + + for (sal_uInt16 nLayout = 0; nLayout < nCount; nLayout++) + { + SdPage* pMaster = static_cast<SdPage*>( pTemplDoc->GetMasterPage(nLayout) ); + if (pMaster->GetPageKind() == PageKind::Standard) + { + OUString aLayoutName(pMaster->GetLayoutName()); + aLayoutName = aLayoutName.copy(0, aLayoutName.indexOf(SD_LT_SEPARATOR)); + maLayoutNames.push_back(aLayoutName); + + Image aBitmap(pTemplDocSh->GetPagePreviewBitmap(pMaster)); + m_xVS->InsertItem(static_cast<sal_uInt16>(maLayoutNames.size()), aBitmap, aLayoutName); + } + } + } + else + { + bCancel = true; + } + + pDoc->CloseBookmarkDoc(); + } + else + { + // empty layout + maLayoutNames.push_back(maStrNone); + m_xVS->InsertItem( static_cast<sal_uInt16>(maLayoutNames.size()), + Image(BMP_SLIDE_NONE), maStrNone ); + } + + if (!bCancel) + { + // select template + m_xVS->SelectItem( static_cast<sal_uInt16>(maLayoutNames.size()) ); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/sdtreelb.cxx b/sd/source/ui/dlg/sdtreelb.cxx new file mode 100644 index 000000000..c15a2ea09 --- /dev/null +++ b/sd/source/ui/dlg/sdtreelb.cxx @@ -0,0 +1,1206 @@ +/* -*- 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 <sal/log.hxx> +#include <sal/types.h> +#include <sot/formats.hxx> +#include <vcl/weld.hxx> +#include <svx/svditer.hxx> +#include <sfx2/docfile.hxx> +#include <svx/svdoole2.hxx> +#include <vcl/svapp.hxx> +#include <cusshow.hxx> + +#include <sfx2/viewfrm.hxx> + +#include <sdtreelb.hxx> +#include <DrawDocShell.hxx> +#include <drawdoc.hxx> +#include <sdpage.hxx> +#include <sdmod.hxx> +#include <sdresid.hxx> +#include <navigatr.hxx> +#include <strings.hrc> + +#include <bitmaps.hlst> +#include <customshowlist.hxx> +#include <ViewShell.hxx> +#include <DrawController.hxx> +#include <ViewShellBase.hxx> + +#include <com/sun/star/embed/XEmbedPersist.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <svtools/acceleratorexecute.hxx> +#include <svtools/embedtransfer.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/processfactory.hxx> + + +using namespace com::sun::star; + +bool SdPageObjsTLV::bIsInDrag = false; + +bool SdPageObjsTLV::IsInDrag() +{ + return bIsInDrag; +} + +SotClipboardFormatId SdPageObjsTLV::SdPageObjsTransferable::mnListBoxDropFormatId = static_cast<SotClipboardFormatId>(SAL_MAX_UINT32); + +SdPageObjsTLV::SdPageObjsTransferable::SdPageObjsTransferable( + const INetBookmark& rBookmark, + ::sd::DrawDocShell& rDocShell, + NavigatorDragType eDragType) + : SdTransferable(rDocShell.GetDoc(), nullptr, true), + maBookmark( rBookmark ), + mrDocShell( rDocShell ), + meDragType( eDragType ) +{ +} + +SdPageObjsTLV::SdPageObjsTransferable::~SdPageObjsTransferable() +{ +} + +void SdPageObjsTLV::SdPageObjsTransferable::AddSupportedFormats() +{ + AddFormat(SotClipboardFormatId::NETSCAPE_BOOKMARK); + AddFormat(SotClipboardFormatId::TREELISTBOX); + AddFormat(GetListBoxDropFormatId()); +} + +bool SdPageObjsTLV::SdPageObjsTransferable::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ ) +{ + SotClipboardFormatId nFormatId = SotExchange::GetFormat( rFlavor ); + switch (nFormatId) + { + case SotClipboardFormatId::NETSCAPE_BOOKMARK: + SetINetBookmark( maBookmark, rFlavor ); + return true; + + case SotClipboardFormatId::TREELISTBOX: + { + css::uno::Any aTreeListBoxData; // empty for now + SetAny(aTreeListBoxData); + return true; + } + + default: + return false; + } +} + +void SdPageObjsTLV::SdPageObjsTransferable::DragFinished( sal_Int8 nDropAction ) +{ + SdPageObjsTLV::OnDragFinished(); + SdTransferable::DragFinished(nDropAction); +} + +sal_Int64 SAL_CALL SdPageObjsTLV::SdPageObjsTransferable::getSomething( const css::uno::Sequence< sal_Int8 >& rId ) +{ + return comphelper::getSomethingImpl(rId, this, + comphelper::FallbackToGetSomethingOf<SdTransferable>{}); +} + +const css::uno::Sequence<sal_Int8>& SdPageObjsTLV::SdPageObjsTransferable::getUnoTunnelId() +{ + static const comphelper::UnoIdInit theSdPageObjsTLBUnoTunnelId; + return theSdPageObjsTLBUnoTunnelId.getSeq(); +} + +SdPageObjsTLV::SdPageObjsTransferable* SdPageObjsTLV::SdPageObjsTransferable::getImplementation( const css::uno::Reference< css::uno::XInterface >& rxData ) + noexcept +{ + try + { + return comphelper::getFromUnoTunnel<SdPageObjsTLV::SdPageObjsTransferable>(rxData); + } + catch( const css::uno::Exception& ) + { + } + return nullptr; +} + +SotClipboardFormatId SdPageObjsTLV::SdPageObjsTransferable::GetListBoxDropFormatId() +{ + if (mnListBoxDropFormatId == static_cast<SotClipboardFormatId>(SAL_MAX_UINT32)) + mnListBoxDropFormatId = SotExchange::RegisterFormatMimeType("application/x-openoffice-treelistbox-moveonly;windows_formatname=\"SV_LBOX_DD_FORMAT_MOVE\""); + return mnListBoxDropFormatId; +} + +/** + * @return true if children of the specified string are selected + */ +bool SdPageObjsTLV::HasSelectedChildren( std::u16string_view rName ) +{ + bool bChildren = false; + + if( !rName.empty() ) + { + std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator()); + OUString aTmp; + + if (m_xTreeView->get_iter_first(*xEntry)) + { + do + { + aTmp = m_xTreeView->get_text(*xEntry); + if (aTmp == rName) + { + + // see if any of the selected nodes are subchildren of this node + m_xTreeView->selected_foreach([this, &bChildren, &xEntry](weld::TreeIter& rEntry){ + std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry)); + while (!bChildren && m_xTreeView->iter_parent(*xParent)) + bChildren = m_xTreeView->iter_compare(*xParent, *xEntry) == 0; + return bChildren; + }); + + break; + } + } + while (m_xTreeView->iter_next(*xEntry)); + } + } + + return bChildren; +} + +void SdPageObjsTLV::SetShowAllShapes ( + const bool bShowAllShapes, + const bool bFillList) +{ + m_bShowAllShapes = bShowAllShapes; + if (bFillList) + { + if (m_pMedium == nullptr) + Fill(m_pDoc, m_bShowAllPages, m_aDocName); + else + Fill(m_pDoc, m_pMedium, m_aDocName); + } +} + +bool SdPageObjsTLV::IsEqualToShapeList(std::unique_ptr<weld::TreeIter>& rEntry, const SdrObjList& rList, + std::u16string_view rListName) +{ + if (!rEntry) + return false; + OUString aName = m_xTreeView->get_text(*rEntry); + + if (rListName != aName) + return false; + + if (!m_xTreeView->iter_next(*rEntry)) + rEntry.reset(); + + SdrObjListIter aIter(&rList, + !rList.HasObjectNavigationOrder() /* use navigation order, if available */, + SdrIterMode::Flat); + + while (aIter.IsMore()) + { + SdrObject* pObj = aIter.Next(); + + const OUString aObjectName(GetObjectName(pObj)); + + if (!aObjectName.isEmpty()) + { + if (!rEntry) + return false; + + aName = m_xTreeView->get_text(*rEntry); + + if (aObjectName != aName) + return false; + + if (pObj->IsGroupObject()) + { + bool bRet = IsEqualToShapeList(rEntry, *pObj->GetSubList(), aObjectName); + if (!bRet) + return false; + } + else + { + if (!m_xTreeView->iter_next(*rEntry)) + rEntry.reset(); + } + } + } + + return true; +} + +/** + * Checks if the pages (PageKind::Standard) of a doc and the objects on the pages + * are identical to the TreeLB. + * If a doc is provided, this will be the used doc (important by more than + * one document). + */ +bool SdPageObjsTLV::IsEqualToDoc( const SdDrawDocument* pInDoc ) +{ + if( pInDoc ) + m_pDoc = pInDoc; + + if( !m_pDoc ) + return false; + + std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator()); + if (!m_xTreeView->get_iter_first(*xEntry)) + xEntry.reset(); + + // compare all pages including the objects + sal_uInt16 nPage = 0; + const sal_uInt16 nMaxPages = m_pDoc->GetPageCount(); + + while( nPage < nMaxPages ) + { + const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetPage( nPage ) ); + if( pPage->GetPageKind() == PageKind::Standard ) + { + bool bRet = IsEqualToShapeList(xEntry, *pPage, pPage->GetName()); + if (!bRet) + return false; + } + nPage++; + } + // If there are still entries in the listbox, + // then objects (with names) or pages were deleted + return !xEntry; +} + +IMPL_LINK(SdPageObjsTLV, KeyInputHdl, const KeyEvent&, rKEvt, bool) +{ + const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); + if (m_xAccel->execute(rKeyCode)) + { + // the accelerator consumed the event + return true; + } + if (rKeyCode.GetCode() == KEY_RETURN) + { + std::unique_ptr<weld::TreeIter> xCursor(m_xTreeView->make_iterator()); + if (m_xTreeView->get_cursor(xCursor.get()) && m_xTreeView->iter_has_child(*xCursor)) + { + if (m_xTreeView->get_row_expanded(*xCursor)) + m_xTreeView->collapse_row(*xCursor); + else + m_xTreeView->expand_row(*xCursor); + } + m_aRowActivatedHdl.Call(*m_xTreeView); + return true; + } + return m_aKeyPressHdl.Call(rKEvt); +} + +IMPL_LINK(SdPageObjsTLV, MousePressHdl, const MouseEvent&, rMEvt, bool) +{ + m_bSelectionHandlerNavigates = rMEvt.GetClicks() == 1; + m_bNavigationGrabsFocus = rMEvt.GetClicks() != 1; + return false; +} + +IMPL_LINK_NOARG(SdPageObjsTLV, MouseReleaseHdl, const MouseEvent&, bool) +{ + m_bSelectionHandlerNavigates = false; + m_bNavigationGrabsFocus = true; + return false; +} + +IMPL_LINK(SdPageObjsTLV, DragBeginHdl, bool&, rUnsetDragIcon, bool) +{ + rUnsetDragIcon = false; + return StartDrag(); +} + +namespace +{ + bool CanDragSource(const weld::TreeView& rTreeView) + { + std::unique_ptr<weld::TreeIter> xSource(rTreeView.make_iterator()); + if (!rTreeView.get_selected(xSource.get())) + return false; + + std::unique_ptr<weld::TreeIter> xSourceParent(rTreeView.make_iterator(xSource.get())); + bool bSourceHasParent = rTreeView.iter_parent(*xSourceParent); + // level 1 objects only + if (!bSourceHasParent || rTreeView.get_iter_depth(*xSourceParent)) + return false; + + SdrObject* pSourceObject = weld::fromId<SdrObject*>(rTreeView.get_id(*xSource)); + if (pSourceObject == reinterpret_cast<SdrObject*>(1)) + pSourceObject = nullptr; + + if (!pSourceObject) + return false; + + SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject(); + if (!pObjectList) + return false; + + return true; + } +} + +/** + * StartDrag-Request + */ +bool SdPageObjsTLV::StartDrag() +{ + return !CanDragSource(*m_xTreeView) || DoDrag(); +} + +/** + * Begin drag + */ +bool SdPageObjsTLV::DoDrag() +{ + if (!m_pNavigator) + return true; + + if (!m_xHelper) + return true; + + // Get the view. + ::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh(); + ::sd::ViewShell* pViewShell = GetViewShellForDocShell(*pDocShell); + if (pViewShell == nullptr) + { + OSL_ASSERT(pViewShell!=nullptr); + return true; + } + sd::View* pView = pViewShell->GetView(); + if (pView == nullptr) + { + OSL_ASSERT(pView!=nullptr); + return true; + } + + bIsInDrag = true; + + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + bool bUserData = m_xTreeView->get_cursor(xEntry.get()); + + SdrObject* pObject = nullptr; + sal_Int64 nUserData = bUserData ? m_xTreeView->get_id(*xEntry).toInt64() : 0; + if (nUserData != 1) + pObject = reinterpret_cast<SdrObject*>(nUserData); + if (pObject != nullptr) + { + // For shapes without a user supplied name (the automatically + // created name does not count), a different drag and drop technique + // is used. + if (GetObjectName(pObject, false).isEmpty()) + { + AddShapeToTransferable(*m_xHelper, *pObject); + m_xHelper->SetView(pView); + SD_MOD()->pTransferDrag = m_xHelper.get(); + } + + // Unnamed shapes have to be selected to be recognized by the + // current drop implementation. In order to have a consistent + // behaviour for all shapes, every shape that is to be dragged is + // selected first. + SdrPageView* pPageView = pView->GetSdrPageView(); + pView->UnmarkAllObj(pPageView); + pView->MarkObj(pObject, pPageView); + } + else + { + m_xHelper->SetView(pView); + SD_MOD()->pTransferDrag = m_xHelper.get(); + } + + return false; +} + +void SdPageObjsTLV::OnDragFinished() +{ + bIsInDrag = false; +} + +SdPageObjsTLVDropTarget::SdPageObjsTLVDropTarget(weld::TreeView& rTreeView) + : DropTargetHelper(rTreeView.get_drop_target()) + , m_rTreeView(rTreeView) +{ +} + +/** + * AcceptDrop-Event + */ +sal_Int8 SdPageObjsTLVDropTarget::AcceptDrop(const AcceptDropEvent& rEvt) +{ + weld::TreeView* pSource = m_rTreeView.get_drag_source(); + // only dragging within the same widget allowed + if (!pSource || pSource != &m_rTreeView) + return DND_ACTION_NONE; + + std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator()); + if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true)) + return DND_ACTION_NONE; + + std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator()); + if (!m_rTreeView.get_selected(xSource.get())) + return DND_ACTION_NONE; + + std::unique_ptr<weld::TreeIter> xTargetParent(m_rTreeView.make_iterator(xTarget.get())); + while (m_rTreeView.get_iter_depth(*xTargetParent)) + m_rTreeView.iter_parent(*xTargetParent); + + std::unique_ptr<weld::TreeIter> xSourceParent(m_rTreeView.make_iterator(xSource.get())); + while (m_rTreeView.get_iter_depth(*xSourceParent)) + m_rTreeView.iter_parent(*xSourceParent); + + // can only drop within the same page + if (m_rTreeView.iter_compare(*xTargetParent, *xSourceParent) != 0) + return DND_ACTION_NONE; + + return DND_ACTION_MOVE; +} + +/** + * ExecuteDrop-Event + */ +sal_Int8 SdPageObjsTLVDropTarget::ExecuteDrop( const ExecuteDropEvent& rEvt ) +{ + weld::TreeView* pSource = m_rTreeView.get_drag_source(); + // only dragging within the same widget allowed + if (!pSource || pSource != &m_rTreeView) + return DND_ACTION_NONE; + + std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator()); + if (!m_rTreeView.get_selected(xSource.get())) + return DND_ACTION_NONE; + + std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator()); + if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true)) + return DND_ACTION_NONE; + int nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget) + 1; + + SdrObject* pTargetObject = weld::fromId<SdrObject*>(m_rTreeView.get_id(*xTarget)); + SdrObject* pSourceObject = weld::fromId<SdrObject*>(m_rTreeView.get_id(*xSource)); + if (pSourceObject == reinterpret_cast<SdrObject*>(1)) + pSourceObject = nullptr; + + if (pTargetObject != nullptr && pSourceObject != nullptr) + { + SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject(); + if (pObjectList != nullptr) + { + sal_uInt32 nNewPosition; + if (pTargetObject == reinterpret_cast<SdrObject*>(1)) + { + nNewPosition = 0; + nTargetPos = 0; + } + else + nNewPosition = pTargetObject->GetNavigationPosition() + 1; + pObjectList->SetObjectNavigationPosition(*pSourceObject, nNewPosition); + } + + std::unique_ptr<weld::TreeIter> xSourceParent(m_rTreeView.make_iterator(xSource.get())); + m_rTreeView.iter_parent(*xSourceParent); + + m_rTreeView.move_subtree(*xSource, xSourceParent.get(), nTargetPos); + } + + return DND_ACTION_NONE; +} + +void SdPageObjsTLV::AddShapeToTransferable ( + SdTransferable& rTransferable, + const SdrObject& rObject) const +{ + std::unique_ptr<TransferableObjectDescriptor> pObjectDescriptor(new TransferableObjectDescriptor); + bool bIsDescriptorFillingPending (true); + + const SdrOle2Obj* pOleObject = dynamic_cast<const SdrOle2Obj*>(&rObject); + if (pOleObject != nullptr && pOleObject->GetObjRef().is()) + { + // If object has no persistence it must be copied as part of the document + try + { + uno::Reference< embed::XEmbedPersist > xPersObj (pOleObject->GetObjRef(), uno::UNO_QUERY ); + if (xPersObj.is() && xPersObj->hasEntry()) + { + SvEmbedTransferHelper::FillTransferableObjectDescriptor( + *pObjectDescriptor, + pOleObject->GetObjRef(), + pOleObject->GetGraphic(), + pOleObject->GetAspect()); + bIsDescriptorFillingPending = false; + } + } + catch( uno::Exception& ) + { + } + } + + ::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh(); + if (bIsDescriptorFillingPending && pDocShell!=nullptr) + { + pDocShell->FillTransferableObjectDescriptor(*pObjectDescriptor); + } + + Point aDragPos (rObject.GetCurrentBoundRect().Center()); + pObjectDescriptor->maDragStartPos = aDragPos; + if (pDocShell != nullptr) + pObjectDescriptor->maDisplayName = pDocShell->GetMedium()->GetURLObject().GetURLNoPass(); + else + pObjectDescriptor->maDisplayName.clear(); + + rTransferable.SetStartPos(aDragPos); + rTransferable.SetObjectDescriptor( std::move(pObjectDescriptor) ); +} + +::sd::ViewShell* SdPageObjsTLV::GetViewShellForDocShell (::sd::DrawDocShell& rDocShell) +{ + { + ::sd::ViewShell* pViewShell = rDocShell.GetViewShell(); + if (pViewShell != nullptr) + return pViewShell; + } + + try + { + // Get a component enumeration from the desktop and search it for documents. + uno::Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext()); + + uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(xContext); + + if ( ! xDesktop.is()) + return nullptr; + + uno::Reference<container::XIndexAccess> xFrameAccess = xDesktop->getFrames(); + if ( ! xFrameAccess.is()) + return nullptr; + + for (sal_Int32 nIndex=0,nCount=xFrameAccess->getCount(); nIndex<nCount; ++nIndex) + { + uno::Reference<frame::XFrame> xFrame; + if ( ! (xFrameAccess->getByIndex(nIndex) >>= xFrame)) + continue; + + auto xController = xFrame->getController(); + ::sd::DrawController* pController = dynamic_cast<sd::DrawController*>(xController.get()); + if (pController == nullptr) + continue; + ::sd::ViewShellBase* pBase = pController->GetViewShellBase(); + if (pBase == nullptr) + continue; + if (pBase->GetDocShell() != &rDocShell) + continue; + + const std::shared_ptr<sd::ViewShell> pViewShell (pBase->GetMainViewShell()); + if (pViewShell) + return pViewShell.get(); + } + } + catch (uno::Exception &) + { + // When there is an exception then simply use the default value of + // bIsEnabled and disable the controls. + } + return nullptr; +} + +SdPageObjsTLV::SdPageObjsTLV(std::unique_ptr<weld::TreeView> xTreeView) + : m_xTreeView(std::move(xTreeView)) + , m_xScratchIter(m_xTreeView->make_iterator()) + , m_xDropTargetHelper(new SdPageObjsTLVDropTarget(*m_xTreeView)) + , m_xAccel(::svt::AcceleratorExecute::createAcceleratorHelper()) + , m_pNavigator(nullptr) + , m_pDoc(nullptr) + , m_pBookmarkDoc(nullptr) + , m_pMedium(nullptr) + , m_pOwnMedium(nullptr) + , m_bLinkableSelected(false) + , m_bShowAllShapes(false) + , m_bShowAllPages(false) + , m_bSelectionHandlerNavigates(false) + , m_bNavigationGrabsFocus(true) + , m_eSelectionMode(SelectionMode::Single) + , m_nSelectEventId(nullptr) + , m_nRowActivateEventId(nullptr) +{ + m_xTreeView->connect_expanding(LINK(this, SdPageObjsTLV, RequestingChildrenHdl)); + m_xTreeView->connect_changed(LINK(this, SdPageObjsTLV, SelectHdl)); + m_xTreeView->connect_row_activated(LINK(this, SdPageObjsTLV, RowActivatedHdl)); + m_xTreeView->connect_drag_begin(LINK(this, SdPageObjsTLV, DragBeginHdl)); + m_xTreeView->connect_key_press(LINK(this, SdPageObjsTLV, KeyInputHdl)); + m_xTreeView->connect_mouse_press(LINK(this, SdPageObjsTLV, MousePressHdl)); + m_xTreeView->connect_mouse_release(LINK(this, SdPageObjsTLV, MouseReleaseHdl)); + + m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 28, + m_xTreeView->get_text_height() * 8); +} + +IMPL_LINK_NOARG(SdPageObjsTLV, SelectHdl, weld::TreeView&, void) +{ + if (m_nSelectEventId) + Application::RemoveUserEvent(m_nSelectEventId); + // post the event to process select event after mouse press event + m_nSelectEventId = Application::PostUserEvent(LINK(this, SdPageObjsTLV, AsyncSelectHdl)); +} + +IMPL_LINK_NOARG(SdPageObjsTLV, RowActivatedHdl, weld::TreeView&, bool) +{ + if (m_nRowActivateEventId) + Application::RemoveUserEvent(m_nRowActivateEventId); + // post the event to process row activate after mouse press event + m_nRowActivateEventId = Application::PostUserEvent(LINK(this, SdPageObjsTLV, AsyncRowActivatedHdl)); + return true; +} + +IMPL_LINK_NOARG(SdPageObjsTLV, AsyncSelectHdl, void*, void) +{ + Select(); +} + +void SdPageObjsTLV::Select() +{ + m_nSelectEventId = nullptr; + + m_bLinkableSelected = true; + + m_xTreeView->selected_foreach([this](weld::TreeIter& rEntry){ + if (m_xTreeView->get_id(rEntry).toInt64() == 0) + m_bLinkableSelected = false; + return false; + }); + + m_aChangeHdl.Call(*m_xTreeView); + + if (m_bSelectionHandlerNavigates) + { + // Page items in the tree are given user data value 1. + // Drawing object items are given user data value of the object pointer they represent. + sal_Int64 nUserData = m_xTreeView->get_selected_id().toInt64(); + if (nUserData != 1) + { + SdrObject* pObject = reinterpret_cast<SdrObject*>(nUserData); + if (pObject && pObject->GetName().isEmpty()) + { + const bool bUndo = pObject->getSdrModelFromSdrObject().IsUndoEnabled(); + pObject->getSdrModelFromSdrObject().EnableUndo(false); + pObject->SetName(m_xTreeView->get_selected_text(), false); + pObject->getSdrModelFromSdrObject().EnableUndo(bUndo); + m_aRowActivatedHdl.Call(*m_xTreeView); + pObject->getSdrModelFromSdrObject().EnableUndo(false); + pObject->SetName(OUString(), false); + pObject->getSdrModelFromSdrObject().EnableUndo(bUndo); + } + else + m_aRowActivatedHdl.Call(*m_xTreeView); + } + else + m_aRowActivatedHdl.Call(*m_xTreeView); + } + + if (!m_pNavigator) + { + m_xHelper.clear(); + return; + } + + ::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh(); + OUString aURL = INetURLObject(pDocShell->GetMedium()->GetPhysicalName(), INetProtocol::File).GetMainURL(INetURLObject::DecodeMechanism::NONE); + NavigatorDragType eDragType = m_pNavigator->GetNavigatorDragType(); + + OUString sSelectedEntry = m_xTreeView->get_selected_text(); + aURL += "#" + sSelectedEntry; + + INetBookmark aBookmark(aURL, sSelectedEntry); + sal_Int8 nDNDActions = DND_ACTION_COPYMOVE; + + if( eDragType == NAVIGATOR_DRAGTYPE_LINK ) + nDNDActions = DND_ACTION_LINK; // Either COPY *or* LINK, never both! + else if (m_pDoc->GetSdPageCount(PageKind::Standard) == 1) + { + // Can not move away the last slide in a document. + nDNDActions = DND_ACTION_COPY; + } + + // object is destroyed by internal reference mechanism + m_xHelper.set(new SdPageObjsTLV::SdPageObjsTransferable(aBookmark, *pDocShell, eDragType)); + rtl::Reference<TransferDataContainer> xHelper(m_xHelper); + m_xTreeView->enable_drag_source(xHelper, nDNDActions); +} + +IMPL_LINK_NOARG(SdPageObjsTLV, AsyncRowActivatedHdl, void*, void) +{ + m_nRowActivateEventId = nullptr; + m_aRowActivatedHdl.Call(*m_xTreeView); +} + +OUString SdPageObjsTLV::GetObjectName( + const SdrObject* pObject, + const bool bCreate) const +{ + OUString aRet; + + if ( pObject ) + { + aRet = pObject->GetName(); + + if (aRet.isEmpty()) + if (auto pOleObj = dynamic_cast<const SdrOle2Obj* >(pObject)) + aRet = pOleObj->GetPersistName(); + } + + if (bCreate + && m_bShowAllShapes + && aRet.isEmpty() + && pObject!=nullptr) + { + aRet = SdResId(STR_NAVIGATOR_SHAPE_BASE_NAME) + " (" + pObject->TakeObjNameSingul() +")"; + aRet = aRet.replaceFirst("%1", OUString::number(pObject->GetOrdNum() + 1)); + } + + return aRet; +} + +std::vector<OUString> SdPageObjsTLV::GetSelectEntryList(const int nDepth) const +{ + std::vector<OUString> aEntries; + + m_xTreeView->selected_foreach([this, nDepth, &aEntries](weld::TreeIter& rEntry){ + int nListDepth = m_xTreeView->get_iter_depth(rEntry); + if (nListDepth == nDepth) + aEntries.push_back(m_xTreeView->get_text(rEntry)); + return false; + }); + + return aEntries; +} + +/** + * Checks if it is a draw file and opens the BookmarkDoc depending of + * the provided Docs + */ +SdDrawDocument* SdPageObjsTLV::GetBookmarkDoc(SfxMedium* pMed) +{ + if ( + !m_pBookmarkDoc || + (pMed && (!m_pOwnMedium || m_pOwnMedium->GetName() != pMed->GetName())) + ) + { + // create a new BookmarkDoc if now one exists or if a new Medium is provided + if (m_pOwnMedium != pMed) + { + CloseBookmarkDoc(); + } + + if (pMed) + { + // it looks that it is undefined if a Medium was set by Fill() already + DBG_ASSERT( !m_pMedium, "SfxMedium confusion!" ); + delete m_pMedium; + m_pMedium = nullptr; + + // take over this Medium (currently used only be Navigator) + m_pOwnMedium = pMed; + } + + DBG_ASSERT( m_pMedium || pMed, "No SfxMedium provided!" ); + + if( pMed ) + { + // in this mode the document is also owned and controlled by this instance + m_xBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress); + if (m_xBookmarkDocShRef->DoLoad(pMed)) + m_pBookmarkDoc = m_xBookmarkDocShRef->GetDoc(); + else + m_pBookmarkDoc = nullptr; + } + else if ( m_pMedium ) + // in this mode the document is owned and controlled by the SdDrawDocument + // it can be released by calling the corresponding CloseBookmarkDoc method + // successful creation of a document makes this the owner of the medium + m_pBookmarkDoc = const_cast<SdDrawDocument*>(m_pDoc)->OpenBookmarkDoc(m_pMedium); + + if ( !m_pBookmarkDoc ) + { + std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xTreeView.get(), + VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR))); + xErrorBox->run(); + m_pMedium = nullptr; //On failure the SfxMedium is invalid + } + } + + return m_pBookmarkDoc; +} + +/** + * Entries are inserted only by request (double click) + */ +IMPL_LINK(SdPageObjsTLV, RequestingChildrenHdl, const weld::TreeIter&, rFileEntry, bool) +{ + if (!m_xTreeView->iter_has_child(rFileEntry)) + { + if (GetBookmarkDoc()) + { + SdrObject* pObj = nullptr; + + OUString sImgPage(BMP_PAGE); + OUString sImgPageObjs(BMP_PAGEOBJS); + OUString sImgObjects(BMP_OBJECTS); + OUString sImgOle(BMP_OLE); + OUString sImgGraphic(BMP_GRAPHIC); + + // document name already inserted + + // only insert all "normal" ? slides with objects + sal_uInt16 nPage = 0; + const sal_uInt16 nMaxPages = m_pBookmarkDoc->GetPageCount(); + + std::unique_ptr<weld::TreeIter> xPageEntry; + while (nPage < nMaxPages) + { + SdPage* pPage = static_cast<SdPage*>(m_pBookmarkDoc->GetPage(nPage)); + if (pPage->GetPageKind() == PageKind::Standard) + { + OUString sId(OUString::number(1)); + m_xTreeView->insert(&rFileEntry, -1, &pPage->GetName(), &sId, + nullptr, nullptr, false, m_xScratchIter.get()); + m_xTreeView->set_image(*m_xScratchIter, sImgPage); + + if (!xPageEntry) + { + xPageEntry = m_xTreeView->make_iterator(&rFileEntry); + (void)m_xTreeView->iter_children(*xPageEntry); + } + else + (void)m_xTreeView->iter_next_sibling(*xPageEntry); + + SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups ); + + while( aIter.IsMore() ) + { + pObj = aIter.Next(); + OUString aStr( GetObjectName( pObj ) ); + if( !aStr.isEmpty() ) + { + if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::OLE2 ) + { + m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr, + nullptr, nullptr, false, m_xScratchIter.get()); + m_xTreeView->set_image(*m_xScratchIter, sImgOle); + } + else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::Graphic ) + { + m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr, + nullptr, nullptr, false, m_xScratchIter.get()); + m_xTreeView->set_image(*m_xScratchIter, sImgGraphic); + } + else + { + m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr, + nullptr, nullptr, false, m_xScratchIter.get()); + m_xTreeView->set_image(*m_xScratchIter, sImgObjects); + } + } + } + if (m_xTreeView->iter_has_child(*xPageEntry)) + { + m_xTreeView->set_image(*xPageEntry, sImgPageObjs); + } + } + nPage++; + } + } + } + return true; +} + +void SdPageObjsTLV::SetSdNavigator(SdNavigatorWin* pNavigator) +{ + m_pNavigator = pNavigator; +} + +void SdPageObjsTLV::SetViewFrame(const SfxViewFrame* pViewFrame) +{ + sd::ViewShellBase* pBase = sd::ViewShellBase::GetViewShellBase(pViewFrame); + std::shared_ptr<sd::ViewShell> xViewShell = pBase->GetMainViewShell(); + SAL_WARN_IF(!xViewShell, "sd", "null pBaseViewFrame"); + const css::uno::Reference< css::frame::XFrame > xFrame = xViewShell ? xViewShell->GetViewFrame()->GetFrame().GetFrameInterface() : nullptr; + m_xAccel->init(::comphelper::getProcessComponentContext(), xFrame); +} + +/** + * Close and delete bookmark document + */ +void SdPageObjsTLV::CloseBookmarkDoc() +{ + if (m_xBookmarkDocShRef.is()) + { + m_xBookmarkDocShRef->DoClose(); + m_xBookmarkDocShRef.clear(); + + // Medium is owned by document, so it's destroyed already + m_pOwnMedium = nullptr; + } + else if (m_pBookmarkDoc) + { + DBG_ASSERT(!m_pOwnMedium, "SfxMedium confusion!"); + if (m_pDoc) + { + // The document owns the Medium, so the Medium will be invalid after closing the document + const_cast<SdDrawDocument*>(m_pDoc)->CloseBookmarkDoc(); + m_pMedium = nullptr; + } + } + else + { + // perhaps mpOwnMedium provided, but no successful creation of BookmarkDoc + delete m_pOwnMedium; + m_pOwnMedium = nullptr; + } + + m_pBookmarkDoc = nullptr; +} + +bool SdPageObjsTLV::PageBelongsToCurrentShow(const SdPage* pPage) const +{ + // Return <TRUE/> as default when there is no custom show or when none + // is used. The page does then belong to the standard show. + bool bBelongsToShow = true; + + if (m_pDoc->getPresentationSettings().mbCustomShow) + { + // Get the current custom show. + SdCustomShow* pCustomShow = nullptr; + SdCustomShowList* pShowList = const_cast<SdDrawDocument*>(m_pDoc)->GetCustomShowList(); + if (pShowList != nullptr) + { + sal_uLong nCurrentShowIndex = pShowList->GetCurPos(); + pCustomShow = (*pShowList)[nCurrentShowIndex].get(); + } + + // Check whether the given page is part of that custom show. + if (pCustomShow != nullptr) + { + bBelongsToShow = false; + size_t nPageCount = pCustomShow->PagesVector().size(); + for (size_t i=0; i<nPageCount && !bBelongsToShow; i++) + if (pPage == pCustomShow->PagesVector()[i]) + bBelongsToShow = true; + } + } + + return bBelongsToShow; +} + +void SdPageObjsTLV::AddShapeList ( + const SdrObjList& rList, + const SdrObject* pShape, + const OUString& rsName, + const bool bIsExcluded, + const weld::TreeIter* pParentEntry) +{ + OUString aIcon(BMP_PAGE); + if (bIsExcluded) + aIcon = BMP_PAGE_EXCLUDED; + else if (pShape != nullptr) + aIcon = BMP_GROUP; + + OUString aUserData("1"); + if (pShape != nullptr) + aUserData = weld::toId(pShape); + + std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator(); + InsertEntry(pParentEntry, aUserData, rsName, aIcon, xEntry.get()); + + SdrObjListIter aIter( + &rList, + !rList.HasObjectNavigationOrder() /* use navigation order, if available */, + SdrIterMode::Flat); + + while( aIter.IsMore() ) + { + SdrObject* pObj = aIter.Next(); + OSL_ASSERT(pObj!=nullptr); + + // Get the shape name. + OUString aStr (GetObjectName( pObj ) ); + OUString sId(weld::toId(pObj)); + + if( !aStr.isEmpty() ) + { + if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::OLE2 ) + { + InsertEntry(xEntry.get(), sId, aStr, BMP_OLE); + } + else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::Graphic ) + { + InsertEntry(xEntry.get(), sId, aStr, BMP_GRAPHIC); + } + else if (pObj->IsGroupObject()) + { + AddShapeList( + *pObj->GetSubList(), + pObj, + aStr, + false, + xEntry.get()); + } + else + { + InsertEntry(xEntry.get(), sId, aStr, BMP_OBJECTS); + } + } + } + + if (!m_xTreeView->iter_has_child(*xEntry)) + return; + + if (bIsExcluded) + m_xTreeView->set_image(*xEntry, BMP_PAGEOBJS_EXCLUDED); + else + m_xTreeView->set_image(*xEntry, BMP_PAGEOBJS); + m_xTreeView->expand_row(*xEntry); +} + +/** + * Fill TreeLB with pages and objects + */ +void SdPageObjsTLV::Fill(const SdDrawDocument* pInDoc, bool bAllPages, const OUString& rDocName) +{ + OUString aSelection = m_xTreeView->get_selected_text(); + clear(); + + m_pDoc = pInDoc; + m_aDocName = rDocName; + m_bShowAllPages = bAllPages; + m_pMedium = nullptr; + + // first insert all pages including objects + sal_uInt16 nPage = 0; + const sal_uInt16 nMaxPages = m_pDoc->GetPageCount(); + + while( nPage < nMaxPages ) + { + const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetPage( nPage ) ); + if( (m_bShowAllPages || pPage->GetPageKind() == PageKind::Standard) + && (pPage->GetPageKind() != PageKind::Handout) ) //#94954# never list the normal handout page ( handout-masterpage is used instead ) + { + bool bPageExcluded = pPage->IsExcluded(); + + bool bPageBelongsToShow = PageBelongsToCurrentShow (pPage); + bPageExcluded |= !bPageBelongsToShow; + + AddShapeList(*pPage, nullptr, pPage->GetName(), bPageExcluded, nullptr); + } + nPage++; + } + + // then insert all master pages including objects + if( m_bShowAllPages ) + { + nPage = 0; + const sal_uInt16 nMaxMasterPages = m_pDoc->GetMasterPageCount(); + + while( nPage < nMaxMasterPages ) + { + const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetMasterPage( nPage ) ); + AddShapeList(*pPage, nullptr, pPage->GetName(), false, nullptr); + nPage++; + } + } + if (!aSelection.isEmpty()) + { + m_xTreeView->all_foreach([this, &aSelection](weld::TreeIter& rEntry){ + if (m_xTreeView->get_text(rEntry) == aSelection) + { + m_xTreeView->select(rEntry); + return true; + } + return false; + }); + } +} + +/** + * We insert only the first entry. Children are created on demand. + */ +void SdPageObjsTLV::Fill( const SdDrawDocument* pInDoc, SfxMedium* pInMedium, + const OUString& rDocName ) +{ + m_pDoc = pInDoc; + + // this object now owns the Medium + m_pMedium = pInMedium; + m_aDocName = rDocName; + + OUString sId(OUString::number(1)); + // insert document name + m_xTreeView->insert(nullptr, -1, &m_aDocName, &sId, nullptr, nullptr, true, m_xScratchIter.get()); + m_xTreeView->set_image(*m_xScratchIter, BMP_DOC_OPEN); +} + +/** + * select an entry in TreeLB + */ +bool SdPageObjsTLV::SelectEntry( std::u16string_view rName ) +{ + bool bFound = false; + + if (!rName.empty()) + { + std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator()); + OUString aTmp; + + if (m_xTreeView->get_iter_first(*xEntry)) + { + do + { + aTmp = m_xTreeView->get_text(*xEntry); + if (aTmp == rName) + { + m_xTreeView->set_cursor(*xEntry); + m_xTreeView->select(*xEntry); + bFound = true; + break; + } + } + while (m_xTreeView->iter_next(*xEntry)); + } + } + + return bFound; +} + +SdPageObjsTLV::~SdPageObjsTLV() +{ + if (m_nSelectEventId) + Application::RemoveUserEvent(m_nSelectEventId); + if (m_nRowActivateEventId) + Application::RemoveUserEvent(m_nRowActivateEventId); + + if (m_pBookmarkDoc) + CloseBookmarkDoc(); + else + { + // no document was created from m_pMedium, so this object is still the owner of it + delete m_pMedium; + } + m_xAccel.reset(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/sduiexp.cxx b/sd/source/ui/dlg/sduiexp.cxx new file mode 100644 index 000000000..62901c70d --- /dev/null +++ b/sd/source/ui/dlg/sduiexp.cxx @@ -0,0 +1,33 @@ +/* -*- 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 "sddlgfact.hxx" +#include <sal/types.h> + +class SdAbstractDialogFactory; + +extern "C" { +SAL_DLLPUBLIC_EXPORT SdAbstractDialogFactory* SdCreateDialogFactory() +{ + static SdAbstractDialogFactory_Impl aFactory; + return &aFactory; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/tabtempl.cxx b/sd/source/ui/dlg/tabtempl.cxx new file mode 100644 index 000000000..e5db39e68 --- /dev/null +++ b/sd/source/ui/dlg/tabtempl.cxx @@ -0,0 +1,160 @@ +/* -*- 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 <editeng/flstitem.hxx> + +#include <svx/svxids.hrc> + +#include <svx/drawitem.hxx> +#include <svl/intitem.hxx> +#include <svx/ofaitem.hxx> +#include <svx/svdmodel.hxx> +#include <svl/cjkoptions.hxx> +#include <sfx2/objsh.hxx> +#include <svx/dialogs.hrc> +#include <svl/style.hxx> + +#include <tabtempl.hxx> +#include <svx/flagsdef.hxx> + +/** + * Constructor of the Tab dialog: appends pages to the dialog + */ +SdTabTemplateDlg::SdTabTemplateDlg(weld::Window* pParent, + const SfxObjectShell* pDocShell, + SfxStyleSheetBase& rStyleBase, + SdrModel const * pModel, + SdrView* pView) + : SfxStyleDialogController(pParent, "modules/simpress/ui/templatedialog.ui", + "TemplateDialog", rStyleBase) + , rDocShell(*pDocShell) + , pSdrView(pView) + , pColorList(pModel->GetColorList()) + , pGradientList(pModel->GetGradientList()) + , pHatchingList(pModel->GetHatchList()) + , pBitmapList(pModel->GetBitmapList()) + , pPatternList(pModel->GetPatternList()) + , pDashList(pModel->GetDashList()) + , pLineEndList(pModel->GetLineEndList()) +{ + // fill Listbox and set Select-Handler + + AddTabPage("line", RID_SVXPAGE_LINE); + AddTabPage("area", RID_SVXPAGE_AREA); + AddTabPage("shadowing", RID_SVXPAGE_SHADOW); + AddTabPage("transparency", RID_SVXPAGE_TRANSPARENCE); + AddTabPage("font", RID_SVXPAGE_CHAR_NAME); + AddTabPage("fonteffect", RID_SVXPAGE_CHAR_EFFECTS); + AddTabPage("background", RID_SVXPAGE_BKG); + AddTabPage("indents", RID_SVXPAGE_STD_PARAGRAPH); + AddTabPage("text", RID_SVXPAGE_TEXTATTR); + AddTabPage("animation", RID_SVXPAGE_TEXTANIMATION); + AddTabPage("dimensioning", RID_SVXPAGE_MEASURE); + AddTabPage("connector", RID_SVXPAGE_CONNECTION); + AddTabPage("alignment", RID_SVXPAGE_ALIGN_PARAGRAPH); + AddTabPage("tabs", RID_SVXPAGE_TABULATOR); + if( SvtCJKOptions::IsAsianTypographyEnabled() ) + AddTabPage("asiantypo", RID_SVXPAGE_PARA_ASIAN); + else + RemoveTabPage("asiantypo"); +} + +void SdTabTemplateDlg::PageCreated(const OString& rId, SfxTabPage &rPage) +{ + SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool())); + if (rId == "line") + { + aSet.Put (SvxColorListItem(pColorList,SID_COLOR_TABLE)); + aSet.Put (SvxDashListItem(pDashList,SID_DASH_LIST)); + aSet.Put (SvxLineEndListItem(pLineEndList,SID_LINEEND_LIST)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + rPage.PageCreated(aSet); + } + else if (rId == "area") + { + aSet.Put (SvxColorListItem(pColorList,SID_COLOR_TABLE)); + aSet.Put (SvxGradientListItem(pGradientList,SID_GRADIENT_LIST)); + aSet.Put (SvxHatchListItem(pHatchingList,SID_HATCH_LIST)); + aSet.Put (SvxBitmapListItem(pBitmapList,SID_BITMAP_LIST)); + aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + aSet.Put (SfxUInt16Item(SID_TABPAGE_POS,0)); + aSet.Put (SvxPatternListItem(pPatternList,SID_PATTERN_LIST)); + rPage.PageCreated(aSet); + } + else if (rId == "shadowing") + { + aSet.Put (SvxColorListItem(pColorList,SID_COLOR_TABLE)); + aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + rPage.PageCreated(aSet); + } + else if (rId == "transparency") + { + aSet.Put (SfxUInt16Item(SID_PAGE_TYPE,0)); + aSet.Put (SfxUInt16Item(SID_DLG_TYPE,1)); + rPage.PageCreated(aSet); + } + else if (rId == "font") + { + SvxFontListItem aItem(*static_cast<const SvxFontListItem*>( + rDocShell.GetItem( SID_ATTR_CHAR_FONTLIST) ) ); + + aSet.Put (SvxFontListItem( aItem.GetFontList(), SID_ATTR_CHAR_FONTLIST)); + rPage.PageCreated(aSet); + } + else if (rId == "fonteffect") + { + rPage.PageCreated(aSet); + } + else if (rId == "background") + { + aSet.Put(SfxUInt32Item(SID_FLAG_TYPE,static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR))); + rPage.PageCreated(aSet); + } + else if (rId == "text") + { + rPage.PageCreated(aSet); + } + else if (rId == "dimensioning") + { + aSet.Put (OfaPtrItem(SID_OBJECT_LIST,pSdrView)); + rPage.PageCreated(aSet); + } + else if (rId == "connector") + { + aSet.Put (OfaPtrItem(SID_OBJECT_LIST,pSdrView)); + rPage.PageCreated(aSet); + } +} + +void SdTabTemplateDlg::RefreshInputSet() +{ + SfxItemSet* pInputSet = GetInputSetImpl(); + + if( pInputSet ) + { + pInputSet->ClearItem(); + pInputSet->SetParent( GetStyleSheet().GetItemSet().GetParent() ); + } + else + SetInputSet(&GetStyleSheet().GetItemSet()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/titledockwin.cxx b/sd/source/ui/dlg/titledockwin.cxx new file mode 100644 index 000000000..f2aa744c2 --- /dev/null +++ b/sd/source/ui/dlg/titledockwin.cxx @@ -0,0 +1,261 @@ +/* -*- 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 <sfx2/bindings.hxx> +#include <sfx2/dispatch.hxx> +#include <svl/eitem.hxx> +#include <vcl/event.hxx> +#include <vcl/settings.hxx> +#include <vcl/toolbox.hxx> + +#include <bitmaps.hlst> +#include <strings.hrc> +#include <sdresid.hxx> +#include <titledockwin.hxx> + +namespace sd +{ + //= TitledDockingWindow + TitledDockingWindow::TitledDockingWindow( SfxBindings* i_pBindings, SfxChildWindow* i_pChildWindow, vcl::Window* i_pParent ) + :SfxDockingWindow( i_pBindings, i_pChildWindow, i_pParent, WB_MOVEABLE|WB_CLOSEABLE|WB_DOCKABLE|WB_HIDE|WB_3DLOOK ) + ,m_aToolbox( VclPtr<ToolBox>::Create(this) ) + ,m_aContentWindow( VclPtr<vcl::Window>::Create(this, WB_DIALOGCONTROL) ) + ,m_aBorder( 3, 1, 3, 3 ) + ,m_nTitleBarHeight(0) + { + SetBackground( Wallpaper() ); + + m_aToolbox->SetSelectHdl( LINK( this, TitledDockingWindow, OnToolboxItemSelected ) ); + m_aToolbox->SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetDialogColor() ) ); + m_aToolbox->Show(); + impl_resetToolBox(); + + m_aContentWindow->Show(); + } + + TitledDockingWindow::~TitledDockingWindow() + { + disposeOnce(); + } + + void TitledDockingWindow::dispose() + { + m_aToolbox.disposeAndClear(); + m_aContentWindow.disposeAndClear(); + SfxDockingWindow::dispose(); + } + + void TitledDockingWindow::SetTitle( const OUString& i_rTitle ) + { + m_sTitle = i_rTitle; + Invalidate(); + } + + + void TitledDockingWindow::SetText( const OUString& i_rText ) + { + SfxDockingWindow::SetText( i_rText ); + if ( m_sTitle.isEmpty() ) + // our text is used as title, too => repaint + Invalidate(); + } + + + void TitledDockingWindow::Resize() + { + SfxDockingWindow::Resize(); + impl_layout(); + } + + + void TitledDockingWindow::impl_layout() + { + m_aToolbox->ShowItem( ToolBoxItemId(1), !IsFloatingMode() ); + + const Size aToolBoxSize( m_aToolbox->CalcWindowSizePixel() ); + Size aWindowSize( GetOutputSizePixel() ); + + // position the tool box + m_nTitleBarHeight = GetSettings().GetStyleSettings().GetTitleHeight(); + if ( aToolBoxSize.Height() > m_nTitleBarHeight ) + m_nTitleBarHeight = aToolBoxSize.Height(); + m_aToolbox->SetPosSizePixel( + Point( + aWindowSize.Width() - aToolBoxSize.Width(), + ( m_nTitleBarHeight - aToolBoxSize.Height() ) / 2 + ), + aToolBoxSize + ); + + // Place the content window. + if ( m_nTitleBarHeight < aToolBoxSize.Height() ) + m_nTitleBarHeight = aToolBoxSize.Height(); + aWindowSize.AdjustHeight( -m_nTitleBarHeight ); + m_aContentWindow->SetPosSizePixel( + Point( m_aBorder.Left(), m_nTitleBarHeight + m_aBorder.Top() ), + Size( + aWindowSize.Width() - m_aBorder.Left() - m_aBorder.Right(), + aWindowSize.Height() - m_aBorder.Top() - m_aBorder.Bottom() + ) + ); + } + + void TitledDockingWindow::ApplySettings(vcl::RenderContext& rRenderContext) + { + const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); + + // Font + ApplyControlFont(rRenderContext, rStyleSettings.GetAppFont()); + + // Color + ApplyControlForeground(rRenderContext, rStyleSettings.GetButtonTextColor()); + rRenderContext.SetTextFillColor(); + } + + void TitledDockingWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& i_rArea) + { + const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); + + SfxDockingWindow::Paint(rRenderContext, i_rArea); + + rRenderContext.Push(vcl::PushFlags::FONT | vcl::PushFlags::FILLCOLOR | vcl::PushFlags::LINECOLOR); + + rRenderContext.SetFillColor(rStyleSettings.GetDialogColor()); + rRenderContext.SetLineColor(); + + // bold font + vcl::Font aFont(rRenderContext.GetFont()); + aFont.SetWeight(WEIGHT_BOLD); + rRenderContext.SetFont(aFont); + + // Set border values. + Size aWindowSize(GetOutputSizePixel()); + int nOuterLeft = 0; + int nInnerLeft = nOuterLeft + m_aBorder.Left() - 1; + int nOuterRight = aWindowSize.Width() - 1; + int nInnerRight = nOuterRight - m_aBorder.Right() + 1; + int nInnerTop = m_nTitleBarHeight + m_aBorder.Top() - 1; + int nOuterBottom = aWindowSize.Height() - 1; + int nInnerBottom = nOuterBottom - m_aBorder.Bottom() + 1; + + // Paint title bar background. + ::tools::Rectangle aTitleBarBox(::tools::Rectangle(nOuterLeft, 0, nOuterRight, nInnerTop - 1)); + rRenderContext.DrawRect(aTitleBarBox); + + if (nInnerLeft > nOuterLeft) + rRenderContext.DrawRect(::tools::Rectangle(nOuterLeft, nInnerTop, nInnerLeft, nInnerBottom)); + if (nOuterRight > nInnerRight) + rRenderContext.DrawRect(::tools::Rectangle(nInnerRight, nInnerTop, nOuterRight, nInnerBottom)); + if (nInnerBottom < nOuterBottom) + rRenderContext.DrawRect(::tools::Rectangle(nOuterLeft, nInnerBottom, nOuterRight, nOuterBottom)); + + // Paint bevel border. + rRenderContext.SetFillColor(); + rRenderContext.SetLineColor(rStyleSettings.GetShadowColor()); + if (m_aBorder.Top() > 0) + rRenderContext.DrawLine(Point(nInnerLeft, nInnerTop), Point(nInnerLeft, nInnerBottom)); + if (m_aBorder.Left() > 0) + rRenderContext.DrawLine(Point(nInnerLeft, nInnerTop), Point(nInnerRight, nInnerTop)); + + rRenderContext.SetLineColor(rStyleSettings.GetLightColor()); + if (m_aBorder.Bottom() > 0) + rRenderContext.DrawLine(Point(nInnerRight, nInnerBottom), Point(nInnerLeft, nInnerBottom)); + if (m_aBorder.Right() > 0) + rRenderContext.DrawLine(Point(nInnerRight, nInnerBottom), Point(nInnerRight, nInnerTop)); + + // Paint title bar text. + rRenderContext.SetLineColor(rStyleSettings.GetActiveTextColor()); + aTitleBarBox.AdjustLeft(3 ); + rRenderContext.DrawText(aTitleBarBox, + !m_sTitle.isEmpty() ? m_sTitle : GetText(), + DrawTextFlags::Left | DrawTextFlags::VCenter | DrawTextFlags::MultiLine | DrawTextFlags::WordBreak); + + // Restore original values of the output device. + rRenderContext.Pop(); + } + + + void TitledDockingWindow::impl_resetToolBox() + { + m_aToolbox->Clear(); + + // Get the closer bitmap and set it as right most button. + m_aToolbox->InsertItem(ToolBoxItemId(1), Image(StockImage::Yes, SFX_BMP_CLOSE_DOC)); + m_aToolbox->SetQuickHelpText(ToolBoxItemId(1), SdResId(STR_CLOSE_PANE)); + m_aToolbox->ShowItem( ToolBoxItemId(1) ); + } + + + IMPL_LINK( TitledDockingWindow, OnToolboxItemSelected, ToolBox*, pToolBox, void ) + { + const ToolBoxItemId nId = pToolBox->GetCurItemId(); + + if ( nId == ToolBoxItemId(1) ) + { + // the closer + EndTracking(); + const sal_uInt16 nChildWindowId( GetChildWindow_Impl()->GetType() ); + const SfxBoolItem aVisibility( nChildWindowId, false ); + GetBindings().GetDispatcher()->ExecuteList( + nChildWindowId, + SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, + { &aVisibility } + ); + } + } + + + void TitledDockingWindow::StateChanged( StateChangedType i_nType ) + { + switch ( i_nType ) + { + case StateChangedType::InitShow: + impl_layout(); + break; + default:; + } + SfxDockingWindow::StateChanged( i_nType ); + } + + void TitledDockingWindow::DataChanged( const DataChangedEvent& i_rDataChangedEvent ) + { + SfxDockingWindow::DataChanged( i_rDataChangedEvent ); + + switch ( i_rDataChangedEvent.GetType() ) + { + case DataChangedEventType::SETTINGS: + if ( !( i_rDataChangedEvent.GetFlags() & AllSettingsFlags::STYLE ) ) + break; + [[fallthrough]]; + case DataChangedEventType::FONTS: + case DataChangedEventType::FONTSUBSTITUTION: + { + impl_layout(); + Invalidate(); + } + break; + default: break; + } + } + + +} // namespace sfx2 + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/tpaction.cxx b/sd/source/ui/dlg/tpaction.cxx new file mode 100644 index 000000000..f89fa51f5 --- /dev/null +++ b/sd/source/ui/dlg/tpaction.cxx @@ -0,0 +1,801 @@ +/* -*- 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 <svx/svxids.hrc> +#include <com/sun/star/presentation/ClickAction.hpp> +#include <com/sun/star/embed/NeedsRunningStateException.hpp> +#include <com/sun/star/embed/VerbDescriptor.hpp> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/embed/XEmbeddedObject.hpp> +#include <comphelper/string.hxx> +#include <com/sun/star/embed/VerbAttributes.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> + +#include <sdattr.hrc> +#include <sfx2/sfxresid.hxx> +#include <sfx2/strings.hrc> +#include <o3tl/safeint.hxx> +#include <tools/debug.hxx> +#include <sfx2/app.hxx> +#include <svx/svdograf.hxx> +#include <svl/stritem.hxx> +#include <svx/svdoole2.hxx> +#include <sfx2/docfile.hxx> +#include <svx/xtable.hxx> +#include <vcl/mnemonic.hxx> +#include <svl/intitem.hxx> +#include <svl/urihelper.hxx> +#include <sfx2/filedlghelper.hxx> +#include <svx/drawitem.hxx> +#include <osl/diagnose.h> +#include <o3tl/string_view.hxx> +#include <View.hxx> +#include <sdresid.hxx> +#include <tpaction.hxx> +#include <ViewShell.hxx> +#include <drawdoc.hxx> +#include <DrawDocShell.hxx> +#include <strings.hrc> + +#include <filedlg.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +#define DOCUMENT_TOKEN '#' + +// XML content stream +constexpr OUStringLiteral pStarDrawXMLContent( u"content.xml" ); + +/** + * Constructor of the Tab dialog: appends the pages to the dialog + */ +SdActionDlg::SdActionDlg(weld::Window* pParent, const SfxItemSet* pAttr, ::sd::View const * pView) + : SfxSingleTabDialogController(pParent, pAttr, "modules/simpress/ui/interactiondialog.ui", + "InteractionDialog") +{ + std::unique_ptr<SfxTabPage> xNewPage = SdTPAction::Create(get_content_area(), this, *pAttr); + + // formerly in PageCreated + static_cast<SdTPAction*>( xNewPage.get() )->SetView( pView ); + static_cast<SdTPAction*>( xNewPage.get() )->Construct(); + + SetTabPage(std::move(xNewPage)); +} + +/** + * Action-TabPage + */ +SdTPAction::SdTPAction(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs) + : SfxTabPage(pPage, pController, "modules/simpress/ui/interactionpage.ui", "InteractionPage", &rInAttrs) + , mpView(nullptr) + , mpDoc(nullptr) + , bTreeUpdated(false) + , m_xLbAction(m_xBuilder->weld_combo_box("listbox")) + , m_xFtTree(m_xBuilder->weld_label("fttree")) + , m_xLbTree(new SdPageObjsTLV(m_xBuilder->weld_tree_view("tree"))) + , m_xLbTreeDocument(new SdPageObjsTLV(m_xBuilder->weld_tree_view("treedoc"))) + , m_xLbOLEAction(m_xBuilder->weld_tree_view("oleaction")) + , m_xFrame(m_xBuilder->weld_frame("frame")) + , m_xEdtSound(m_xBuilder->weld_entry("sound")) + , m_xEdtBookmark(m_xBuilder->weld_entry("bookmark")) + , m_xEdtDocument(m_xBuilder->weld_entry("document")) + , m_xEdtProgram(m_xBuilder->weld_entry("program")) + , m_xEdtMacro(m_xBuilder->weld_entry("macro")) + , m_xBtnSearch(m_xBuilder->weld_button("browse")) + , m_xBtnSeek(m_xBuilder->weld_button("find")) +{ + m_xLbOLEAction->set_size_request(m_xLbOLEAction->get_approximate_digit_width() * 48, + m_xLbOLEAction->get_height_rows(12)); + + m_xBtnSearch->connect_clicked( LINK( this, SdTPAction, ClickSearchHdl ) ); + m_xBtnSeek->connect_clicked( LINK( this, SdTPAction, ClickSearchHdl ) ); + + // this page needs ExchangeSupport + SetExchangeSupport(); + + m_xLbAction->connect_changed( LINK( this, SdTPAction, ClickActionHdl ) ); + m_xLbTree->connect_changed( LINK( this, SdTPAction, SelectTreeHdl ) ); + m_xEdtDocument->connect_focus_out( LINK( this, SdTPAction, CheckFileHdl ) ); + m_xEdtMacro->connect_focus_out( LINK( this, SdTPAction, CheckFileHdl ) ); + + //Lock to initial max size + Size aSize(m_xContainer->get_preferred_size()); + m_xContainer->set_size_request(aSize.Width(), aSize.Height()); + + ClickActionHdl( *m_xLbAction ); +} + +SdTPAction::~SdTPAction() +{ +} + +void SdTPAction::SetView( const ::sd::View* pSdView ) +{ + mpView = pSdView; + + // get ColorTable and fill ListBox + ::sd::DrawDocShell* pDocSh = mpView->GetDocSh(); + if( pDocSh && pDocSh->GetViewShell() ) + { + mpDoc = pDocSh->GetDoc(); + SfxViewFrame* pFrame = pDocSh->GetViewShell()->GetViewFrame(); + m_xLbTree->SetViewFrame( pFrame ); + m_xLbTreeDocument->SetViewFrame( pFrame ); + + pColList = pDocSh->GetItem( SID_COLOR_TABLE )->GetColorList(); + DBG_ASSERT( pColList.is(), "No color table available!" ); + } + else + { + OSL_FAIL("sd::SdTPAction::SetView(), no docshell or viewshell?"); + } +} + +void SdTPAction::Construct() +{ + // fill OLE-Actionlistbox + SdrOle2Obj* pOleObj = nullptr; + SdrGrafObj* pGrafObj = nullptr; + bool bOLEAction = false; + + if ( mpView->AreObjectsMarked() ) + { + const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); + if (rMarkList.GetMarkCount() == 1) + { + SdrMark* pMark = rMarkList.GetMark(0); + SdrObject* pObj = pMark->GetMarkedSdrObj(); + + SdrInventor nInv = pObj->GetObjInventor(); + SdrObjKind nSdrObjKind = pObj->GetObjIdentifier(); + + if (nInv == SdrInventor::Default && nSdrObjKind == SdrObjKind::OLE2) + { + pOleObj = static_cast<SdrOle2Obj*>(pObj); + } + else if (nInv == SdrInventor::Default && nSdrObjKind == SdrObjKind::Graphic) + { + pGrafObj = static_cast<SdrGrafObj*>(pObj); + } + } + } + if( pGrafObj ) + { + bOLEAction = true; + + aVerbVector.push_back( 0 ); + m_xLbOLEAction->append_text( MnemonicGenerator::EraseAllMnemonicChars( SdResId( STR_EDIT_OBJ ) ) ); + } + else if( pOleObj ) + { + const uno::Reference < embed::XEmbeddedObject >& xObj = pOleObj->GetObjRef(); + if ( xObj.is() ) + { + bOLEAction = true; + uno::Sequence < embed::VerbDescriptor > aVerbs; + try + { + aVerbs = xObj->getSupportedVerbs(); + } + catch ( embed::NeedsRunningStateException& ) + { + xObj->changeState( embed::EmbedStates::RUNNING ); + aVerbs = xObj->getSupportedVerbs(); + } + + for( const embed::VerbDescriptor& aVerb : std::as_const(aVerbs) ) + { + if( aVerb.VerbAttributes & embed::VerbAttributes::MS_VERBATTR_ONCONTAINERMENU ) + { + OUString aTmp( aVerb.VerbName ); + aVerbVector.push_back( aVerb.VerbID ); + m_xLbOLEAction->append_text( MnemonicGenerator::EraseAllMnemonicChars( aTmp ) ); + } + } + } + } + + maCurrentActions.push_back( presentation::ClickAction_NONE ); + maCurrentActions.push_back( presentation::ClickAction_PREVPAGE ); + maCurrentActions.push_back( presentation::ClickAction_NEXTPAGE ); + maCurrentActions.push_back( presentation::ClickAction_FIRSTPAGE ); + maCurrentActions.push_back( presentation::ClickAction_LASTPAGE ); + maCurrentActions.push_back( presentation::ClickAction_BOOKMARK ); + maCurrentActions.push_back( presentation::ClickAction_DOCUMENT ); + maCurrentActions.push_back( presentation::ClickAction_SOUND ); + if( bOLEAction && m_xLbOLEAction->n_children() ) + maCurrentActions.push_back( presentation::ClickAction_VERB ); + maCurrentActions.push_back( presentation::ClickAction_PROGRAM ); + maCurrentActions.push_back( presentation::ClickAction_MACRO ); + maCurrentActions.push_back( presentation::ClickAction_STOPPRESENTATION ); + + // fill Action-Listbox + for (const presentation::ClickAction & rAction : maCurrentActions) + { + TranslateId pRId = GetClickActionSdResId(rAction); + m_xLbAction->append_text(SdResId(pRId)); + } + +} + +bool SdTPAction::FillItemSet( SfxItemSet* rAttrs ) +{ + bool bModified = false; + presentation::ClickAction eCA = presentation::ClickAction_NONE; + + if (m_xLbAction->get_active() != -1) + eCA = GetActualClickAction(); + + if( m_xLbAction->get_value_changed_from_saved() ) + { + rAttrs->Put( SfxUInt16Item( ATTR_ACTION, static_cast<sal_uInt16>(eCA) ) ); + bModified = true; + } + else + rAttrs->InvalidateItem( ATTR_ACTION ); + + OUString aFileName = GetEditText( true ); + if( aFileName.isEmpty() ) + rAttrs->InvalidateItem( ATTR_ACTION_FILENAME ); + else + { + if( mpDoc && mpDoc->GetDocSh() && mpDoc->GetDocSh()->GetMedium() ) + { + OUString aBaseURL = mpDoc->GetDocSh()->GetMedium()->GetBaseURL(); + if( eCA == presentation::ClickAction_SOUND || + eCA == presentation::ClickAction_DOCUMENT || + eCA == presentation::ClickAction_PROGRAM ) + aFileName = ::URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), aFileName, URIHelper::GetMaybeFileHdl(), true, false, + INetURLObject::EncodeMechanism::WasEncoded, + INetURLObject::DecodeMechanism::Unambiguous ); + + rAttrs->Put( SfxStringItem( ATTR_ACTION_FILENAME, aFileName ) ); + bModified = true; + } + else + { + OSL_FAIL("sd::SdTPAction::FillItemSet(), I need a medium!"); + } + } + + return bModified; +} + +void SdTPAction::Reset( const SfxItemSet* rAttrs ) +{ + presentation::ClickAction eCA = presentation::ClickAction_NONE; + OUString aFileName; + + // m_xLbAction + if( rAttrs->GetItemState( ATTR_ACTION ) != SfxItemState::DONTCARE ) + { + eCA = static_cast<presentation::ClickAction>(static_cast<const SfxUInt16Item&>( rAttrs-> + Get( ATTR_ACTION ) ).GetValue()); + SetActualClickAction( eCA ); + } + else + m_xLbAction->set_active(-1); + + // m_xEdtSound + if( rAttrs->GetItemState( ATTR_ACTION_FILENAME ) != SfxItemState::DONTCARE ) + { + aFileName = static_cast<const SfxStringItem&>( rAttrs->Get( ATTR_ACTION_FILENAME ) ).GetValue(); + SetEditText( aFileName ); + } + + switch( eCA ) + { + case presentation::ClickAction_BOOKMARK: + { + if (!m_xLbTree->SelectEntry(aFileName)) + m_xLbTree->unselect_all(); + } + break; + + case presentation::ClickAction_DOCUMENT: + { + if( comphelper::string::getTokenCount(aFileName, DOCUMENT_TOKEN) == 2 ) + m_xLbTreeDocument->SelectEntry( o3tl::getToken(aFileName, 1, DOCUMENT_TOKEN ) ); + } + break; + + default: + break; + } + ClickActionHdl( *m_xLbAction ); + + m_xLbAction->save_value(); + m_xEdtSound->save_value(); +} + +void SdTPAction::ActivatePage( const SfxItemSet& ) +{ +} + +DeactivateRC SdTPAction::DeactivatePage( SfxItemSet* pPageSet ) +{ + if( pPageSet ) + FillItemSet( pPageSet ); + + return DeactivateRC::LeavePage; +} + +std::unique_ptr<SfxTabPage> SdTPAction::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrs) +{ + return std::make_unique<SdTPAction>( pPage, pController, rAttrs ); +} + +void SdTPAction::UpdateTree() +{ + if( !bTreeUpdated && mpDoc && mpDoc->GetDocSh() && mpDoc->GetDocSh()->GetMedium() ) + { + m_xLbTree->Fill( mpDoc, true, mpDoc->GetDocSh()->GetMedium()->GetName() ); + bTreeUpdated = true; + } +} + +void SdTPAction::OpenFileDialog() +{ + // Soundpreview only for interaction with sound + presentation::ClickAction eCA = GetActualClickAction(); + bool bSound = ( eCA == presentation::ClickAction_SOUND ); + bool bPage = ( eCA == presentation::ClickAction_BOOKMARK ); + bool bDocument = ( eCA == presentation::ClickAction_DOCUMENT || + eCA == presentation::ClickAction_PROGRAM ); + bool bMacro = ( eCA == presentation::ClickAction_MACRO ); + + if( bPage ) + { + // search in the TreeLB for the specified object + m_xLbTree->SelectEntry(GetEditText()); + } + else + { + OUString aFile( GetEditText() ); + + if (bSound) + { + SdOpenSoundFileDialog aFileDialog(GetFrameWeld()); + + if( !aFile.isEmpty() ) + aFileDialog.SetPath( aFile ); + + if( aFileDialog.Execute() == ERRCODE_NONE ) + { + aFile = aFileDialog.GetPath(); + SetEditText( aFile ); + } + } + else if (bMacro) + { + // choose macro dialog + OUString aScriptURL = SfxApplication::ChooseScript(GetFrameWeld()); + + if ( !aScriptURL.isEmpty() ) + { + SetEditText( aScriptURL ); + } + } + else + { + sfx2::FileDialogHelper aFileDialog( + ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION, + FileDialogFlags::NONE, GetFrameWeld()); + aFileDialog.SetContext(sfx2::FileDialogHelper::ImpressClickAction); + + // The following is a workaround for #i4306#: + // The addition of the implicitly existing "all files" + // filter makes the (Windows system) open file dialog follow + // links on the desktop to directories. + aFileDialog.AddFilter ( + SfxResId(STR_SFX_FILTERNAME_ALL), + "*.*"); + + if( aFileDialog.Execute() == ERRCODE_NONE ) + { + aFile = aFileDialog.GetPath(); + SetEditText( aFile ); + } + if( bDocument ) + CheckFileHdl( *m_xEdtDocument ); + } + } +} + +IMPL_LINK_NOARG(SdTPAction, ClickSearchHdl, weld::Button&, void) +{ + OpenFileDialog(); +} + +IMPL_LINK_NOARG(SdTPAction, ClickActionHdl, weld::ComboBox&, void) +{ + presentation::ClickAction eCA = GetActualClickAction(); + + // hide controls we don't need + switch( eCA ) + { + case presentation::ClickAction_NONE: + case presentation::ClickAction_INVISIBLE: + case presentation::ClickAction_PREVPAGE: + case presentation::ClickAction_NEXTPAGE: + case presentation::ClickAction_FIRSTPAGE: + case presentation::ClickAction_LASTPAGE: + case presentation::ClickAction_STOPPRESENTATION: + default: + m_xFtTree->hide(); + m_xLbTree->hide(); + m_xLbTreeDocument->hide(); + m_xLbOLEAction->hide(); + + m_xFrame->hide(); + m_xEdtSound->hide(); + m_xEdtBookmark->hide(); + m_xEdtDocument->hide(); + m_xEdtProgram->hide(); + m_xEdtMacro->hide(); + m_xBtnSearch->hide(); + m_xBtnSeek->hide(); + break; + + case presentation::ClickAction_SOUND: + case presentation::ClickAction_PROGRAM: + case presentation::ClickAction_MACRO: + m_xFtTree->hide(); + m_xLbTree->hide(); + m_xLbTreeDocument->hide(); + m_xLbOLEAction->hide(); + + m_xEdtDocument->hide(); + + if( eCA == presentation::ClickAction_MACRO ) + { + m_xEdtSound->hide(); + m_xEdtProgram->hide(); + } + else if( eCA == presentation::ClickAction_PROGRAM ) + { + m_xEdtSound->hide(); + m_xEdtMacro->hide(); + } + else if( eCA == presentation::ClickAction_SOUND ) + { + m_xEdtProgram->hide(); + m_xEdtMacro->hide(); + } + + m_xBtnSeek->hide(); + break; + + case presentation::ClickAction_DOCUMENT: + m_xLbTree->hide(); + m_xLbOLEAction->hide(); + + m_xEdtSound->hide(); + m_xEdtProgram->hide(); + m_xEdtMacro->hide(); + m_xEdtBookmark->hide(); + m_xBtnSeek->hide(); + break; + + case presentation::ClickAction_BOOKMARK: + m_xLbTreeDocument->hide(); + m_xLbOLEAction->hide(); + m_xEdtSound->hide(); + m_xEdtDocument->hide(); + m_xEdtProgram->hide(); + m_xEdtMacro->hide(); + m_xBtnSearch->hide(); + break; + + case presentation::ClickAction_VERB: + m_xLbTree->hide(); + m_xEdtDocument->hide(); + m_xEdtProgram->hide(); + m_xEdtBookmark->hide(); + m_xEdtMacro->hide(); + m_xBtnSearch->hide(); + m_xFrame->hide(); + m_xEdtSound->hide(); + m_xBtnSeek->hide(); + break; + } + + // show controls we do need + switch( eCA ) + { + case presentation::ClickAction_NONE: + case presentation::ClickAction_INVISIBLE: + case presentation::ClickAction_PREVPAGE: + case presentation::ClickAction_NEXTPAGE: + case presentation::ClickAction_FIRSTPAGE: + case presentation::ClickAction_LASTPAGE: + case presentation::ClickAction_STOPPRESENTATION: + // none + break; + + case presentation::ClickAction_SOUND: + m_xFrame->show(); + m_xEdtSound->show(); + m_xEdtSound->set_sensitive(true); + m_xBtnSearch->show(); + m_xBtnSearch->set_sensitive(true); + m_xFrame->set_label( SdResId( STR_EFFECTDLG_SOUND ) ); + break; + + case presentation::ClickAction_PROGRAM: + case presentation::ClickAction_MACRO: + m_xFrame->show(); + m_xBtnSearch->show(); + m_xBtnSearch->set_sensitive(true); + if( eCA == presentation::ClickAction_MACRO ) + { + m_xEdtMacro->show(); + m_xFrame->set_label( SdResId( STR_EFFECTDLG_MACRO ) ); + } + else + { + m_xEdtProgram->show(); + m_xFrame->set_label( SdResId( STR_EFFECTDLG_PROGRAM ) ); + } + break; + + case presentation::ClickAction_DOCUMENT: + m_xFtTree->show(); + m_xLbTreeDocument->show(); + + m_xFrame->show(); + m_xEdtDocument->show(); + m_xBtnSearch->show(); + m_xBtnSearch->set_sensitive(true); + + m_xFtTree->set_label( SdResId( STR_EFFECTDLG_JUMP ) ); + m_xFrame->set_label( SdResId( STR_EFFECTDLG_DOCUMENT ) ); + + CheckFileHdl( *m_xEdtDocument ); + break; + + case presentation::ClickAction_VERB: + m_xFtTree->show(); + m_xLbOLEAction->show(); + + m_xFtTree->set_label( SdResId( STR_EFFECTDLG_ACTION ) ); + break; + + case presentation::ClickAction_BOOKMARK: + UpdateTree(); + + m_xFtTree->show(); + m_xLbTree->show(); + + m_xFrame->show(); + m_xEdtBookmark->show(); + m_xBtnSeek->show(); + + m_xFtTree->set_label( SdResId( STR_EFFECTDLG_JUMP ) ); + m_xFrame->set_label( SdResId( STR_EFFECTDLG_PAGE_OBJECT ) ); + break; + default: + break; + } +} + +IMPL_LINK_NOARG(SdTPAction, SelectTreeHdl, weld::TreeView&, void) +{ + m_xEdtBookmark->set_text( m_xLbTree->get_selected_text() ); +} + +IMPL_LINK_NOARG(SdTPAction, CheckFileHdl, weld::Widget&, void) +{ + OUString aFile( GetEditText() ); + + if( aFile == aLastFile ) + return; + + bool bHideTreeDocument = true; + + if (mpDoc) + { + // check if it is a valid draw file + SfxMedium aMedium( aFile, + StreamMode::READ | StreamMode::NOCREATE ); + + if( aMedium.IsStorage() ) + { + weld::WaitObject aWait(GetFrameWeld()); + + // is it a draw file? + // open with READ, otherwise the Storages might write into the file! + uno::Reference < embed::XStorage > xStorage = aMedium.GetStorage(); + DBG_ASSERT( xStorage.is(), "No storage!" ); + + if (xStorage.is()) + { + try + { + if (xStorage->hasByName(pStarDrawXMLContent)) + { + if (SdDrawDocument* pBookmarkDoc = mpDoc->OpenBookmarkDoc(aFile)) + { + aLastFile = aFile; + + m_xLbTreeDocument->clear(); + m_xLbTreeDocument->Fill(pBookmarkDoc, true, aFile); + mpDoc->CloseBookmarkDoc(); + m_xLbTreeDocument->show(); + bHideTreeDocument = false; + } + } + } + catch (...) + { + } + } + } + } + + if (bHideTreeDocument) + m_xLbTreeDocument->hide(); +} + +presentation::ClickAction SdTPAction::GetActualClickAction() +{ + presentation::ClickAction eCA = presentation::ClickAction_NONE; + int nPos = m_xLbAction->get_active(); + if (nPos != -1 && o3tl::make_unsigned(nPos) < maCurrentActions.size()) + eCA = maCurrentActions[ nPos ]; + return eCA; +} + +void SdTPAction::SetActualClickAction( presentation::ClickAction eCA ) +{ + std::vector<css::presentation::ClickAction>::const_iterator pIter = + std::find(maCurrentActions.begin(),maCurrentActions.end(),eCA); + + if ( pIter != maCurrentActions.end() ) + m_xLbAction->set_active(pIter-maCurrentActions.begin()); +} + +void SdTPAction::SetEditText( OUString const & rStr ) +{ + presentation::ClickAction eCA = GetActualClickAction(); + OUString aText(rStr); + + // possibly convert URI back to system path + switch( eCA ) + { + case presentation::ClickAction_DOCUMENT: + if( comphelper::string::getTokenCount(rStr, DOCUMENT_TOKEN) == 2 ) + aText = rStr.getToken( 0, DOCUMENT_TOKEN ); + + [[fallthrough]]; + case presentation::ClickAction_SOUND: + case presentation::ClickAction_PROGRAM: + { + INetURLObject aURL( aText ); + + // try to convert to system path + OUString aTmpStr(aURL.getFSysPath(FSysStyle::Detect)); + + if( !aTmpStr.isEmpty() ) + aText = aTmpStr; // was a system path + } + break; + default: + break; + } + + // set the string to the corresponding control + switch( eCA ) + { + case presentation::ClickAction_SOUND: + m_xEdtSound->set_text(aText ); + break; + case presentation::ClickAction_VERB: + { + ::std::vector< tools::Long >::iterator aFound( ::std::find( aVerbVector.begin(), aVerbVector.end(), rStr.toInt32() ) ); + if( aFound != aVerbVector.end() ) + m_xLbOLEAction->select(aFound - aVerbVector.begin()); + } + break; + case presentation::ClickAction_PROGRAM: + m_xEdtProgram->set_text( aText ); + break; + case presentation::ClickAction_MACRO: + m_xEdtMacro->set_text( aText ); + break; + case presentation::ClickAction_DOCUMENT: + m_xEdtDocument->set_text( aText ); + break; + case presentation::ClickAction_BOOKMARK: + m_xEdtBookmark->set_text( aText ); + break; + default: + break; + } +} + +OUString SdTPAction::GetEditText( bool bFullDocDestination ) +{ + OUString aStr; + presentation::ClickAction eCA = GetActualClickAction(); + + switch( eCA ) + { + case presentation::ClickAction_SOUND: + aStr = m_xEdtSound->get_text(); + break; + case presentation::ClickAction_VERB: + { + const int nPos = m_xLbOLEAction->get_selected_index(); + if (nPos != -1 && o3tl::make_unsigned(nPos) < aVerbVector.size() ) + aStr = OUString::number( aVerbVector[ nPos ] ); + return aStr; + } + case presentation::ClickAction_DOCUMENT: + aStr = m_xEdtDocument->get_text(); + break; + + case presentation::ClickAction_PROGRAM: + aStr = m_xEdtProgram->get_text(); + break; + + case presentation::ClickAction_MACRO: + { + return m_xEdtMacro->get_text(); + } + + case presentation::ClickAction_BOOKMARK: + return m_xEdtBookmark->get_text(); + + default: + break; + } + + // validate file URI + INetURLObject aURL( aStr ); + OUString aBaseURL; + if( mpDoc && mpDoc->GetDocSh() && mpDoc->GetDocSh()->GetMedium() ) + aBaseURL = mpDoc->GetDocSh()->GetMedium()->GetBaseURL(); + + if( !aStr.isEmpty() && aURL.GetProtocol() == INetProtocol::NotValid ) + aURL = INetURLObject( ::URIHelper::SmartRel2Abs( INetURLObject(aBaseURL), aStr, URIHelper::GetMaybeFileHdl() ) ); + + // get adjusted file name + aStr = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ); + + if( bFullDocDestination && + eCA == presentation::ClickAction_DOCUMENT && + m_xLbTreeDocument->get_visible() && + m_xLbTreeDocument->get_selected() ) + { + OUString aTmpStr( m_xLbTreeDocument->get_selected_text() ); + if( !aTmpStr.isEmpty() ) + { + aStr += OUStringChar(DOCUMENT_TOKEN) + aTmpStr; + } + } + + return aStr; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/tpoption.cxx b/sd/source/ui/dlg/tpoption.cxx new file mode 100644 index 000000000..0c534682d --- /dev/null +++ b/sd/source/ui/dlg/tpoption.cxx @@ -0,0 +1,618 @@ +/* -*- 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 <com/sun/star/document/PrinterIndependentLayout.hpp> +#include <com/sun/star/frame/Desktop.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <comphelper/processfactory.hxx> +#include <comphelper/string.hxx> +#include <com/sun/star/uno/Exception.hpp> +#include <sfx2/module.hxx> +#include <svx/svxids.hrc> +#include <svx/strarray.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <svtools/unitconv.hxx> + +#include <sdattr.hrc> +#include <sdresid.hxx> +#include <optsitem.hxx> +#include <tpoption.hxx> +#include <strings.hrc> +#include <app.hrc> +#include <svl/intitem.hxx> +#include <o3tl/string_view.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; + +SdTpOptionsSnap::SdTpOptionsSnap(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs) + : SvxGridTabPage(pPage, pController, rInAttrs) +{ + m_xSnapFrames->show(); +} + +SdTpOptionsSnap::~SdTpOptionsSnap() +{ +} + +bool SdTpOptionsSnap::FillItemSet( SfxItemSet* rAttrs ) +{ + SvxGridTabPage::FillItemSet(rAttrs); + SdOptionsSnapItem aOptsItem; + + aOptsItem.GetOptionsSnap().SetSnapHelplines( m_xCbxSnapHelplines->get_active() ); + aOptsItem.GetOptionsSnap().SetSnapBorder( m_xCbxSnapBorder->get_active() ); + aOptsItem.GetOptionsSnap().SetSnapFrame( m_xCbxSnapFrame->get_active() ); + aOptsItem.GetOptionsSnap().SetSnapPoints( m_xCbxSnapPoints->get_active() ); + aOptsItem.GetOptionsSnap().SetOrtho( m_xCbxOrtho->get_active() ); + aOptsItem.GetOptionsSnap().SetBigOrtho( m_xCbxBigOrtho->get_active() ); + aOptsItem.GetOptionsSnap().SetRotate( m_xCbxRotate->get_active() ); + aOptsItem.GetOptionsSnap().SetSnapArea(static_cast<sal_Int16>(m_xMtrFldSnapArea->get_value(FieldUnit::PIXEL))); + aOptsItem.GetOptionsSnap().SetAngle(Degree100(m_xMtrFldAngle->get_value(FieldUnit::DEGREE))); + aOptsItem.GetOptionsSnap().SetEliminatePolyPointLimitAngle(Degree100(m_xMtrFldBezAngle->get_value(FieldUnit::DEGREE))); + + rAttrs->Put( aOptsItem ); + + // we get a possible existing GridItem, this ensures that we do not set + // some default values by accident + return true; +} + +void SdTpOptionsSnap::Reset( const SfxItemSet* rAttrs ) +{ + SvxGridTabPage::Reset(rAttrs); + + SdOptionsSnapItem aOptsItem( rAttrs->Get( ATTR_OPTIONS_SNAP ) ); + + m_xCbxSnapHelplines->set_active( aOptsItem.GetOptionsSnap().IsSnapHelplines() ); + m_xCbxSnapBorder->set_active( aOptsItem.GetOptionsSnap().IsSnapBorder() ); + m_xCbxSnapFrame->set_active( aOptsItem.GetOptionsSnap().IsSnapFrame() ); + m_xCbxSnapPoints->set_active( aOptsItem.GetOptionsSnap().IsSnapPoints() ); + m_xCbxOrtho->set_active( aOptsItem.GetOptionsSnap().IsOrtho() ); + m_xCbxBigOrtho->set_active( aOptsItem.GetOptionsSnap().IsBigOrtho() ); + m_xCbxRotate->set_active( aOptsItem.GetOptionsSnap().IsRotate() ); + m_xMtrFldSnapArea->set_value(aOptsItem.GetOptionsSnap().GetSnapArea(), FieldUnit::PIXEL); + m_xMtrFldAngle->set_value(aOptsItem.GetOptionsSnap().GetAngle().get(), FieldUnit::DEGREE); + m_xMtrFldBezAngle->set_value(aOptsItem.GetOptionsSnap().GetEliminatePolyPointLimitAngle().get(), FieldUnit::DEGREE); + + ClickRotateHdl_Impl(*m_xCbxRotate); +} + +std::unique_ptr<SfxTabPage> SdTpOptionsSnap::Create( weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet* rAttrs ) +{ + return std::make_unique<SdTpOptionsSnap>(pPage, pController, *rAttrs); +} + +/************************************************************************* +|* +|* TabPage to adjust the content options +|* +\************************************************************************/ +SdTpOptionsContents::SdTpOptionsContents(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs) + : SfxTabPage(pPage, pController, "modules/simpress/ui/sdviewpage.ui", "SdViewPage", &rInAttrs) + , m_xCbxRuler(m_xBuilder->weld_check_button("ruler")) + , m_xCbxDragStripes(m_xBuilder->weld_check_button("dragstripes")) + , m_xCbxHandlesBezier(m_xBuilder->weld_check_button("handlesbezier")) + , m_xCbxMoveOutline(m_xBuilder->weld_check_button("moveoutline")) +{ +} + +SdTpOptionsContents::~SdTpOptionsContents() +{ +} + +bool SdTpOptionsContents::FillItemSet( SfxItemSet* rAttrs ) +{ + bool bModified = false; + + if( m_xCbxRuler->get_state_changed_from_saved() || + m_xCbxMoveOutline->get_state_changed_from_saved() || + m_xCbxDragStripes->get_state_changed_from_saved() || + m_xCbxHandlesBezier->get_state_changed_from_saved() ) + { + SdOptionsLayoutItem aOptsItem; + + aOptsItem.GetOptionsLayout().SetRulerVisible( m_xCbxRuler->get_active() ); + aOptsItem.GetOptionsLayout().SetMoveOutline( m_xCbxMoveOutline->get_active() ); + aOptsItem.GetOptionsLayout().SetDragStripes( m_xCbxDragStripes->get_active() ); + aOptsItem.GetOptionsLayout().SetHandlesBezier( m_xCbxHandlesBezier->get_active() ); + + rAttrs->Put( aOptsItem ); + bModified = true; + } + return bModified; +} + +void SdTpOptionsContents::Reset( const SfxItemSet* rAttrs ) +{ + SdOptionsLayoutItem aLayoutItem( rAttrs->Get( ATTR_OPTIONS_LAYOUT ) ); + + m_xCbxRuler->set_active( aLayoutItem.GetOptionsLayout().IsRulerVisible() ); + m_xCbxMoveOutline->set_active( aLayoutItem.GetOptionsLayout().IsMoveOutline() ); + m_xCbxDragStripes->set_active( aLayoutItem.GetOptionsLayout().IsDragStripes() ); + m_xCbxHandlesBezier->set_active( aLayoutItem.GetOptionsLayout().IsHandlesBezier() ); + + m_xCbxRuler->save_state(); + m_xCbxMoveOutline->save_state(); + m_xCbxDragStripes->save_state(); + m_xCbxHandlesBezier->save_state(); +} + +std::unique_ptr<SfxTabPage> SdTpOptionsContents::Create( weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet* rAttrs ) +{ + return std::make_unique<SdTpOptionsContents>(pPage, pController, *rAttrs); +} + +/************************************************************************* +|* +|* TabPage to adjust the misc options +|* +\************************************************************************/ +#define TABLE_COUNT 12 +#define TOKEN ':' + +SdTpOptionsMisc::SdTpOptionsMisc(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs) + : SfxTabPage(pPage, pController, "modules/simpress/ui/optimpressgeneralpage.ui", "OptSavePage", &rInAttrs) + , nWidth(0) + , nHeight(0) + , m_xCbxQuickEdit(m_xBuilder->weld_check_button("qickedit")) + , m_xCbxPickThrough(m_xBuilder->weld_check_button("textselected")) + , m_xNewDocumentFrame(m_xBuilder->weld_frame("newdocumentframe")) + , m_xCbxStartWithTemplate(m_xBuilder->weld_check_button("startwithwizard")) + , m_xCbxMasterPageCache(m_xBuilder->weld_check_button("backgroundback")) + , m_xCbxCopy(m_xBuilder->weld_check_button("copywhenmove")) + , m_xCbxMarkedHitMovesAlways(m_xBuilder->weld_check_button("objalwymov")) + , m_xPresentationFrame(m_xBuilder->weld_frame("presentationframe")) + , m_xLbMetric(m_xBuilder->weld_combo_box("units")) + , m_xMtrFldTabstop(m_xBuilder->weld_metric_spin_button("metricFields", FieldUnit::MM)) + , m_xCbxEnableSdremote(m_xBuilder->weld_check_button("enremotcont")) + , m_xCbxEnablePresenterScreen(m_xBuilder->weld_check_button("enprsntcons")) + , m_xCbxUsePrinterMetrics(m_xBuilder->weld_check_button("printermetrics")) + , m_xCbxCompatibility(m_xBuilder->weld_check_button("cbCompatibility")) + , m_xScaleFrame(m_xBuilder->weld_frame("scaleframe")) + , m_xCbScale(m_xBuilder->weld_combo_box("scaleBox")) + , m_xNewDocLb(m_xBuilder->weld_label("newdoclbl")) + , m_xFiInfo1(m_xBuilder->weld_label("info1")) + , m_xMtrFldOriginalWidth(m_xBuilder->weld_metric_spin_button("metricWidthFields", FieldUnit::MM)) + , m_xWidthLb(m_xBuilder->weld_label("widthlbl")) + , m_xHeightLb(m_xBuilder->weld_label("heightlbl")) + , m_xFiInfo2(m_xBuilder->weld_label("info2")) + , m_xMtrFldOriginalHeight(m_xBuilder->weld_metric_spin_button("metricHeightFields", FieldUnit::MM)) + , m_xCbxDistort(m_xBuilder->weld_check_button("distortcb")) + , m_xMtrFldInfo1(m_xBuilder->weld_metric_spin_button("metricInfo1Fields", FieldUnit::MM)) + , m_xMtrFldInfo2(m_xBuilder->weld_metric_spin_button("metricInfo2Fields", FieldUnit::MM)) +{ + SetExchangeSupport(); + + // set metric + FieldUnit eFUnit; + + sal_uInt16 nWhich = GetWhich( SID_ATTR_METRIC ); + if ( rInAttrs.GetItemState( nWhich ) >= SfxItemState::DEFAULT ) + { + const SfxUInt16Item& rItem = static_cast<const SfxUInt16Item&>(rInAttrs.Get( nWhich )); + eFUnit = static_cast<FieldUnit>(rItem.GetValue()); + } + else + eFUnit = SfxModule::GetCurrentFieldUnit(); + + SetFieldUnit( *m_xMtrFldTabstop , eFUnit ); + // tdf#148292 - avoid right frame to change position depending on width of this control + m_xMtrFldTabstop->set_size_request(150, -1); + // Impress is default mode, let' hide the entire scale frame etc. + m_xCbxDistort->hide(); + m_xScaleFrame->hide(); + + // fill ListBox with metrics + for (sal_uInt32 i = 0; i < SvxFieldUnitTable::Count(); ++i) + { + OUString sMetric = SvxFieldUnitTable::GetString(i); + sal_uInt32 nFieldUnit = sal_uInt32(SvxFieldUnitTable::GetValue(i)); + m_xLbMetric->append(OUString::number(nFieldUnit), sMetric); + } + m_xLbMetric->connect_changed( LINK( this, SdTpOptionsMisc, SelectMetricHdl_Impl ) ); + + SetFieldUnit( *m_xMtrFldOriginalWidth, eFUnit ); + SetFieldUnit( *m_xMtrFldOriginalHeight, eFUnit ); + m_xMtrFldOriginalWidth->set_max(999999999, FieldUnit::NONE); + m_xMtrFldOriginalHeight->set_max(999999999, FieldUnit::NONE); + + // temporary fields for info texts (for formatting/calculation) + m_xMtrFldInfo1->set_unit( eFUnit ); + m_xMtrFldInfo1->set_max(999999999, FieldUnit::NONE); + m_xMtrFldInfo1->set_digits( 2 ); + m_xMtrFldInfo2->set_unit( eFUnit ); + m_xMtrFldInfo2->set_max(999999999, FieldUnit::NONE); + m_xMtrFldInfo2->set_digits( 2 ); + + // determine PoolUnit + SfxItemPool* pPool = rInAttrs.GetPool(); + DBG_ASSERT( pPool, "Where is the Pool?" ); + ePoolUnit = pPool->GetMetric( SID_ATTR_FILL_HATCH ); + + // Fill the CB + sal_uInt16 aTable[ TABLE_COUNT ] = + { 1, 2, 4, 5, 8, 10, 16, 20, 30, 40, 50, 100 }; + + for( sal_uInt16 i = TABLE_COUNT-1; i > 0 ; i-- ) + m_xCbScale->append_text( GetScale( 1, aTable[i] ) ); + for( sal_uInt16 i = 0; i < TABLE_COUNT; i++ ) + m_xCbScale->append_text( GetScale( aTable[i], 1 ) ); +} + +SdTpOptionsMisc::~SdTpOptionsMisc() +{ +} + +void SdTpOptionsMisc::ActivatePage( const SfxItemSet& rSet ) +{ + // We have to call save_state again since it can happen that the value + // has no effect on other TabPages + m_xLbMetric->save_value(); + // change metric if necessary (since TabPage is in the Dialog where + // the metric is set) + const SfxUInt16Item* pAttr = rSet.GetItemIfSet( SID_ATTR_METRIC , false ); + if( !pAttr ) + return; + + FieldUnit eFUnit = static_cast<FieldUnit>(static_cast<tools::Long>(pAttr->GetValue())); + + if( eFUnit == m_xMtrFldOriginalWidth->get_unit() ) + return; + + // set metrics + sal_Int64 nVal = m_xMtrFldOriginalWidth->denormalize( m_xMtrFldOriginalWidth->get_value( FieldUnit::TWIP ) ); + SetFieldUnit( *m_xMtrFldOriginalWidth, eFUnit, true ); + m_xMtrFldOriginalWidth->set_value( m_xMtrFldOriginalWidth->normalize( nVal ), FieldUnit::TWIP ); + + nVal = m_xMtrFldOriginalHeight->denormalize( m_xMtrFldOriginalHeight->get_value( FieldUnit::TWIP ) ); + SetFieldUnit( *m_xMtrFldOriginalHeight, eFUnit, true ); + m_xMtrFldOriginalHeight->set_value( m_xMtrFldOriginalHeight->normalize( nVal ), FieldUnit::TWIP ); + + if( nWidth == 0 || nHeight == 0 ) + return; + + m_xMtrFldInfo1->set_unit( eFUnit ); + m_xMtrFldInfo2->set_unit( eFUnit ); + + SetMetricValue( *m_xMtrFldInfo1, nWidth, ePoolUnit ); + aInfo1 = m_xMtrFldInfo1->get_text(); + m_xFiInfo1->set_label( aInfo1 ); + + SetMetricValue( *m_xMtrFldInfo2, nHeight, ePoolUnit ); + aInfo2 = m_xMtrFldInfo2->get_text(); + m_xFiInfo2->set_label( aInfo2 ); +} + +DeactivateRC SdTpOptionsMisc::DeactivatePage( SfxItemSet* pActiveSet ) +{ + // check parser + sal_Int32 nX, nY; + if( SetScale( m_xCbScale->get_active_text(), nX, nY ) ) + { + if( pActiveSet ) + FillItemSet( pActiveSet ); + return DeactivateRC::LeavePage; + } + + std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetFrameWeld(), + VclMessageType::Warning, VclButtonsType::YesNo, + SdResId(STR_WARN_SCALE_FAIL))); + if (xWarn->run() == RET_YES) + return DeactivateRC::KeepPage; + + if( pActiveSet ) + FillItemSet( pActiveSet ); + + return DeactivateRC::LeavePage; +} + +bool SdTpOptionsMisc::FillItemSet( SfxItemSet* rAttrs ) +{ + bool bModified = false; + + if( m_xCbxStartWithTemplate->get_state_changed_from_saved() || + m_xCbxMarkedHitMovesAlways->get_state_changed_from_saved() || + m_xCbxQuickEdit->get_state_changed_from_saved() || + m_xCbxPickThrough->get_state_changed_from_saved() || + m_xCbxMasterPageCache->get_state_changed_from_saved() || + m_xCbxCopy->get_state_changed_from_saved() || + m_xCbxEnableSdremote->get_state_changed_from_saved() || + m_xCbxEnablePresenterScreen->get_state_changed_from_saved() || + m_xCbxCompatibility->get_state_changed_from_saved() || + m_xCbxUsePrinterMetrics->get_state_changed_from_saved() || + m_xCbxDistort->get_state_changed_from_saved()) + { + SdOptionsMiscItem aOptsItem; + + aOptsItem.GetOptionsMisc().SetStartWithTemplate( m_xCbxStartWithTemplate->get_active() ); + aOptsItem.GetOptionsMisc().SetMarkedHitMovesAlways( m_xCbxMarkedHitMovesAlways->get_active() ); + aOptsItem.GetOptionsMisc().SetQuickEdit( m_xCbxQuickEdit->get_active() ); + aOptsItem.GetOptionsMisc().SetPickThrough( m_xCbxPickThrough->get_active() ); + aOptsItem.GetOptionsMisc().SetMasterPagePaintCaching( m_xCbxMasterPageCache->get_active() ); + aOptsItem.GetOptionsMisc().SetDragWithCopy( m_xCbxCopy->get_active() ); + aOptsItem.GetOptionsMisc().SetEnableSdremote( m_xCbxEnableSdremote->get_active() ); + aOptsItem.GetOptionsMisc().SetEnablePresenterScreen( m_xCbxEnablePresenterScreen->get_active() ); + aOptsItem.GetOptionsMisc().SetSummationOfParagraphs( m_xCbxCompatibility->get_active() ); + aOptsItem.GetOptionsMisc().SetPrinterIndependentLayout ( + m_xCbxUsePrinterMetrics->get_active() + ? css::document::PrinterIndependentLayout::DISABLED + : css::document::PrinterIndependentLayout::ENABLED); + aOptsItem.GetOptionsMisc().SetCrookNoContortion( m_xCbxDistort->get_active() ); + rAttrs->Put( aOptsItem ); + + bModified = true; + } + + // metric + if (m_xLbMetric->get_value_changed_from_saved()) + { + const sal_Int32 nMPos = m_xLbMetric->get_active(); + sal_uInt16 nFieldUnit = m_xLbMetric->get_id(nMPos).toUInt32(); + rAttrs->Put( SfxUInt16Item( GetWhich( SID_ATTR_METRIC ), nFieldUnit ) ); + bModified = true; + } + + // tabulator space + if( m_xMtrFldTabstop->get_value_changed_from_saved() ) + { + MapUnit eUnit = rAttrs->GetPool()->GetMetric( SID_ATTR_DEFTABSTOP ); + SfxUInt16Item aDef( SID_ATTR_DEFTABSTOP, static_cast<sal_uInt16>(GetCoreValue( *m_xMtrFldTabstop, eUnit )) ); + rAttrs->Put( aDef ); + bModified = true; + } + + sal_Int32 nX, nY; + if( SetScale( m_xCbScale->get_active_text(), nX, nY ) ) + { + rAttrs->Put( SfxInt32Item( ATTR_OPTIONS_SCALE_X, nX ) ); + rAttrs->Put( SfxInt32Item( ATTR_OPTIONS_SCALE_Y, nY ) ); + + bModified = true; + } + + return bModified; +} + +void SdTpOptionsMisc::Reset( const SfxItemSet* rAttrs ) +{ + SdOptionsMiscItem aOptsItem( rAttrs->Get( ATTR_OPTIONS_MISC ) ); + + m_xCbxStartWithTemplate->set_active( aOptsItem.GetOptionsMisc().IsStartWithTemplate() ); + m_xCbxMarkedHitMovesAlways->set_active( aOptsItem.GetOptionsMisc().IsMarkedHitMovesAlways() ); + m_xCbxQuickEdit->set_active( aOptsItem.GetOptionsMisc().IsQuickEdit() ); + m_xCbxPickThrough->set_active( aOptsItem.GetOptionsMisc().IsPickThrough() ); + m_xCbxMasterPageCache->set_active( aOptsItem.GetOptionsMisc().IsMasterPagePaintCaching() ); + m_xCbxCopy->set_active( aOptsItem.GetOptionsMisc().IsDragWithCopy() ); + m_xCbxEnableSdremote->set_active( aOptsItem.GetOptionsMisc().IsEnableSdremote() ); + m_xCbxEnablePresenterScreen->set_active( aOptsItem.GetOptionsMisc().IsEnablePresenterScreen() ); + m_xCbxCompatibility->set_active( aOptsItem.GetOptionsMisc().IsSummationOfParagraphs() ); + m_xCbxUsePrinterMetrics->set_active( aOptsItem.GetOptionsMisc().GetPrinterIndependentLayout()==1 ); + m_xCbxDistort->set_active( aOptsItem.GetOptionsMisc().IsCrookNoContortion() ); + m_xCbxStartWithTemplate->save_state(); + m_xCbxMarkedHitMovesAlways->save_state(); + m_xCbxQuickEdit->save_state(); + m_xCbxPickThrough->save_state(); + + m_xCbxMasterPageCache->save_state(); + m_xCbxCopy->save_state(); + m_xCbxEnableSdremote->save_state(); + m_xCbxEnablePresenterScreen->save_state(); + m_xCbxCompatibility->save_state(); + m_xCbxUsePrinterMetrics->save_state(); + m_xCbxDistort->save_state(); + + // metric + sal_uInt16 nWhich = GetWhich( SID_ATTR_METRIC ); + m_xLbMetric->set_active(-1); + + if ( rAttrs->GetItemState( nWhich ) >= SfxItemState::DEFAULT ) + { + const SfxUInt16Item& rItem = static_cast<const SfxUInt16Item&>(rAttrs->Get( nWhich )); + sal_uInt32 nFieldUnit = static_cast<sal_uInt32>(rItem.GetValue()); + + for (sal_Int32 i = 0, nEntryCount = m_xLbMetric->get_count(); i < nEntryCount; ++i) + { + if (m_xLbMetric->get_id(i).toUInt32() == nFieldUnit) + { + m_xLbMetric->set_active( i ); + break; + } + } + } + + // tabulator space + constexpr auto nWhich2 = SID_ATTR_DEFTABSTOP; + if( rAttrs->GetItemState( nWhich2 ) >= SfxItemState::DEFAULT ) + { + MapUnit eUnit = rAttrs->GetPool()->GetMetric( nWhich2 ); + const SfxUInt16Item& rItem = rAttrs->Get( nWhich2 ); + SetMetricValue( *m_xMtrFldTabstop, rItem.GetValue(), eUnit ); + } + m_xLbMetric->save_value(); + m_xMtrFldTabstop->save_value(); + //Scale + sal_Int32 nX = rAttrs->Get( ATTR_OPTIONS_SCALE_X ).GetValue(); + sal_Int32 nY = rAttrs->Get( ATTR_OPTIONS_SCALE_Y ).GetValue(); + nWidth = static_cast<const SfxUInt32Item&>( rAttrs-> + Get( ATTR_OPTIONS_SCALE_WIDTH ) ).GetValue(); + nHeight = static_cast<const SfxUInt32Item&>( rAttrs-> + Get( ATTR_OPTIONS_SCALE_HEIGHT ) ).GetValue(); + + m_xCbScale->set_entry_text( GetScale( nX, nY ) ); + + m_xMtrFldOriginalWidth->hide(); + m_xMtrFldOriginalWidth->set_text( aInfo1 ); // empty + m_xMtrFldOriginalHeight->hide(); + m_xMtrFldOriginalHeight->set_text( aInfo2 ); //empty + m_xFiInfo1->hide(); + m_xFiInfo2->hide(); + + UpdateCompatibilityControls (); +} + +std::unique_ptr<SfxTabPage> SdTpOptionsMisc::Create( weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet* rAttrs ) +{ + return std::make_unique<SdTpOptionsMisc>( pPage, pController, *rAttrs ); +} + +IMPL_LINK_NOARG(SdTpOptionsMisc, SelectMetricHdl_Impl, weld::ComboBox&, void) +{ + int nPos = m_xLbMetric->get_active(); + if (nPos != -1) + { + FieldUnit eUnit = static_cast<FieldUnit>(m_xLbMetric->get_id(nPos).toUInt32()); + sal_Int64 nVal = + m_xMtrFldTabstop->denormalize(m_xMtrFldTabstop->get_value(FieldUnit::TWIP)); + SetFieldUnit( *m_xMtrFldTabstop, eUnit ); + m_xMtrFldTabstop->set_value( m_xMtrFldTabstop->normalize( nVal ), FieldUnit::TWIP ); + } +} + +void SdTpOptionsMisc::SetImpressMode() +{ +#ifndef ENABLE_SDREMOTE + m_xCbxEnableSdremote->hide(); +#else + (void) this; // loplugin:staticmethods +#endif +} + +void SdTpOptionsMisc::SetDrawMode() +{ + m_xScaleFrame->show(); + m_xNewDocumentFrame->hide(); + m_xCbxEnableSdremote->hide(); + m_xCbxEnablePresenterScreen->hide(); + m_xCbxCompatibility->hide(); + m_xNewDocLb->hide(); + m_xCbScale->show(); + m_xPresentationFrame->hide(); + m_xMtrFldInfo1->hide(); + m_xMtrFldInfo2->hide(); + m_xWidthLb->hide(); + m_xHeightLb->hide(); + m_xFiInfo1->show(); + m_xMtrFldOriginalWidth->show(); + m_xFiInfo2->show(); + m_xMtrFldOriginalHeight->show(); + m_xCbxDistort->show(); + m_xCbxCompatibility->hide(); +} + +OUString SdTpOptionsMisc::GetScale( sal_Int32 nX, sal_Int32 nY ) +{ + return OUString::number(nX) + OUStringChar(TOKEN) + OUString::number(nY); +} + +bool SdTpOptionsMisc::SetScale( std::u16string_view aScale, sal_Int32& rX, sal_Int32& rY ) +{ + if (aScale.empty()) + return false; + + sal_Int32 nIdx {0}; + + std::u16string_view aTmp(o3tl::getToken(aScale, 0, TOKEN, nIdx)); + if (nIdx<0) + return false; // we expect another token! + + if (!comphelper::string::isdigitAsciiString(aTmp)) + return false; + + rX = static_cast<tools::Long>(o3tl::toInt32(aTmp)); + if( rX == 0 ) + return false; + + aTmp = o3tl::getToken(aScale, 0, TOKEN, nIdx); + if (nIdx>=0) + return false; // we require just 2 tokens! + + if (!comphelper::string::isdigitAsciiString(aTmp)) + return false; + + rY = static_cast<tools::Long>(o3tl::toInt32(aTmp)); + return rY != 0; +} + +void SdTpOptionsMisc::UpdateCompatibilityControls() +{ + // Disable the compatibility controls by default. Enable them only when + // there is at least one open document. + bool bIsEnabled = false; + + try + { + // Get a component enumeration from the desktop and search it for documents. + Reference<uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext()); + do + { + Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(xContext); + + Reference<container::XEnumerationAccess> xComponents = + xDesktop->getComponents(); + if ( ! xComponents.is()) + break; + + Reference<container::XEnumeration> xEnumeration ( + xComponents->createEnumeration()); + if ( ! xEnumeration.is()) + break; + + while (xEnumeration->hasMoreElements()) + { + Reference<frame::XModel> xModel (xEnumeration->nextElement(), UNO_QUERY); + if (xModel.is()) + { + // There is at least one model/document: Enable the compatibility controls. + bIsEnabled = true; + break; + } + } + + } + while (false); // One 'loop'. + } + catch (const uno::Exception&) + { + // When there is an exception then simply use the default value of + // bIsEnabled and disable the controls. + } + + m_xCbxCompatibility->set_sensitive(bIsEnabled); + m_xCbxUsePrinterMetrics->set_sensitive(bIsEnabled); +} + +void SdTpOptionsMisc::PageCreated(const SfxAllItemSet& aSet) +{ + const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_SDMODE_FLAG, false); + if (pFlagItem) + { + sal_uInt32 nFlags=pFlagItem->GetValue(); + if ( ( nFlags & SD_DRAW_MODE ) == SD_DRAW_MODE ) + SetDrawMode(); + if ( ( nFlags & SD_IMPRESS_MODE ) == SD_IMPRESS_MODE ) + SetImpressMode(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/unchss.cxx b/sd/source/ui/dlg/unchss.cxx new file mode 100644 index 000000000..7d963cddf --- /dev/null +++ b/sd/source/ui/dlg/unchss.cxx @@ -0,0 +1,119 @@ +/* -*- 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 <svl/itemset.hxx> +#include <svl/style.hxx> +#include <svl/hint.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpool.hxx> +#include <tools/debug.hxx> + +#include <unchss.hxx> + +#include <strings.hrc> +#include <glob.hxx> +#include <sdresid.hxx> +#include <drawdoc.hxx> +#include <stlsheet.hxx> +#include <strings.hxx> + +StyleSheetUndoAction::StyleSheetUndoAction(SdDrawDocument* pTheDoc, + SfxStyleSheet* pTheStyleSheet, + const SfxItemSet* pTheNewItemSet) : + SdUndoAction(pTheDoc) +{ + DBG_ASSERT(pTheStyleSheet, "Undo without StyleSheet ???"); + mpStyleSheet = pTheStyleSheet; + + // Create ItemSets; Attention, it is possible that the new one is from a, + // different pool. Therefore we clone it with its items. + mpNewSet = std::make_unique<SfxItemSet>(static_cast<SfxItemPool&>(SdrObject::GetGlobalDrawObjectItemPool()), pTheNewItemSet->GetRanges()); + SdrModel::MigrateItemSet( pTheNewItemSet, mpNewSet.get(), pTheDoc ); + + mpOldSet = std::make_unique<SfxItemSet>(static_cast<SfxItemPool&>(SdrObject::GetGlobalDrawObjectItemPool()), mpStyleSheet->GetItemSet().GetRanges()); + SdrModel::MigrateItemSet( &mpStyleSheet->GetItemSet(), mpOldSet.get(), pTheDoc ); + + OUString aComment(SdResId(STR_UNDO_CHANGE_PRES_OBJECT)); + OUString aName(mpStyleSheet->GetName()); + + // delete layout name and separator + sal_Int32 nPos = aName.indexOf(SD_LT_SEPARATOR); + if (nPos != -1) + aName = aName.copy(nPos + SD_LT_SEPARATOR.getLength()); + + if (aName == STR_LAYOUT_TITLE) + { + aName = SdResId(STR_PSEUDOSHEET_TITLE); + } + else if (aName == STR_LAYOUT_SUBTITLE) + { + aName = SdResId(STR_PSEUDOSHEET_SUBTITLE); + } + else if (aName == STR_LAYOUT_BACKGROUND) + { + aName = SdResId(STR_PSEUDOSHEET_BACKGROUND); + } + else if (aName == STR_LAYOUT_BACKGROUNDOBJECTS) + { + aName = SdResId(STR_PSEUDOSHEET_BACKGROUNDOBJECTS); + } + else if (aName == STR_LAYOUT_NOTES) + { + aName = SdResId(STR_PSEUDOSHEET_NOTES); + } + else + { + OUString aOutlineStr(SdResId(STR_PSEUDOSHEET_OUTLINE)); + nPos = aName.indexOf(aOutlineStr); + if (nPos != -1) + { + std::u16string_view aNumStr(aName.subView(aOutlineStr.getLength())); + aName = STR_LAYOUT_OUTLINE + aNumStr; + } + } + + // replace placeholder with template name + SetComment(aComment.replaceFirst("$", aName)); +} + +void StyleSheetUndoAction::Undo() +{ + SfxItemSet aNewSet( mpDoc->GetItemPool(), mpOldSet->GetRanges() ); + SdrModel::MigrateItemSet( mpOldSet.get(), &aNewSet, mpDoc ); + + mpStyleSheet->GetItemSet().Set(aNewSet); + if( mpStyleSheet->GetFamily() == SfxStyleFamily::Pseudo ) + static_cast<SdStyleSheet*>(mpStyleSheet)->GetRealStyleSheet()->Broadcast(SfxHint(SfxHintId::DataChanged)); + else + mpStyleSheet->Broadcast(SfxHint(SfxHintId::DataChanged)); +} + +void StyleSheetUndoAction::Redo() +{ + SfxItemSet aNewSet( mpDoc->GetItemPool(), mpOldSet->GetRanges() ); + SdrModel::MigrateItemSet( mpNewSet.get(), &aNewSet, mpDoc ); + + mpStyleSheet->GetItemSet().Set(aNewSet); + if( mpStyleSheet->GetFamily() == SfxStyleFamily::Pseudo ) + static_cast<SdStyleSheet*>(mpStyleSheet)->GetRealStyleSheet()->Broadcast(SfxHint(SfxHintId::DataChanged)); + else + mpStyleSheet->Broadcast(SfxHint(SfxHintId::DataChanged)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/dlg/vectdlg.cxx b/sd/source/ui/dlg/vectdlg.cxx new file mode 100644 index 000000000..2db041e7e --- /dev/null +++ b/sd/source/ui/dlg/vectdlg.cxx @@ -0,0 +1,336 @@ +/* -*- 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 <vcl/vclenum.hxx> +#include <vcl/BitmapReadAccess.hxx> +#include <vcl/metaact.hxx> +#include <vcl/BitmapSimpleColorQuantizationFilter.hxx> +#include <vcl/svapp.hxx> + +#include <DrawDocShell.hxx> +#include <sdmod.hxx> +#include <sdiocmpt.hxx> +#include <vectdlg.hxx> + +#define VECTORIZE_MAX_EXTENT 512 + +SdVectorizeDlg::SdVectorizeDlg(weld::Window* pParent, const Bitmap& rBmp, ::sd::DrawDocShell* pDocShell) + : GenericDialogController(pParent, "modules/sdraw/ui/vectorize.ui", "VectorizeDialog") + , m_pDocSh(pDocShell) + , aBmp(rBmp) + , m_aBmpWin(m_xDialog.get()) + , m_aMtfWin(m_xDialog.get()) + , m_xNmLayers(m_xBuilder->weld_spin_button("colors")) + , m_xMtReduce(m_xBuilder->weld_metric_spin_button("points", FieldUnit::PIXEL)) + , m_xFtFillHoles(m_xBuilder->weld_label("tilesft")) + , m_xMtFillHoles(m_xBuilder->weld_metric_spin_button("tiles", FieldUnit::PIXEL)) + , m_xCbFillHoles(m_xBuilder->weld_check_button("fillholes")) + , m_xBmpWin(new weld::CustomWeld(*m_xBuilder, "source", m_aBmpWin)) + , m_xMtfWin(new weld::CustomWeld(*m_xBuilder, "vectorized", m_aMtfWin)) + , m_xPrgs(m_xBuilder->weld_progress_bar("progressbar")) + , m_xBtnOK(m_xBuilder->weld_button("ok")) + , m_xBtnPreview(m_xBuilder->weld_button("preview")) +{ + const int nWidth = m_xFtFillHoles->get_approximate_digit_width() * 32; + const int nHeight = m_xFtFillHoles->get_text_height() * 16; + m_xBmpWin->set_size_request(nWidth, nHeight); + m_xMtfWin->set_size_request(nWidth, nHeight); + + m_xBtnPreview->connect_clicked( LINK( this, SdVectorizeDlg, ClickPreviewHdl ) ); + m_xBtnOK->connect_clicked( LINK( this, SdVectorizeDlg, ClickOKHdl ) ); + m_xNmLayers->connect_value_changed( LINK( this, SdVectorizeDlg, ModifyHdl ) ); + m_xMtReduce->connect_value_changed( LINK( this, SdVectorizeDlg, MetricModifyHdl ) ); + m_xMtFillHoles->connect_value_changed( LINK( this, SdVectorizeDlg, MetricModifyHdl ) ); + m_xCbFillHoles->connect_toggled( LINK( this, SdVectorizeDlg, ToggleHdl ) ); + + LoadSettings(); + InitPreviewBmp(); +} + +SdVectorizeDlg::~SdVectorizeDlg() +{ +} + +::tools::Rectangle SdVectorizeDlg::GetRect( const Size& rDispSize, const Size& rBmpSize ) +{ + ::tools::Rectangle aRect; + + if( rBmpSize.Width() && rBmpSize.Height() && rDispSize.Width() && rDispSize.Height() ) + { + Size aBmpSize( rBmpSize ); + const double fGrfWH = static_cast<double>(aBmpSize.Width()) / aBmpSize.Height(); + const double fWinWH = static_cast<double>(rDispSize.Width()) / rDispSize.Height(); + + if( fGrfWH < fWinWH ) + { + aBmpSize.setWidth( static_cast<tools::Long>( rDispSize.Height() * fGrfWH ) ); + aBmpSize.setHeight( rDispSize.Height() ); + } + else + { + aBmpSize.setWidth( rDispSize.Width() ); + aBmpSize.setHeight( static_cast<tools::Long>( rDispSize.Width() / fGrfWH) ); + } + + const Point aBmpPos( ( rDispSize.Width() - aBmpSize.Width() ) >> 1, + ( rDispSize.Height() - aBmpSize.Height() ) >> 1 ); + + aRect = ::tools::Rectangle( aBmpPos, aBmpSize ); + } + + return aRect; +} + +void SdVectorizeDlg::InitPreviewBmp() +{ + const ::tools::Rectangle aRect( GetRect( m_aBmpWin.GetOutputSizePixel(), aBmp.GetSizePixel() ) ); + + aPreviewBmp = aBmp; + aPreviewBmp.Scale( aRect.GetSize() ); + m_aBmpWin.SetGraphic(BitmapEx(aPreviewBmp)); +} + +Bitmap SdVectorizeDlg::GetPreparedBitmap( Bitmap const & rBmp, Fraction& rScale ) +{ + Bitmap aNew( rBmp ); + const Size aSizePix( aNew.GetSizePixel() ); + + if( aSizePix.Width() > VECTORIZE_MAX_EXTENT || aSizePix.Height() > VECTORIZE_MAX_EXTENT ) + { + const ::tools::Rectangle aRect( GetRect( Size( VECTORIZE_MAX_EXTENT, VECTORIZE_MAX_EXTENT ), aSizePix ) ); + rScale = Fraction( aSizePix.Width(), aRect.GetWidth() ); + aNew.Scale( aRect.GetSize() ); + } + else + rScale = Fraction( 1, 1 ); + + BitmapEx aNewBmpEx(aNew); + BitmapFilter::Filter(aNewBmpEx, BitmapSimpleColorQuantizationFilter(m_xNmLayers->get_value())); + aNew = aNewBmpEx.GetBitmap(); + + return aNew; +} + +void SdVectorizeDlg::Calculate( Bitmap const & rBmp, GDIMetaFile& rMtf ) +{ + m_pDocSh->SetWaitCursor( true ); + m_xPrgs->set_percentage(0); + + Fraction aScale; + Bitmap aTmp( GetPreparedBitmap( rBmp, aScale ) ); + + if( !aTmp.IsEmpty() ) + { + const Link<::tools::Long,void> aPrgsHdl( LINK( this, SdVectorizeDlg, ProgressHdl ) ); + aTmp.Vectorize( rMtf, static_cast<sal_uInt8>(m_xMtReduce->get_value(FieldUnit::NONE)), &aPrgsHdl ); + + if (m_xCbFillHoles->get_active()) + { + GDIMetaFile aNewMtf; + Bitmap::ScopedReadAccess pRAcc(aTmp); + + if( pRAcc ) + { + const tools::Long nWidth = pRAcc->Width(); + const tools::Long nHeight = pRAcc->Height(); + const tools::Long nTileX = m_xMtFillHoles->get_value(FieldUnit::NONE); + const tools::Long nTileY = m_xMtFillHoles->get_value(FieldUnit::NONE); + assert(nTileX && "div-by-zero"); + const tools::Long nCountX = nWidth / nTileX; + assert(nTileY && "div-by-zero"); + const tools::Long nCountY = nHeight / nTileY; + const tools::Long nRestX = nWidth % nTileX; + const tools::Long nRestY = nHeight % nTileY; + + MapMode aMap( rMtf.GetPrefMapMode() ); + aNewMtf.SetPrefSize( rMtf.GetPrefSize() ); + aNewMtf.SetPrefMapMode( aMap ); + + for( tools::Long nTY = 0; nTY < nCountY; nTY++ ) + { + const tools::Long nY = nTY * nTileY; + + for( tools::Long nTX = 0; nTX < nCountX; nTX++ ) + AddTile( pRAcc.get(), aNewMtf, nTX * nTileX, nTY * nTileY, nTileX, nTileY ); + + if( nRestX ) + AddTile( pRAcc.get(), aNewMtf, nCountX * nTileX, nY, nRestX, nTileY ); + } + + if( nRestY ) + { + const tools::Long nY = nCountY * nTileY; + + for( tools::Long nTX = 0; nTX < nCountX; nTX++ ) + AddTile( pRAcc.get(), aNewMtf, nTX * nTileX, nY, nTileX, nRestY ); + + if( nRestX ) + AddTile( pRAcc.get(), aNewMtf, nCountX * nTileX, nCountY * nTileY, nRestX, nRestY ); + } + + pRAcc.reset(); + + for( size_t n = 0, nCount = rMtf.GetActionSize(); n < nCount; n++ ) + aNewMtf.AddAction( rMtf.GetAction( n )->Clone() ); + + aMap.SetScaleX( aMap.GetScaleX() * aScale ); + aMap.SetScaleY( aMap.GetScaleY() * aScale ); + aNewMtf.SetPrefMapMode( aMap ); + rMtf = aNewMtf; + } + } + } + + m_xPrgs->set_percentage(0); + m_pDocSh->SetWaitCursor( false ); +} + +void SdVectorizeDlg::AddTile( BitmapReadAccess const * pRAcc, GDIMetaFile& rMtf, + tools::Long nPosX, tools::Long nPosY, tools::Long nWidth, tools::Long nHeight ) +{ + sal_uLong nSumR = 0, nSumG = 0, nSumB = 0; + const tools::Long nRight = nPosX + nWidth - 1; + const tools::Long nBottom = nPosY + nHeight - 1; + const double fMult = 1.0 / ( nWidth * nHeight ); + + for( tools::Long nY = nPosY; nY <= nBottom; nY++ ) + { + for( tools::Long nX = nPosX; nX <= nRight; nX++ ) + { + const BitmapColor aPixel( pRAcc->GetColor( nY, nX ) ); + + nSumR += aPixel.GetRed(); + nSumG += aPixel.GetGreen(); + nSumB += aPixel.GetBlue(); + } + } + + const Color aColor( static_cast<sal_uInt8>(FRound( nSumR * fMult )), + static_cast<sal_uInt8>(FRound( nSumG * fMult )), + static_cast<sal_uInt8>(FRound( nSumB * fMult )) ); + + ::tools::Rectangle aRect( Point( nPosX, nPosY ), Size( nWidth + 1, nHeight + 1 ) ); + const Size& rMaxSize = rMtf.GetPrefSize(); + + aRect = Application::GetDefaultDevice()->PixelToLogic(aRect, rMtf.GetPrefMapMode()); + + if( aRect.Right() > ( rMaxSize.Width() - 1 ) ) + aRect.SetRight( rMaxSize.Width() - 1 ); + + if( aRect.Bottom() > ( rMaxSize.Height() - 1 ) ) + aRect.SetBottom( rMaxSize.Height() - 1 ); + + rMtf.AddAction( new MetaLineColorAction( aColor, true ) ); + rMtf.AddAction( new MetaFillColorAction( aColor, true ) ); + rMtf.AddAction( new MetaRectAction( aRect ) ); +} + +IMPL_LINK( SdVectorizeDlg, ProgressHdl, tools::Long, nData, void ) +{ + m_xPrgs->set_percentage(nData); +} + +IMPL_LINK_NOARG(SdVectorizeDlg, ClickPreviewHdl, weld::Button&, void) +{ + Calculate( aBmp, aMtf ); + m_aMtfWin.SetGraphic( aMtf ); + m_xBtnPreview->set_sensitive(false); +} + +IMPL_LINK_NOARG(SdVectorizeDlg, ClickOKHdl, weld::Button&, void) +{ + if (m_xBtnPreview->get_sensitive()) + Calculate( aBmp, aMtf ); + + SaveSettings(); + m_xDialog->response(RET_OK); +} + +IMPL_LINK( SdVectorizeDlg, ToggleHdl, weld::Toggleable&, rCb, void ) +{ + if (rCb.get_active()) + { + m_xFtFillHoles->set_sensitive(true); + m_xMtFillHoles->set_sensitive(true); + } + else + { + m_xFtFillHoles->set_sensitive(false); + m_xMtFillHoles->set_sensitive(false); + } + + m_xBtnPreview->set_sensitive(true); +} + +IMPL_LINK_NOARG(SdVectorizeDlg, ModifyHdl, weld::SpinButton&, void) +{ + m_xBtnPreview->set_sensitive(true); +} + +IMPL_LINK_NOARG(SdVectorizeDlg, MetricModifyHdl, weld::MetricSpinButton&, void) +{ + m_xBtnPreview->set_sensitive(true); +} + +void SdVectorizeDlg::LoadSettings() +{ + tools::SvRef<SotStorageStream> xIStm( SD_MOD()->GetOptionStream( + SD_OPTION_VECTORIZE , + SdOptionStreamMode::Load ) ); + sal_uInt16 nLayers; + sal_uInt16 nReduce; + sal_uInt16 nFillHoles; + bool bFillHoles; + + if( xIStm.is() ) + { + SdIOCompat aCompat( *xIStm, StreamMode::READ ); + xIStm->ReadUInt16( nLayers ).ReadUInt16( nReduce ).ReadUInt16( nFillHoles ).ReadCharAsBool( bFillHoles ); + } + else + { + nLayers = 8; + nReduce = 0; + nFillHoles = 32; + bFillHoles = false; + } + + m_xNmLayers->set_value(nLayers); + m_xMtReduce->set_value(nReduce, FieldUnit::NONE); + m_xMtFillHoles->set_value(nFillHoles, FieldUnit::NONE); + m_xCbFillHoles->set_active(bFillHoles); + + ToggleHdl(*m_xCbFillHoles); +} + +void SdVectorizeDlg::SaveSettings() const +{ + tools::SvRef<SotStorageStream> xOStm( SD_MOD()->GetOptionStream( + SD_OPTION_VECTORIZE , + SdOptionStreamMode::Store ) ); + + if( xOStm.is() ) + { + SdIOCompat aCompat( *xOStm, StreamMode::WRITE, 1 ); + xOStm->WriteUInt16( m_xNmLayers->get_value() ).WriteUInt16(m_xMtReduce->get_value(FieldUnit::NONE)); + xOStm->WriteUInt16( m_xMtFillHoles->get_value(FieldUnit::NONE) ).WriteBool(m_xCbFillHoles->get_active()); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |