diff options
Diffstat (limited to 'sc/source/ui/pagedlg')
-rw-r--r-- | sc/source/ui/pagedlg/areasdlg.cxx | 788 | ||||
-rw-r--r-- | sc/source/ui/pagedlg/hfedtdlg.cxx | 191 | ||||
-rw-r--r-- | sc/source/ui/pagedlg/scuitphfedit.cxx | 832 | ||||
-rw-r--r-- | sc/source/ui/pagedlg/tphf.cxx | 239 | ||||
-rw-r--r-- | sc/source/ui/pagedlg/tphfedit.cxx | 274 | ||||
-rw-r--r-- | sc/source/ui/pagedlg/tptable.cxx | 535 |
6 files changed, 2859 insertions, 0 deletions
diff --git a/sc/source/ui/pagedlg/areasdlg.cxx b/sc/source/ui/pagedlg/areasdlg.cxx new file mode 100644 index 000000000..791c4d1e6 --- /dev/null +++ b/sc/source/ui/pagedlg/areasdlg.cxx @@ -0,0 +1,788 @@ +/* -*- 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 <rangelst.hxx> + +#include <sfx2/dispatch.hxx> +#include <svl/stritem.hxx> +#include <vcl/svapp.hxx> +#include <vcl/weld.hxx> +#include <unotools/charclass.hxx> + +#include <areasdlg.hxx> +#include <rangenam.hxx> +#include <reffact.hxx> +#include <tabvwsh.hxx> +#include <docsh.hxx> +#include <globstr.hrc> +#include <scresid.hxx> +#include <compiler.hxx> +#include <markdata.hxx> + +// List box positions for print range (PR) +enum { + SC_AREASDLG_PR_ENTIRE = 1, + SC_AREASDLG_PR_USER = 2, + SC_AREASDLG_PR_SELECT = 3 +}; + +// List box positions for repeat ranges (RR) +enum { + SC_AREASDLG_RR_NONE = 0, + SC_AREASDLG_RR_USER = 1, + SC_AREASDLG_RR_OFFSET = 2 +}; + +#define HDL(hdl) LINK( this, ScPrintAreasDlg, hdl ) +namespace +{ + void ERRORBOX(weld::Window* pParent, const char* rId) + { + std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent, + VclMessageType::Warning, VclButtonsType::Ok, + ScResId(rId))); + xBox->run(); + } +} + +// global functions (->at the end of the file): + +static bool lcl_CheckRepeatString( const OUString& rStr, const ScDocument& rDoc, bool bIsRow, ScRange* pRange ); +static void lcl_GetRepeatRangeString( const ScRange* pRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr ); + +#if 0 +// this method is useful when debugging address flags. +static void printAddressFlags(ScRefFlags nFlag) +{ + if ((nFlag & ScRefFlags::COL_ABS ) == ScRefFlags::COL_ABS ) printf("ScRefFlags::COL_ABS \n"); + if ((nFlag & ScRefFlags::ROW_ABS ) == ScRefFlags::ROW_ABS ) printf("ScRefFlags::ROW_ABS \n"); + if ((nFlag & ScRefFlags::TAB_ABS ) == ScRefFlags::TAB_ABS ) printf("ScRefFlags::TAB_ABS \n"); + if ((nFlag & ScRefFlags::TAB_3D ) == ScRefFlags::TAB_3D ) printf("ScRefFlags::TAB_3D \n"); + if ((nFlag & ScRefFlags::COL2_ABS ) == ScRefFlags::COL2_ABS ) printf("ScRefFlags::COL2_ABS \n"); + if ((nFlag & ScRefFlags::ROW2_ABS ) == ScRefFlags::ROW2_ABS ) printf("ScRefFlags::ROW2_ABS \n"); + if ((nFlag & ScRefFlags::TAB2_ABS ) == ScRefFlags::TAB2_ABS ) printf("ScRefFlags::TAB2_ABS \n"); + if ((nFlag & ScRefFlags::TAB2_3D ) == ScRefFlags::TAB2_3D ) printf("ScRefFlags::TAB2_3D \n"); + if ((nFlag & ScRefFlags::ROW_VALID ) == ScRefFlags::ROW_VALID ) printf("ScRefFlags::ROW_VALID \n"); + if ((nFlag & ScRefFlags::COL_VALID ) == ScRefFlags::COL_VALID ) printf("ScRefFlags::COL_VALID \n"); + if ((nFlag & ScRefFlags::TAB_VALID ) == ScRefFlags::TAB_VALID ) printf("ScRefFlags::TAB_VALID \n"); + if ((nFlag & ScRefFlags::FORCE_DOC ) == ScRefFlags::FORCE_DOC ) printf("ScRefFlags::FORCE_DOC \n"); + if ((nFlag & ScRefFlags::ROW2_VALID ) == ScRefFlags::ROW2_VALID ) printf("ScRefFlags::ROW2_VALID \n"); + if ((nFlag & ScRefFlags::COL2_VALID ) == ScRefFlags::COL2_VALID ) printf("ScRefFlags::COL2_VALID \n"); + if ((nFlag & ScRefFlags::TAB2_VALID ) == ScRefFlags::TAB2_VALID ) printf("ScRefFlags::TAB2_VALID \n"); + if ((nFlag & ScRefFlags::VALID ) == ScRefFlags::VALID ) printf("ScRefFlags::VALID \n"); + if ((nFlag & ScRefFlags::ADDR_ABS ) == ScRefFlags::ADDR_ABS ) printf("ScRefFlags::ADDR_ABS \n"); + if ((nFlag & ScRefFlags::RANGE_ABS ) == ScRefFlags::RANGE_ABS ) printf("ScRefFlags::RANGE_ABS \n"); + if ((nFlag & ScRefFlags::ADDR_ABS_3D ) == ScRefFlags::ADDR_ABS_3D ) printf("ScRefFlags::ADDR_ABS_3D \n"); + if ((nFlag & ScRefFlags::RANGE_ABS_3D ) == ScRefFlags::RANGE_ABS_3D ) printf("ScRefFlags::RANGE_ABS_3D \n"); +} +#endif + + +ScPrintAreasDlg::ScPrintAreasDlg(SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent) + : ScAnyRefDlgController(pB, pCW, pParent, "modules/scalc/ui/printareasdialog.ui", "PrintAreasDialog") + , bDlgLostFocus(false) + , pDoc(nullptr) + , pViewData(nullptr) + , nCurTab(0) + , m_xLbPrintArea(m_xBuilder->weld_combo_box("lbprintarea")) + , m_xEdPrintArea(new formula::RefEdit(m_xBuilder->weld_entry("edprintarea"))) + , m_xRbPrintArea(new formula::RefButton(m_xBuilder->weld_button("rbprintarea"))) + , m_xLbRepeatRow(m_xBuilder->weld_combo_box("lbrepeatrow")) + , m_xEdRepeatRow(new formula::RefEdit(m_xBuilder->weld_entry("edrepeatrow"))) + , m_xRbRepeatRow(new formula::RefButton(m_xBuilder->weld_button("rbrepeatrow"))) + , m_xLbRepeatCol(m_xBuilder->weld_combo_box("lbrepeatcol")) + , m_xEdRepeatCol(new formula::RefEdit(m_xBuilder->weld_entry("edrepeatcol"))) + , m_xRbRepeatCol(new formula::RefButton(m_xBuilder->weld_button("rbrepeatcol"))) + , m_xBtnOk(m_xBuilder->weld_button("ok")) + , m_xBtnCancel(m_xBuilder->weld_button("cancel")) + , m_xPrintFrame(m_xBuilder->weld_frame("printframe")) + , m_xRowFrame(m_xBuilder->weld_frame("rowframe")) + , m_xColFrame(m_xBuilder->weld_frame("colframe")) + , m_xPrintFrameFT(m_xPrintFrame->weld_label_widget()) + , m_xRowFrameFT(m_xRowFrame->weld_label_widget()) + , m_xColFrameFT(m_xColFrame->weld_label_widget()) +{ + m_xEdPrintArea->SetReferences(this, m_xPrintFrameFT.get()); + m_pRefInputEdit = m_xEdPrintArea.get(); + m_xRbPrintArea->SetReferences(this, m_xEdPrintArea.get()); + + m_xEdRepeatRow->SetReferences(this, m_xRowFrameFT.get()); + m_xRbRepeatRow->SetReferences(this, m_xEdRepeatRow.get()); + + m_xEdRepeatCol->SetReferences(this, m_xColFrameFT.get()); + m_xRbRepeatCol->SetReferences(this, m_xEdRepeatCol.get()); + + ScTabViewShell* pScViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() ); + ScDocShell* pScDocSh = dynamic_cast<ScDocShell*>(SfxObjectShell::Current()); + assert(pScDocSh && "Current DocumentShell not found :-("); + + pDoc = &pScDocSh->GetDocument(); + + if ( pScViewSh ) + { + pViewData = &pScViewSh->GetViewData(); + nCurTab = pViewData->GetTabNo(); + } + + Impl_Reset(); + + //@BugID 54702 Enable/Disable only in base class + //SFX_APPWINDOW->Enable(); +} + +ScPrintAreasDlg::~ScPrintAreasDlg() +{ +} + +void ScPrintAreasDlg::Close() +{ + DoClose( ScPrintAreasDlgWrapper::GetChildWindowId() ); +} + +bool ScPrintAreasDlg::IsTableLocked() const +{ + // Printing areas are per table, therefore it makes no sense, + // to switch the table during input + + return true; +} + +void ScPrintAreasDlg::SetReference( const ScRange& rRef, ScDocument& /* rDoc */ ) +{ + if ( m_pRefInputEdit ) + { + if ( rRef.aStart != rRef.aEnd ) + RefInputStart( m_pRefInputEdit ); + + OUString aStr; + const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); + + if (m_xEdPrintArea.get() == m_pRefInputEdit) + { + aStr = rRef.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv); + OUString aVal = m_xEdPrintArea->GetText(); + Selection aSel = m_xEdPrintArea->GetSelection(); + aSel.Justify(); + aVal = aVal.replaceAt( aSel.Min(), aSel.Len(), aStr ); + Selection aNewSel( aSel.Min(), aSel.Min()+aStr.getLength() ); + m_xEdPrintArea->SetRefString( aVal ); + m_xEdPrintArea->SetSelection( aNewSel ); + } + else + { + bool bRow = ( m_xEdRepeatRow.get() == m_pRefInputEdit ); + lcl_GetRepeatRangeString(&rRef, *pDoc, bRow, aStr); + m_pRefInputEdit->SetRefString( aStr ); + } + Impl_ModifyHdl( *m_pRefInputEdit ); + } +} + +void ScPrintAreasDlg::AddRefEntry() +{ + if (m_pRefInputEdit == m_xEdPrintArea.get()) + { + const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep); + OUString aVal = m_xEdPrintArea->GetText() + OUStringChar(sep); + m_xEdPrintArea->SetText(aVal); + + sal_Int32 nLen = aVal.getLength(); + m_xEdPrintArea->SetSelection( Selection( nLen, nLen ) ); + + Impl_ModifyHdl( *m_xEdPrintArea ); + } +} + +void ScPrintAreasDlg::Deactivate() +{ + bDlgLostFocus = true; +} + +void ScPrintAreasDlg::SetActive() +{ + if ( bDlgLostFocus ) + { + bDlgLostFocus = false; + + if ( m_pRefInputEdit ) + { + m_pRefInputEdit->GrabFocus(); + Impl_ModifyHdl( *m_pRefInputEdit ); + } + } + else + m_xDialog->grab_focus(); + + RefInputDone(); +} + +void ScPrintAreasDlg::Impl_Reset() +{ + OUString aStrRange; + const ScRange* pRepeatColRange = pDoc->GetRepeatColRange( nCurTab ); + const ScRange* pRepeatRowRange = pDoc->GetRepeatRowRange( nCurTab ); + + m_xEdPrintArea->SetModifyHdl ( HDL(Impl_ModifyHdl) ); + m_xEdRepeatRow->SetModifyHdl ( HDL(Impl_ModifyHdl) ); + m_xEdRepeatCol->SetModifyHdl ( HDL(Impl_ModifyHdl) ); + m_xEdPrintArea->SetGetFocusHdl( HDL(Impl_GetEditFocusHdl) ); + m_xEdRepeatRow->SetGetFocusHdl( HDL(Impl_GetEditFocusHdl) ); + m_xEdRepeatCol->SetGetFocusHdl( HDL(Impl_GetEditFocusHdl) ); + m_xLbPrintArea->connect_focus_in( HDL(Impl_GetFocusHdl) ); + m_xLbRepeatRow->connect_focus_in( HDL(Impl_GetFocusHdl) ); + m_xLbRepeatCol->connect_focus_in( HDL(Impl_GetFocusHdl) ); + m_xLbPrintArea->connect_changed( HDL(Impl_SelectHdl) ); + m_xLbRepeatRow->connect_changed( HDL(Impl_SelectHdl) ); + m_xLbRepeatCol->connect_changed( HDL(Impl_SelectHdl) ); + m_xBtnOk->connect_clicked( HDL(Impl_BtnHdl) ); + m_xBtnCancel->connect_clicked( HDL(Impl_BtnHdl) ); + + Impl_FillLists(); + + // printing area + + aStrRange.clear(); + const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); + const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep); + sal_uInt16 nRangeCount = pDoc->GetPrintRangeCount( nCurTab ); + for (sal_uInt16 i=0; i<nRangeCount; i++) + { + const ScRange* pPrintRange = pDoc->GetPrintRange( nCurTab, i ); + if (pPrintRange) + { + if ( !aStrRange.isEmpty() ) + aStrRange += OUStringChar(sep); + aStrRange += pPrintRange->Format(*pDoc, ScRefFlags::RANGE_ABS, eConv); + } + } + m_xEdPrintArea->SetText( aStrRange ); + + // repeat row + + lcl_GetRepeatRangeString(pRepeatRowRange, *pDoc, true, aStrRange); + m_xEdRepeatRow->SetText( aStrRange ); + + // repeat column + + lcl_GetRepeatRangeString(pRepeatColRange, *pDoc, false, aStrRange); + m_xEdRepeatCol->SetText( aStrRange ); + + Impl_ModifyHdl( *m_xEdPrintArea ); + Impl_ModifyHdl( *m_xEdRepeatRow ); + Impl_ModifyHdl( *m_xEdRepeatCol ); + if( pDoc->IsPrintEntireSheet( nCurTab ) ) + m_xLbPrintArea->set_active(SC_AREASDLG_PR_ENTIRE); + + m_xEdPrintArea->SaveValue(); // save for FillItemSet(): + m_xEdRepeatRow->SaveValue(); + m_xEdRepeatCol->SaveValue(); +} + +bool ScPrintAreasDlg::Impl_GetItem( const formula::RefEdit* pEd, SfxStringItem& rItem ) +{ + OUString aRangeStr = pEd->GetText(); + bool bDataChanged = pEd->IsValueChangedFromSaved(); + + if ( !aRangeStr.isEmpty() && m_xEdPrintArea.get() != pEd ) + { + ScRange aRange; + const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); + lcl_CheckRepeatString(aRangeStr, *pDoc, m_xEdRepeatRow.get() == pEd, &aRange); + aRangeStr = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv); + } + + rItem.SetValue( aRangeStr ); + + return bDataChanged; +} + +bool ScPrintAreasDlg::Impl_CheckRefStrings() +{ + bool bOk = false; + OUString aStrPrintArea = m_xEdPrintArea->GetText(); + OUString aStrRepeatRow = m_xEdRepeatRow->GetText(); + OUString aStrRepeatCol = m_xEdRepeatCol->GetText(); + + bool bPrintAreaOk = true; + if ( !aStrPrintArea.isEmpty() ) + { + const ScRefFlags nValidAddr = ScRefFlags::VALID | ScRefFlags::ROW_VALID | ScRefFlags::COL_VALID; + const ScRefFlags nValidRange = nValidAddr | ScRefFlags::ROW2_VALID | ScRefFlags::COL2_VALID; + const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); + const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep); + + ScAddress aAddr; + ScRange aRange; + for ( sal_Int32 nIdx = 0; nIdx >= 0; ) + { + const OUString aOne = aStrPrintArea.getToken(0, sep, nIdx); + ScRefFlags nResult = aRange.Parse( aOne, pDoc, eConv ); + if ((nResult & nValidRange) != nValidRange) + { + ScRefFlags nAddrResult = aAddr.Parse( aOne, pDoc, eConv ); + if ((nAddrResult & nValidAddr) != nValidAddr) + { + bPrintAreaOk = false; + break; + } + } + } + } + + bool bRepeatRowOk = aStrRepeatRow.isEmpty(); + if ( !bRepeatRowOk ) + bRepeatRowOk = lcl_CheckRepeatString(aStrRepeatRow, *pDoc, true, nullptr); + + bool bRepeatColOk = aStrRepeatCol.isEmpty(); + if ( !bRepeatColOk ) + bRepeatColOk = lcl_CheckRepeatString(aStrRepeatCol, *pDoc, false, nullptr); + + // error messages + + bOk = (bPrintAreaOk && bRepeatRowOk && bRepeatColOk); + + if ( !bOk ) + { + formula::RefEdit* pEd = nullptr; + + if ( !bPrintAreaOk ) pEd = m_xEdPrintArea.get(); + else if ( !bRepeatRowOk ) pEd = m_xEdRepeatRow.get(); + else if ( !bRepeatColOk ) pEd = m_xEdRepeatCol.get(); + + ERRORBOX(m_xDialog.get(), STR_INVALID_TABREF); + + OSL_ASSERT(pEd); + + if (pEd) + pEd->GrabFocus(); + } + + return bOk; +} + +void ScPrintAreasDlg::Impl_FillLists() +{ + + // Get selection and remember String in PrintArea-ListBox + + ScRange aRange; + OUString aStrRange; + bool bSimple = true; + + if ( pViewData ) + bSimple = (pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE); + + formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention(); + + if ( bSimple ) + aStrRange = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv); + else + { + ScRangeListRef aList( new ScRangeList ); + pViewData->GetMarkData().FillRangeListWithMarks( aList.get(), false ); + aList->Format(aStrRange, ScRefFlags::RANGE_ABS, *pDoc, eConv); + } + + m_xLbPrintArea->set_id(SC_AREASDLG_PR_SELECT, aStrRange); + + // Get ranges and remember in ListBoxen + + ScRangeName* pRangeNames = pDoc->GetRangeName(); + + if (!pRangeNames || pRangeNames->empty()) + // No range names to process. + return; + + for (const auto& rEntry : *pRangeNames) + { + if (!rEntry.second->HasType(ScRangeData::Type::AbsArea ) + && !rEntry.second->HasType(ScRangeData::Type::RefArea) + && !rEntry.second->HasType(ScRangeData::Type::AbsPos )) + continue; + + OUString aName = rEntry.second->GetName(); + OUString aSymbol; + rEntry.second->GetSymbol(aSymbol); + if (aRange.ParseAny(aSymbol, pDoc, eConv) & ScRefFlags::VALID) + { + if (rEntry.second->HasType(ScRangeData::Type::PrintArea)) + { + aSymbol = aRange.Format(*pDoc, ScRefFlags::RANGE_ABS, eConv); + m_xLbPrintArea->append(aSymbol, aName); + } + + if (rEntry.second->HasType(ScRangeData::Type::RowHeader)) + { + lcl_GetRepeatRangeString(&aRange, *pDoc, true, aSymbol); + m_xLbRepeatRow->append(aSymbol, aName); + } + + if (rEntry.second->HasType(ScRangeData::Type::ColHeader)) + { + lcl_GetRepeatRangeString(&aRange, *pDoc, false, aSymbol); + m_xLbRepeatCol->append(aSymbol, aName); + } + } + } +} + +// Handler: + +IMPL_LINK(ScPrintAreasDlg, Impl_BtnHdl, weld::Button&, rBtn, void) +{ + if (m_xBtnOk.get() == &rBtn) + { + if ( Impl_CheckRefStrings() ) + { + OUString aStr; + SfxStringItem aPrintArea( SID_CHANGE_PRINTAREA, aStr ); + SfxStringItem aRepeatRow( FN_PARAM_2, aStr ); + SfxStringItem aRepeatCol( FN_PARAM_3, aStr ); + + // Printing area changed? + + // first try the list box, if "Entire sheet" is selected + bool bEntireSheet = (m_xLbPrintArea->get_active() == SC_AREASDLG_PR_ENTIRE); + SfxBoolItem aEntireSheet( FN_PARAM_4, bEntireSheet ); + + bool bDataChanged = bEntireSheet != pDoc->IsPrintEntireSheet( nCurTab ); + if( !bEntireSheet ) + { + // if new list box selection is not "Entire sheet", get the edit field contents + bDataChanged |= Impl_GetItem( m_xEdPrintArea.get(), aPrintArea ); + } + + // Repeat row changed? + + bDataChanged |= Impl_GetItem( m_xEdRepeatRow.get(), aRepeatRow ); + + // Repeat column changed? + + bDataChanged |= Impl_GetItem( m_xEdRepeatCol.get(), aRepeatCol ); + + if ( bDataChanged ) + { + SetDispatcherLock( false ); + SwitchToDocument(); + GetBindings().GetDispatcher()->ExecuteList(SID_CHANGE_PRINTAREA, + SfxCallMode::SLOT | SfxCallMode::RECORD, + { &aPrintArea, &aRepeatRow, &aRepeatCol, &aEntireSheet }); + } + + response(RET_OK); + } + } + else if (m_xBtnCancel.get() == &rBtn) + response(RET_CANCEL); +} + +IMPL_LINK(ScPrintAreasDlg, Impl_GetEditFocusHdl, formula::RefEdit&, rCtrl, void) +{ + m_pRefInputEdit = &rCtrl; +} + +IMPL_LINK(ScPrintAreasDlg, Impl_GetFocusHdl, weld::Widget&, rCtrl, void) +{ + if (&rCtrl == m_xLbPrintArea.get()) + m_pRefInputEdit = m_xEdPrintArea.get(); + else if (&rCtrl == m_xLbRepeatRow.get()) + m_pRefInputEdit = m_xEdRepeatRow.get(); + else if (&rCtrl == m_xLbRepeatCol.get()) + m_pRefInputEdit = m_xEdRepeatCol.get(); +} + +IMPL_LINK( ScPrintAreasDlg, Impl_SelectHdl, weld::ComboBox&, rLb, void ) +{ + const sal_Int32 nSelPos = rLb.get_active(); + formula::RefEdit* pEd = nullptr; + + // list box positions of specific entries, default to "repeat row/column" list boxes + sal_Int32 nAllSheetPos = SC_AREASDLG_RR_NONE; + sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET; + + // find edit field for list box, and list box positions + if (&rLb == m_xLbPrintArea.get()) + { + pEd = m_xEdPrintArea.get(); + nAllSheetPos = SC_AREASDLG_PR_ENTIRE; + nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following + } + else if (&rLb == m_xLbRepeatCol.get()) + pEd = m_xEdRepeatCol.get(); + else if (&rLb == m_xLbRepeatRow.get()) + pEd = m_xEdRepeatRow.get(); + else + return; + + // fill edit field according to list box selection + if( (nSelPos == 0) || (nSelPos == nAllSheetPos) ) + pEd->SetText( EMPTY_OUSTRING ); + else if( nSelPos >= nFirstCustomPos ) + pEd->SetText(rLb.get_id(nSelPos)); +} + +IMPL_LINK( ScPrintAreasDlg, Impl_ModifyHdl, formula::RefEdit&, rEd, void ) +{ + weld::ComboBox* pLb = nullptr; + + // list box positions of specific entries, default to "repeat row/column" list boxes + sal_Int32 nUserDefPos = SC_AREASDLG_RR_USER; + sal_Int32 nFirstCustomPos = SC_AREASDLG_RR_OFFSET; + + if( &rEd == m_xEdPrintArea.get() ) + { + pLb = m_xLbPrintArea.get(); + nUserDefPos = SC_AREASDLG_PR_USER; + nFirstCustomPos = SC_AREASDLG_PR_SELECT; // "Selection" and following + } + else if( &rEd == m_xEdRepeatCol.get() ) + pLb = m_xLbRepeatCol.get(); + else if( &rEd == m_xEdRepeatRow.get() ) + pLb = m_xLbRepeatRow.get(); + else + return; + + // set list box selection according to edit field + const sal_Int32 nEntryCount = pLb->get_count(); + OUString aStrEd( rEd.GetText() ); + OUString aEdUpper = aStrEd.toAsciiUpperCase(); + + if ( (nEntryCount > nFirstCustomPos) && !aStrEd.isEmpty() ) + { + bool bFound = false; + sal_Int32 i; + + for ( i=nFirstCustomPos; i<nEntryCount && !bFound; i++ ) + { + const OUString& rSymbol = pLb->get_id(i); + bFound = (rSymbol == aStrEd || rSymbol == aEdUpper); + } + + pLb->set_active( bFound ? i-1 : nUserDefPos ); + } + else + pLb->set_active( !aStrEd.isEmpty() ? nUserDefPos : 0 ); +} + +// global functions: + +// TODO: It might make sense to move these functions to address.?xx. -kohei + +static bool lcl_CheckOne_OOO( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal ) +{ + // Allowed syntax for rStr: + // Row: [$]1-MAXTAB + // Col: [$]A-IV + + OUString aStr = rStr; + sal_Int32 nLen = aStr.getLength(); + SCCOLROW nNum = 0; + bool bStrOk = ( nLen > 0 ) && ( bIsRow ? ( nLen < 6 ) : ( nLen < 4 ) ); + + if ( bStrOk ) + { + if ( '$' == aStr[0] ) + aStr = aStr.copy( 1 ); + + if ( bIsRow ) + { + bStrOk = CharClass::isAsciiNumeric(aStr); + + if ( bStrOk ) + { + sal_Int32 n = aStr.toInt32(); + + bStrOk = (n > 0) && ( n <= MAXROWCOUNT ); + if ( bStrOk ) + nNum = static_cast<SCCOLROW>(n - 1); + } + } + else + { + SCCOL nCol = 0; + bStrOk = ::AlphaToCol(rDoc, nCol, aStr); + nNum = nCol; + } + } + + if ( bStrOk ) + rVal = nNum; + + return bStrOk; +} + +static bool lcl_CheckOne_XL_A1( const ScDocument& rDoc, const OUString& rStr, bool bIsRow, SCCOLROW& rVal ) +{ + // XL A1 style is identical to OOO one for print range formats. + return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal); +} + +static bool lcl_CheckOne_XL_R1C1( const OUString& rStr, bool bIsRow, SCCOLROW& rVal ) +{ + sal_Int32 nLen = rStr.getLength(); + if (nLen <= 1) + // There must be at least two characters. + return false; + + const sal_Unicode preUpper = bIsRow ? 'R' : 'C'; + const sal_Unicode preLower = bIsRow ? 'r' : 'c'; + if (rStr[0] != preUpper && rStr[0] != preLower) + return false; + + OUString aNumStr = rStr.copy(1); + if (!CharClass::isAsciiNumeric(aNumStr)) + return false; + + sal_Int32 nNum = aNumStr.toInt32(); + + if (nNum <= 0) + return false; + + if ((bIsRow && nNum > MAXROWCOUNT) || (!bIsRow && nNum > MAXCOLCOUNT)) + return false; + + rVal = static_cast<SCCOLROW>(nNum-1); + return true; +} + +static bool lcl_CheckRepeatOne( const ScDocument& rDoc, const OUString& rStr, formula::FormulaGrammar::AddressConvention eConv, bool bIsRow, SCCOLROW& rVal ) +{ + switch (eConv) + { + case formula::FormulaGrammar::CONV_OOO: + return lcl_CheckOne_OOO(rDoc, rStr, bIsRow, rVal); + case formula::FormulaGrammar::CONV_XL_A1: + return lcl_CheckOne_XL_A1(rDoc, rStr, bIsRow, rVal); + case formula::FormulaGrammar::CONV_XL_R1C1: + return lcl_CheckOne_XL_R1C1(rStr, bIsRow, rVal); + default: + { + // added to avoid warnings + } + } + return false; +} + +static bool lcl_CheckRepeatString( const OUString& rStr, const ScDocument& rDoc, bool bIsRow, ScRange* pRange ) +{ + // Row: [valid row] rsep [valid row] + // Col: [valid col] rsep [valid col] + + const formula::FormulaGrammar::AddressConvention eConv = rDoc.GetAddressConvention(); + const sal_Unicode rsep = ScCompiler::GetNativeSymbolChar(ocRange); + + if (pRange) + { + // initialize the range value. + pRange->aStart.SetCol(0); + pRange->aStart.SetRow(0); + pRange->aEnd.SetCol(0); + pRange->aEnd.SetRow(0); + } + + OUString aBuf; + SCCOLROW nVal = 0; + sal_Int32 nLen = rStr.getLength(); + bool bEndPos = false; + for( sal_Int32 i = 0; i < nLen; ++i ) + { + const sal_Unicode c = rStr[i]; + if (c == rsep) + { + if (bEndPos) + // We aren't supposed to have more than one range separator. + return false; + + // range separator + if (aBuf.isEmpty()) + return false; + + bool bRes = lcl_CheckRepeatOne(rDoc, aBuf, eConv, bIsRow, nVal); + if (!bRes) + return false; + + if (pRange) + { + if (bIsRow) + { + pRange->aStart.SetRow(static_cast<SCROW>(nVal)); + pRange->aEnd.SetRow(static_cast<SCROW>(nVal)); + } + else + { + pRange->aStart.SetCol(static_cast<SCCOL>(nVal)); + pRange->aEnd.SetCol(static_cast<SCCOL>(nVal)); + } + } + + aBuf.clear(); + bEndPos = true; + } + else + aBuf += OUStringChar(c); + } + + if (!aBuf.isEmpty()) + { + bool bRes = lcl_CheckRepeatOne(rDoc, aBuf, eConv, bIsRow, nVal); + if (!bRes) + return false; + + if (pRange) + { + if (bIsRow) + { + if (!bEndPos) + pRange->aStart.SetRow(static_cast<SCROW>(nVal)); + pRange->aEnd.SetRow(static_cast<SCROW>(nVal)); + } + else + { + if (!bEndPos) + pRange->aStart.SetCol(static_cast<SCCOL>(nVal)); + pRange->aEnd.SetCol(static_cast<SCCOL>(nVal)); + } + } + } + + return true; +} + +static void lcl_GetRepeatRangeString( const ScRange* pRange, const ScDocument& rDoc, bool bIsRow, OUString& rStr ) +{ + rStr.clear(); + if (!pRange) + return; + + const formula::FormulaGrammar::AddressConvention eConv = rDoc.GetAddressConvention(); + const ScAddress& rStart = pRange->aStart; + const ScAddress& rEnd = pRange->aEnd; + + const ScRefFlags nFmt = bIsRow + ? (ScRefFlags::ROW_VALID | ScRefFlags::ROW_ABS) + : (ScRefFlags::COL_VALID | ScRefFlags::COL_ABS); + rStr += rStart.Format(nFmt, &rDoc, eConv); + if ((bIsRow && rStart.Row() != rEnd.Row()) || (!bIsRow && rStart.Col() != rEnd.Col())) + { + rStr += ScCompiler::GetNativeSymbol(ocRange); + rStr += rEnd.Format(nFmt, &rDoc, eConv); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/pagedlg/hfedtdlg.cxx b/sc/source/ui/pagedlg/hfedtdlg.cxx new file mode 100644 index 000000000..14fd69866 --- /dev/null +++ b/sc/source/ui/pagedlg/hfedtdlg.cxx @@ -0,0 +1,191 @@ +/* -*- 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 . + */ + +#undef SC_DLLIMPLEMENTATION + +#include <scitems.hxx> +#include <svl/eitem.hxx> + +#include <hfedtdlg.hxx> +#include <globstr.hrc> +#include <scresid.hxx> +#include <scuitphfedit.hxx> +#include <svx/svxids.hrc> +#include <svx/pageitem.hxx> + +ScHFEditDlg::ScHFEditDlg(weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle, + const OUString& rUIXMLDescription, + const OString& rID) + : SfxTabDialogController(pParent, rUIXMLDescription, rID, &rCoreSet) +{ + eNumType = rCoreSet.Get(ATTR_PAGE).GetNumType(); + + OUString aTmp = m_xDialog->get_title() + + " (" + ScResId( STR_PAGESTYLE ) + ": " + rPageStyle + ")"; + + m_xDialog->set_title(aTmp); +} + +ScHFEditHeaderDlg::ScHFEditHeaderDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/headerdialog.ui", "HeaderDialog") +{ + AddTabPage("headerright", ScRightHeaderEditPage::Create, nullptr); + AddTabPage("headerleft", ScLeftHeaderEditPage::Create, nullptr); +} + +ScHFEditFooterDlg::ScHFEditFooterDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/footerdialog.ui", "FooterDialog" ) +{ + AddTabPage("footerright", ScRightFooterEditPage::Create, nullptr); + AddTabPage("footerleft", ScLeftFooterEditPage::Create, nullptr); +} + +ScHFEditLeftHeaderDlg::ScHFEditLeftHeaderDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/leftheaderdialog.ui", "LeftHeaderDialog" ) +{ + AddTabPage("headerleft", ScLeftHeaderEditPage::Create, nullptr); +} + +ScHFEditRightHeaderDlg::ScHFEditRightHeaderDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/rightheaderdialog.ui", "RightHeaderDialog" ) +{ + AddTabPage("headerright", ScRightHeaderEditPage::Create, nullptr); +} + +ScHFEditLeftFooterDlg::ScHFEditLeftFooterDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/leftfooterdialog.ui", "LeftFooterDialog" ) +{ + AddTabPage("footerleft", ScLeftFooterEditPage::Create, nullptr); +} + +ScHFEditRightFooterDlg::ScHFEditRightFooterDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/rightfooterdialog.ui", "RightFooterDialog" ) +{ + AddTabPage("footerright", ScRightFooterEditPage::Create, nullptr); +} + +ScHFEditSharedHeaderDlg::ScHFEditSharedHeaderDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/sharedheaderdialog.ui", "SharedHeaderDialog" ) +{ + AddTabPage("header", ScRightHeaderEditPage::Create, nullptr); + AddTabPage("footerright", ScRightFooterEditPage::Create, nullptr); + AddTabPage("footerleft", ScLeftFooterEditPage::Create, nullptr); +} + +ScHFEditSharedFooterDlg::ScHFEditSharedFooterDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/sharedfooterdialog.ui", "SharedFooterDialog" ) +{ + AddTabPage("headerright", ScRightHeaderEditPage::Create, nullptr); + AddTabPage("headerleft", ScLeftHeaderEditPage::Create, nullptr); + AddTabPage("footer", ScRightFooterEditPage::Create, nullptr); +} + +ScHFEditAllDlg::ScHFEditAllDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/allheaderfooterdialog.ui", "AllHeaderFooterDialog" ) +{ + AddTabPage("headerright", ScRightHeaderEditPage::Create, nullptr); + AddTabPage("headerleft", ScLeftHeaderEditPage::Create, nullptr); + AddTabPage("footerright", ScRightFooterEditPage::Create, nullptr); + AddTabPage("footerleft", ScLeftFooterEditPage::Create, nullptr); +} + +ScHFEditActiveDlg::ScHFEditActiveDlg( + weld::Window* pParent, + const SfxItemSet& rCoreSet, + const OUString& rPageStyle) + : ScHFEditDlg( pParent, rCoreSet, rPageStyle, + "modules/scalc/ui/headerfooterdialog.ui", "HeaderFooterDialog" ) +{ + const SvxPageItem& rPageItem = static_cast<const SvxPageItem&>( + rCoreSet.Get( + rCoreSet.GetPool()->GetWhich(SID_ATTR_PAGE) )); + + bool bRightPage = SvxPageUsage::Left != rPageItem.GetPageUsage(); + + if ( bRightPage ) + { + AddTabPage("header", ScRightHeaderEditPage::Create, nullptr); + AddTabPage("footer", ScRightFooterEditPage::Create, nullptr); + } + else + { + // #69193a# respect "shared" setting + + bool bShareHeader = rCoreSet.Get(ATTR_PAGE_HEADERSET).GetItemSet(). + Get(ATTR_PAGE_SHARED).GetValue(); + if ( bShareHeader ) + AddTabPage("header", ScRightHeaderEditPage::Create, nullptr); + else + AddTabPage("header", ScLeftHeaderEditPage::Create, nullptr); + + bool bShareFooter = rCoreSet.Get(ATTR_PAGE_FOOTERSET).GetItemSet(). + Get(ATTR_PAGE_SHARED).GetValue(); + if ( bShareFooter ) + AddTabPage("footer", ScRightFooterEditPage::Create, nullptr); + else + AddTabPage("footer", ScLeftFooterEditPage::Create, nullptr); + } +} + +void ScHFEditDlg::PageCreated(const OString& /* rId */, SfxTabPage& rPage) +{ + // Can only be a ScHFEditPage... + + static_cast<ScHFEditPage&>(rPage).SetNumType(eNumType); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/pagedlg/scuitphfedit.cxx b/sc/source/ui/pagedlg/scuitphfedit.cxx new file mode 100644 index 000000000..f1336a641 --- /dev/null +++ b/sc/source/ui/pagedlg/scuitphfedit.cxx @@ -0,0 +1,832 @@ +/* -*- 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 . + */ + +#undef SC_DLLIMPLEMENTATION + +#include <scitems.hxx> +#include <editeng/eeitem.hxx> + +#include <editeng/editobj.hxx> +#include <editeng/flditem.hxx> +#include <osl/time.h> +#include <sfx2/tabdlg.hxx> +#include <vcl/settings.hxx> + +#include <unotools/useroptions.hxx> + +#include <editutil.hxx> +#include <global.hxx> +#include <attrib.hxx> +#include <patattr.hxx> + +#include <scuitphfedit.hxx> +#include <memory> + + +ScHFEditPage::ScHFEditPage(weld::Container* pPage, weld::DialogController* pController, + const SfxItemSet& rCoreAttrs, + sal_uInt16 nWhichId, + bool bHeader) + : SfxTabPage(pPage, pController, "modules/scalc/ui/headerfootercontent.ui", "HeaderFooterContent", &rCoreAttrs) + , nWhich( nWhichId ) + , m_bDropDownActive(false) + , m_nTimeToggled(-1) + , m_xFtDefinedHF(m_xBuilder->weld_label(!bHeader ? "labelFT_F_DEFINED" : "labelFT_H_DEFINED")) + , m_xLbDefined(m_xBuilder->weld_combo_box("comboLB_DEFINED")) + , m_xFtCustomHF(m_xBuilder->weld_label(!bHeader ? "labelFT_F_CUSTOM" : "labelFT_H_CUSTOM")) + , m_xBtnText(m_xBuilder->weld_button("buttonBTN_TEXT")) + , m_xBtnFile(m_xBuilder->weld_menu_button("buttonBTN_FILE")) + , m_xBtnTable(m_xBuilder->weld_button("buttonBTN_TABLE")) + , m_xBtnPage(m_xBuilder->weld_button("buttonBTN_PAGE")) + , m_xBtnLastPage(m_xBuilder->weld_button("buttonBTN_PAGES")) + , m_xBtnDate(m_xBuilder->weld_button("buttonBTN_DATE")) + , m_xBtnTime(m_xBuilder->weld_button("buttonBTN_TIME")) + , m_xFtConfidential(m_xBuilder->weld_label("labelSTR_HF_CONFIDENTIAL")) + , m_xFtPage(m_xBuilder->weld_label("labelSTR_PAGE")) + , m_xFtOfQuestion(m_xBuilder->weld_label("labelSTR_HF_OF_QUESTION")) + , m_xFtOf(m_xBuilder->weld_label("labelSTR_HF_OF")) + , m_xFtNone(m_xBuilder->weld_label("labelSTR_HF_NONE_IN_BRACKETS")) + , m_xFtCreatedBy(m_xBuilder->weld_label("labelSTR_HF_CREATED_BY")) + , m_xFtCustomized(m_xBuilder->weld_label("labelSTR_HF_CUSTOMIZED")) + , m_xLeft(m_xBuilder->weld_widget("labelFT_LEFT")) + , m_xRight(m_xBuilder->weld_widget("labelFT_RIGHT")) + , m_xWndLeft(new ScEditWindow(Left, pController->getDialog())) + , m_xWndCenter(new ScEditWindow(Center, pController->getDialog())) + , m_xWndRight(new ScEditWindow(Right, pController->getDialog())) + , m_xWndLeftWnd(new weld::CustomWeld(*m_xBuilder, "textviewWND_LEFT", *m_xWndLeft)) + , m_xWndCenterWnd(new weld::CustomWeld(*m_xBuilder, "textviewWND_CENTER", *m_xWndCenter)) + , m_xWndRightWnd(new weld::CustomWeld(*m_xBuilder, "textviewWND_RIGHT", *m_xWndRight)) + , m_pEditFocus(nullptr) +{ + // tdf#114695 override natural size with a small value + // we expect this to get stretched to some larger but + // limited size based on surrounding widgets + m_xLbDefined->set_size_request(m_xLbDefined->get_approximate_digit_width() * 20, -1); + + //! use default style from current document? + //! if font color is used, header/footer background color must be set + + ScPatternAttr aPatAttr( rCoreAttrs.GetPool() ); + + m_xLbDefined->connect_popup_toggled( LINK( this, ScHFEditPage, ListToggleHdl_Impl) ); + m_xLbDefined->connect_changed( LINK( this, ScHFEditPage, ListHdl_Impl ) ); + m_xBtnFile->connect_selected( LINK( this, ScHFEditPage, MenuHdl ) ); + m_xBtnText->connect_clicked( LINK( this, ScHFEditPage, ClickHdl ) ); + m_xBtnPage->connect_clicked( LINK( this, ScHFEditPage, ClickHdl ) ); + m_xBtnLastPage->connect_clicked( LINK( this, ScHFEditPage, ClickHdl ) ); + m_xBtnDate->connect_clicked( LINK( this, ScHFEditPage, ClickHdl ) ); + m_xBtnTime->connect_clicked( LINK( this, ScHFEditPage, ClickHdl ) ); + m_xBtnTable->connect_clicked( LINK( this, ScHFEditPage, ClickHdl ) ); + + m_xFtDefinedHF->show(); + m_xFtCustomHF->show(); + + //swap left/right areas and their labels in RTL mode + if( AllSettings::GetLayoutRTL() ) + { + sal_Int32 nOldLeftAttach = m_xLeft->get_grid_left_attach(); + sal_Int32 nOldRightAttach = m_xRight->get_grid_left_attach(); + m_xLeft->set_grid_left_attach(nOldRightAttach); + m_xRight->set_grid_left_attach(nOldLeftAttach); + + nOldLeftAttach = m_xWndLeftWnd->get_grid_left_attach(); + nOldRightAttach = m_xWndRightWnd->get_grid_left_attach(); + m_xWndLeftWnd->set_grid_left_attach(nOldRightAttach); + m_xWndRightWnd->set_grid_left_attach(nOldLeftAttach); + } + m_xWndLeft->SetFont( aPatAttr ); + m_xWndCenter->SetFont( aPatAttr ); + m_xWndRight->SetFont( aPatAttr ); + + m_xWndLeft->SetObjectSelectHdl( LINK(this,ScHFEditPage,ObjectSelectHdl) ); + m_xWndCenter->SetObjectSelectHdl( LINK(this,ScHFEditPage,ObjectSelectHdl) ); + m_xWndRight->SetObjectSelectHdl( LINK(this,ScHFEditPage,ObjectSelectHdl) ); + auto setEditFocus = [this](ScEditWindow & rEdit) { this->m_pEditFocus = &rEdit; }; + m_xWndLeft->SetGetFocusHdl(setEditFocus); + m_xWndCenter->SetGetFocusHdl(setEditFocus); + m_xWndRight->SetGetFocusHdl(setEditFocus); + + m_xWndLeft->GrabFocus(); + m_pEditFocus = m_xWndLeft.get(); // there's no event from grab_focus() + + InitPreDefinedList(); + +} + +IMPL_LINK_NOARG( ScHFEditPage, ObjectSelectHdl, ScEditWindow&, void ) +{ + m_xBtnText->grab_focus(); +} + +ScHFEditPage::~ScHFEditPage() +{ +} + +void ScHFEditPage::SetNumType(SvxNumType eNumType) +{ + m_xWndLeft->SetNumType(eNumType); + m_xWndCenter->SetNumType(eNumType); + m_xWndRight->SetNumType(eNumType); +} + +void ScHFEditPage::Reset( const SfxItemSet* rCoreSet ) +{ + const SfxPoolItem* pItem = nullptr; + if ( rCoreSet->HasItem(nWhich, &pItem) ) + { + const ScPageHFItem& rItem = static_cast<const ScPageHFItem&>(*pItem); + + if( const EditTextObject* pLeft = rItem.GetLeftArea() ) + m_xWndLeft->SetText( *pLeft ); + if( const EditTextObject* pCenter = rItem.GetCenterArea() ) + m_xWndCenter->SetText( *pCenter ); + if( const EditTextObject* pRight = rItem.GetRightArea() ) + m_xWndRight->SetText( *pRight ); + + SetSelectDefinedList(); + } +} + +bool ScHFEditPage::FillItemSet( SfxItemSet* rCoreSet ) +{ + ScPageHFItem aItem( nWhich ); + std::unique_ptr<EditTextObject> pLeft = m_xWndLeft->CreateTextObject(); + std::unique_ptr<EditTextObject> pCenter = m_xWndCenter->CreateTextObject(); + std::unique_ptr<EditTextObject> pRight = m_xWndRight->CreateTextObject(); + + aItem.SetLeftArea ( *pLeft ); + aItem.SetCenterArea( *pCenter ); + aItem.SetRightArea ( *pRight ); + + rCoreSet->Put( aItem ); + + return true; +} + +void ScHFEditPage::InitPreDefinedList() +{ + SvtUserOptions aUserOpt; + + std::optional<Color> pTxtColour; + std::optional<Color> pFldColour; + + // Get the all field values at the outset. + OUString aPageFieldValue(m_xWndLeft->GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour)); + OUString aSheetFieldValue(m_xWndLeft->GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour)); + OUString aFileFieldValue(m_xWndLeft->GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour)); + OUString aExtFileFieldValue(m_xWndLeft->GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxExtFileField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour)); + OUString aDateFieldValue(m_xWndLeft->GetEditEngine()->CalcFieldValue(SvxFieldItem(SvxDateField(), EE_FEATURE_FIELD), 0,0, pTxtColour, pFldColour)); + + m_xLbDefined->clear(); + + m_xLbDefined->append_text(m_xFtNone->get_label()); + + OUString aPageEntry(m_xFtPage->get_label() + " " + aPageFieldValue); + m_xLbDefined->append_text(aPageEntry); + + OUString aPageOfEntry(aPageEntry + " " + m_xFtOfQuestion->get_label()); + m_xLbDefined->append_text( aPageOfEntry); + + m_xLbDefined->append_text(aSheetFieldValue); + + OUString aConfidentialEntry(aUserOpt.GetCompany() + " " + m_xFtConfidential->get_label() + ", " + aDateFieldValue + ", " + aPageEntry); + m_xLbDefined->append_text( aConfidentialEntry); + + OUString aFileNamePageEntry(aFileFieldValue + ", " + aPageEntry); + m_xLbDefined->append_text( aFileNamePageEntry); + + m_xLbDefined->append_text( aExtFileFieldValue); + + OUString aPageSheetNameEntry(aPageEntry + ", " + aSheetFieldValue); + m_xLbDefined->append_text( aPageSheetNameEntry); + + OUString aPageFileNameEntry(aPageEntry + ", " + aFileFieldValue); + m_xLbDefined->append_text( aPageFileNameEntry); + + OUString aPagePathNameEntry(aPageEntry + ", " + aExtFileFieldValue); + m_xLbDefined->append_text( aPagePathNameEntry); + + OUString aUserNameEntry(aUserOpt.GetFirstName() + " " + aUserOpt.GetLastName() + ", " + aPageEntry + ", " + aDateFieldValue); + m_xLbDefined->append_text( aUserNameEntry); + + OUString aCreatedByEntry = m_xFtCreatedBy->get_label() + " " + aUserOpt.GetFirstName() + " " + aUserOpt.GetLastName() + ", " + + aDateFieldValue + ", " + aPageEntry; + m_xLbDefined->append_text( aCreatedByEntry); +} + +void ScHFEditPage::InsertToDefinedList() +{ + const sal_Int32 nCount = m_xLbDefined->get_count(); + if(nCount == eEntryCount) + { + m_xLbDefined->append_text( m_xFtCustomized->get_label() ); + m_xLbDefined->set_active(eEntryCount); + } +} + +void ScHFEditPage::RemoveFromDefinedList() +{ + const sal_Int32 nCount = m_xLbDefined->get_count(); + if(nCount > eEntryCount ) + m_xLbDefined->remove( nCount-1); +} + +// determine if the header/footer exists in our predefined list and set select to it. +void ScHFEditPage::SetSelectDefinedList() +{ + SvtUserOptions aUserOpt; + + // default to customized + ScHFEntryId eSelectEntry = eEntryCount; + + std::unique_ptr< EditTextObject > pLeftObj; + std::unique_ptr< EditTextObject > pCenterObj; + std::unique_ptr< EditTextObject > pRightObj; + + OUString aLeftEntry; + OUString aCenterEntry; + OUString aRightEntry; + + pLeftObj = m_xWndLeft->GetEditEngine()->CreateTextObject(); + pCenterObj = m_xWndCenter->GetEditEngine()->CreateTextObject(); + pRightObj = m_xWndRight->GetEditEngine()->CreateTextObject(); + + bool bFound = false; + + const sal_Int32 nCount = m_xLbDefined->get_count(); + for(sal_Int32 i = 0; i < nCount && !bFound; ++i) + { + switch(static_cast<ScHFEntryId>(i)) + { + case eNoneEntry: + { + aLeftEntry = pLeftObj->GetText(0); + aCenterEntry = pCenterObj->GetText(0); + aRightEntry = pRightObj->GetText(0); + if(aLeftEntry == EMPTY_OUSTRING && aCenterEntry == EMPTY_OUSTRING + && aRightEntry == EMPTY_OUSTRING) + { + eSelectEntry = eNoneEntry; + bFound = true; + } + } + break; + + case ePageEntry: + { + aLeftEntry = pLeftObj->GetText(0); + aRightEntry = pRightObj->GetText(0); + if(aLeftEntry == EMPTY_OUSTRING && aRightEntry == EMPTY_OUSTRING) + { + if(IsPageEntry(m_xWndCenter->GetEditEngine(), pCenterObj.get())) + { + eSelectEntry = ePageEntry; + bFound = true; + } + } + } + break; + + //TODO + case ePagesEntry: + { + } + break; + + case eSheetEntry: + { + aLeftEntry = pLeftObj->GetText(0); + aRightEntry = pRightObj->GetText(0); + if(aLeftEntry == EMPTY_OUSTRING && aRightEntry == EMPTY_OUSTRING) + { + if(pCenterObj->IsFieldObject()) + { + const SvxFieldItem* pFieldItem = pCenterObj->GetField(); + if(pFieldItem) + { + const SvxFieldData* pField = pFieldItem->GetField(); + if(dynamic_cast<const SvxTableField*>( pField)) + { + eSelectEntry = eSheetEntry; + bFound = true; + } + } + } + } + } + break; + + case eConfidentialEntry: + { + if(IsDateEntry(pCenterObj.get()) && IsPageEntry(m_xWndRight->GetEditEngine(), pRightObj.get())) + { + OUString aConfidentialEntry(aUserOpt.GetCompany() + " " + m_xFtConfidential->get_label()); + if(aConfidentialEntry == m_xWndLeft->GetEditEngine()->GetText(0)) + { + eSelectEntry = eConfidentialEntry; + bFound = true; + } + } + } + break; + + //TODO + case eFileNamePageEntry: + { + } + break; + + case eExtFileNameEntry: + { + aLeftEntry = pLeftObj->GetText(0); + aRightEntry = pRightObj->GetText(0); + if(IsExtFileNameEntry(pCenterObj.get()) && aLeftEntry == EMPTY_OUSTRING + && aRightEntry == EMPTY_OUSTRING) + { + eSelectEntry = eExtFileNameEntry; + bFound = true; + } + } + break; + + //TODO + case ePageSheetEntry: + { + } + break; + + //TODO + case ePageFileNameEntry: + { + } + break; + + case ePageExtFileNameEntry: + { + aLeftEntry = pLeftObj->GetText(0); + if(IsPageEntry(m_xWndCenter->GetEditEngine(), pCenterObj.get()) && + IsExtFileNameEntry(pRightObj.get()) && aLeftEntry == EMPTY_OUSTRING) + { + eSelectEntry = ePageExtFileNameEntry; + bFound = true; + } + } + break; + + case eUserNameEntry: + { + if(IsDateEntry(pRightObj.get()) && IsPageEntry(m_xWndCenter->GetEditEngine(), pCenterObj.get())) + { + OUString aUserNameEntry(aUserOpt.GetFirstName() + " " + aUserOpt.GetLastName()); + + if(aUserNameEntry == m_xWndLeft->GetEditEngine()->GetText(0)) + { + eSelectEntry = eUserNameEntry; + bFound = true; + } + } + } + break; + + case eCreatedByEntry: + { + if(IsDateEntry(pCenterObj.get()) && IsPageEntry(m_xWndRight->GetEditEngine(), pRightObj.get())) + { + OUString aCreatedByEntry(m_xFtCreatedBy->get_label() + " " + aUserOpt.GetFirstName() + " " + aUserOpt.GetLastName()); + + if(aCreatedByEntry == m_xWndLeft->GetEditEngine()->GetText(0)) + { + eSelectEntry = eCreatedByEntry; + bFound = true; + } + } + } + break; + + default: + { + // added to avoid warnings + } + } + } + + if(eSelectEntry == eEntryCount) + InsertToDefinedList(); + + m_xLbDefined->set_active( sal::static_int_cast<sal_uInt16>( eSelectEntry ) ); +} + +bool ScHFEditPage::IsPageEntry(EditEngine*pEngine, const EditTextObject* pTextObj) +{ + if(!pEngine || !pTextObj) + return false; + + bool bReturn = false; + + if(!pTextObj->IsFieldObject()) + { + std::vector<sal_Int32> aPosList; + pEngine->GetPortions(0,aPosList); + if(aPosList.size() == 2) + { + OUString aPageEntry(m_xFtPage->get_label() + " "); + ESelection aSel(0,0,0,0); + aSel.nEndPos = aPageEntry.getLength(); + if(aPageEntry == pEngine->GetText(aSel)) + { + aSel.nStartPos = aSel.nEndPos; + aSel.nEndPos++; + std::unique_ptr< EditTextObject > pPageObj = pEngine->CreateTextObject(aSel); + if(pPageObj && pPageObj->IsFieldObject() ) + { + const SvxFieldItem* pFieldItem = pPageObj->GetField(); + if(pFieldItem) + { + const SvxFieldData* pField = pFieldItem->GetField(); + if(dynamic_cast<const SvxPageField*>( pField)) + bReturn = true; + } + } + } + } + } + return bReturn; +} + +bool ScHFEditPage::IsDateEntry(const EditTextObject* pTextObj) +{ + if(!pTextObj) + return false; + + bool bReturn = false; + if(pTextObj->IsFieldObject()) + { + const SvxFieldItem* pFieldItem = pTextObj->GetField(); + if(pFieldItem) + { + const SvxFieldData* pField = pFieldItem->GetField(); + if(dynamic_cast<const SvxDateField*>( pField)) + bReturn = true; + } + } + return bReturn; +} + +bool ScHFEditPage::IsExtFileNameEntry(const EditTextObject* pTextObj) +{ + if(!pTextObj) + return false; + bool bReturn = false; + if(pTextObj->IsFieldObject()) + { + const SvxFieldItem* pFieldItem = pTextObj->GetField(); + if(pFieldItem) + { + const SvxFieldData* pField = pFieldItem->GetField(); + if(dynamic_cast<const SvxExtFileField*>( pField)) + bReturn = true; + } + } + return bReturn; +} + +void ScHFEditPage::ProcessDefinedListSel(ScHFEntryId eSel, bool bTravelling) +{ + SvtUserOptions aUserOpt; + std::unique_ptr< EditTextObject > pTextObj; + + switch(eSel) + { + case eNoneEntry: + ClearTextAreas(); + if(!bTravelling) + m_xWndLeft->GrabFocus(); + break; + + case ePageEntry: + { + ClearTextAreas(); + OUString aPageEntry( m_xFtPage->get_label() + " " ); + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + m_xWndCenter->InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) ); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + } + break; + + case ePagesEntry: + { + ClearTextAreas(); + ESelection aSel(0,0,0,0); + OUString aPageEntry( m_xFtPage->get_label() + " "); + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + aSel.nEndPos = aPageEntry.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + ++aSel.nEndPos; + + OUString aPageOfEntry(" " + m_xFtOf->get_label() + " "); + m_xWndCenter->GetEditEngine()->QuickInsertText(aPageOfEntry,ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + aSel.nEndPos = aSel.nEndPos + aPageOfEntry.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + pTextObj = m_xWndCenter->GetEditEngine()->CreateTextObject(); + m_xWndCenter->SetText(*pTextObj); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + } + break; + + case eSheetEntry: + ClearTextAreas(); + m_xWndCenter->InsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD) ); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + break; + + case eConfidentialEntry: + { + ClearTextAreas(); + OUString aConfidentialEntry(aUserOpt.GetCompany() + " " + m_xFtConfidential->get_label()); + m_xWndLeft->GetEditEngine()->SetTextCurrentDefaults(aConfidentialEntry); + m_xWndCenter->InsertField( SvxFieldItem(SvxDateField(Date( Date::SYSTEM ),SvxDateType::Var), EE_FEATURE_FIELD) ); + + OUString aPageEntry( m_xFtPage->get_label() + " "); + m_xWndRight->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + m_xWndRight->InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) ); + if(!bTravelling) + m_xWndRight->GrabFocus(); + } + break; + + case eFileNamePageEntry: + { + ClearTextAreas(); + ESelection aSel(0,0,0,0); + m_xWndCenter->GetEditEngine()->QuickInsertField(SvxFieldItem( SvxFileField(), EE_FEATURE_FIELD ), aSel ); + ++aSel.nEndPos; + OUString aPageEntry(", " + m_xFtPage->get_label() + " "); + m_xWndCenter->GetEditEngine()->QuickInsertText(aPageEntry, ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + aSel.nStartPos = aSel.nEndPos; + aSel.nEndPos = aSel.nEndPos + aPageEntry.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara,aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + pTextObj = m_xWndCenter->GetEditEngine()->CreateTextObject(); + m_xWndCenter->SetText(*pTextObj); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + } + break; + + case eExtFileNameEntry: + ClearTextAreas(); + m_xWndCenter->InsertField( SvxFieldItem( SvxExtFileField( + EMPTY_OUSTRING, SvxFileType::Var, SvxFileFormat::PathFull ), EE_FEATURE_FIELD ) ); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + break; + + case ePageSheetEntry: + { + ClearTextAreas(); + ESelection aSel(0,0,0,0); + OUString aPageEntry( m_xFtPage->get_label() + " " ); + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + aSel.nEndPos = aPageEntry.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + ++aSel.nEndPos; + + OUString aCommaSpace(", "); + m_xWndCenter->GetEditEngine()->QuickInsertText(aCommaSpace,ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + aSel.nEndPos = aSel.nEndPos + aCommaSpace.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField( SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + pTextObj = m_xWndCenter->GetEditEngine()->CreateTextObject(); + m_xWndCenter->SetText(*pTextObj); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + } + break; + + case ePageFileNameEntry: + { + ClearTextAreas(); + ESelection aSel(0,0,0,0); + OUString aPageEntry( m_xFtPage->get_label() + " " ); + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + aSel.nEndPos = aPageEntry.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + ++aSel.nEndPos; + OUString aCommaSpace(", "); + m_xWndCenter->GetEditEngine()->QuickInsertText(aCommaSpace,ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + aSel.nEndPos = aSel.nEndPos + aCommaSpace.getLength(); + m_xWndCenter->GetEditEngine()->QuickInsertField( SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD), ESelection(aSel.nEndPara, aSel.nEndPos, aSel.nEndPara, aSel.nEndPos)); + pTextObj = m_xWndCenter->GetEditEngine()->CreateTextObject(); + m_xWndCenter->SetText(*pTextObj); + if(!bTravelling) + m_xWndCenter->GrabFocus(); + } + break; + + case ePageExtFileNameEntry: + { + ClearTextAreas(); + OUString aPageEntry( m_xFtPage->get_label() + " " ); + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + m_xWndCenter->InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) ); + m_xWndRight->InsertField( SvxFieldItem( SvxExtFileField( + EMPTY_OUSTRING, SvxFileType::Var, SvxFileFormat::PathFull ), EE_FEATURE_FIELD ) ); + if(!bTravelling) + m_xWndRight->GrabFocus(); + } + break; + + case eUserNameEntry: + { + ClearTextAreas(); + OUString aUserNameEntry(aUserOpt.GetFirstName() + " " + aUserOpt.GetLastName()); + m_xWndLeft->GetEditEngine()->SetTextCurrentDefaults(aUserNameEntry); + OUString aPageEntry( m_xFtPage->get_label() + " "); + //aPageEntry += " "; + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + m_xWndCenter->InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) ); + m_xWndRight->InsertField( SvxFieldItem(SvxDateField(Date( Date::SYSTEM ),SvxDateType::Var), EE_FEATURE_FIELD) ); + if(!bTravelling) + m_xWndRight->GrabFocus(); + } + break; + + case eCreatedByEntry: + { + ClearTextAreas(); + OUString aCreatedByEntry( m_xFtCreatedBy->get_label() + " " + aUserOpt.GetFirstName() + " " + aUserOpt.GetLastName()); + m_xWndLeft->GetEditEngine()->SetTextCurrentDefaults(aCreatedByEntry); + m_xWndCenter->InsertField( SvxFieldItem(SvxDateField(Date( Date::SYSTEM ),SvxDateType::Var), EE_FEATURE_FIELD) ); + OUString aPageEntry( m_xFtPage->get_label() + " " ); + m_xWndRight->GetEditEngine()->SetTextCurrentDefaults(aPageEntry); + m_xWndRight->InsertField( SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD) ); + if(!bTravelling) + m_xWndRight->GrabFocus(); + } + break; + + default : + break; + } +} + +void ScHFEditPage::ClearTextAreas() +{ + m_xWndLeft->GetEditEngine()->SetTextCurrentDefaults(EMPTY_OUSTRING); + m_xWndLeft->Invalidate(); + m_xWndCenter->GetEditEngine()->SetTextCurrentDefaults(EMPTY_OUSTRING); + m_xWndCenter->Invalidate(); + m_xWndRight->GetEditEngine()->SetTextCurrentDefaults(EMPTY_OUSTRING); + m_xWndRight->Invalidate(); +} + +// Handler: +IMPL_LINK_NOARG(ScHFEditPage, ListToggleHdl_Impl, weld::ComboBox&, void) +{ + m_bDropDownActive = !m_bDropDownActive; + TimeValue aNow; + osl_getSystemTime(&aNow); + m_nTimeToggled = sal_Int64(aNow.Seconds) * 1000000000L + aNow.Nanosec; +} + +IMPL_LINK_NOARG(ScHFEditPage, ListHdl_Impl, weld::ComboBox&, void) +{ + ScHFEntryId eSel = static_cast<ScHFEntryId>(m_xLbDefined->get_active()); + + TimeValue aNow; + osl_getSystemTime(&aNow); + sal_Int64 nNow = sal_Int64(aNow.Seconds) * 1000000000L + aNow.Nanosec; + + // order of dropdown vs select not guaranteed + bool bDiscrepency = m_xLbDefined->get_popup_shown() != m_bDropDownActive; + if (bDiscrepency) + ListToggleHdl_Impl(*m_xLbDefined); + + bool bFocusToTarget = !m_xLbDefined->get_popup_shown() && m_nTimeToggled != -1 && (nNow - m_nTimeToggled < 800000000L); + ProcessDefinedListSel(eSel, !bFocusToTarget); + // check if we need to remove the customized entry. + if (!m_bDropDownActive && eSel < eEntryCount) + RemoveFromDefinedList(); + + // keep balanced + if (bDiscrepency) + ListToggleHdl_Impl(*m_xLbDefined); +} + +IMPL_LINK( ScHFEditPage, ClickHdl, weld::Button&, rBtn, void ) +{ + if (!m_pEditFocus) + return; + + if (&rBtn == m_xBtnText.get()) + { + m_pEditFocus->SetCharAttributes(); + } + else + { + if ( &rBtn == m_xBtnPage.get() ) + m_pEditFocus->InsertField(SvxFieldItem(SvxPageField(), EE_FEATURE_FIELD)); + else if ( &rBtn == m_xBtnLastPage.get() ) + m_pEditFocus->InsertField(SvxFieldItem(SvxPagesField(), EE_FEATURE_FIELD)); + else if ( &rBtn == m_xBtnDate.get() ) + m_pEditFocus->InsertField(SvxFieldItem(SvxDateField(Date(Date::SYSTEM),SvxDateType::Var), EE_FEATURE_FIELD)); + else if ( &rBtn == m_xBtnTime.get() ) + m_pEditFocus->InsertField(SvxFieldItem(SvxTimeField(), EE_FEATURE_FIELD)); + else if ( &rBtn == m_xBtnTable.get() ) + m_pEditFocus->InsertField(SvxFieldItem(SvxTableField(), EE_FEATURE_FIELD)); + } + InsertToDefinedList(); + m_pEditFocus->GrabFocus(); +} + +IMPL_LINK(ScHFEditPage, MenuHdl, const OString&, rSelectedId, void) +{ + if (!m_pEditFocus) + return; + + if (rSelectedId == "title") + { + m_pEditFocus->InsertField(SvxFieldItem(SvxFileField(), EE_FEATURE_FIELD)); + } + else if (rSelectedId == "filename") + { + m_pEditFocus->InsertField( SvxFieldItem( SvxExtFileField( + OUString(), SvxFileType::Var, SvxFileFormat::NameAndExt ), EE_FEATURE_FIELD ) ); + } + else if (rSelectedId == "pathname") + { + m_pEditFocus->InsertField( SvxFieldItem( SvxExtFileField( + OUString(), SvxFileType::Var, SvxFileFormat::PathFull ), EE_FEATURE_FIELD ) ); + } +} + + +ScRightHeaderEditPage::ScRightHeaderEditPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet ) + : ScHFEditPage( pPage, pController, + rCoreSet, + rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_HEADERRIGHT ), + true ) + {} + +std::unique_ptr<SfxTabPage> ScRightHeaderEditPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet ) +{ + return std::make_unique<ScRightHeaderEditPage>( pPage, pController, *rCoreSet ); +} + + +ScLeftHeaderEditPage::ScLeftHeaderEditPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet ) + : ScHFEditPage( pPage, pController, + rCoreSet, + rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_HEADERLEFT ), + true ) + {} + +std::unique_ptr<SfxTabPage> ScLeftHeaderEditPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet ) +{ + return std::make_unique<ScLeftHeaderEditPage>( pPage, pController, *rCoreSet ); +} + + +ScRightFooterEditPage::ScRightFooterEditPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet ) + : ScHFEditPage( pPage, pController, + rCoreSet, + rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_FOOTERRIGHT ), + false ) + {} + +std::unique_ptr<SfxTabPage> ScRightFooterEditPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet ) +{ + return std::make_unique<ScRightFooterEditPage>( pPage, pController, *rCoreSet ); +} + + +ScLeftFooterEditPage::ScLeftFooterEditPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet ) + : ScHFEditPage( pPage, pController, + rCoreSet, + rCoreSet.GetPool()->GetWhich(SID_SCATTR_PAGE_FOOTERLEFT ), + false ) + {} + +std::unique_ptr<SfxTabPage> ScLeftFooterEditPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet ) +{ + return std::make_unique<ScLeftFooterEditPage>( pPage, pController, *rCoreSet ); +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/pagedlg/tphf.cxx b/sc/source/ui/pagedlg/tphf.cxx new file mode 100644 index 000000000..b4689f511 --- /dev/null +++ b/sc/source/ui/pagedlg/tphf.cxx @@ -0,0 +1,239 @@ +/* -*- 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 . + */ + +#undef SC_DLLIMPLEMENTATION + +#include <scitems.hxx> +#include <sfx2/basedlgs.hxx> +#include <sfx2/sfxdlg.hxx> +#include <svl/style.hxx> +#include <svx/pageitem.hxx> +#include <vcl/svapp.hxx> + +#include <attrib.hxx> +#include <tphf.hxx> +#include <scres.hrc> +#include <scabstdlg.hxx> +#include <globstr.hrc> +#include <scresid.hxx> +#include <tabvwsh.hxx> +#include <viewdata.hxx> +#include <document.hxx> +#include <styledlg.hxx> +#include <scuitphfedit.hxx> +#include <memory> +#include <helpids.h> + + +ScHFPage::ScHFPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet, sal_uInt16 nSetId) + : SvxHFPage(pPage, pController, rSet, nSetId) + , aDataSet(*rSet.GetPool(), svl::Items<ATTR_PAGE, ATTR_PAGE, ATTR_PAGE_HEADERLEFT, ATTR_PAGE_FOOTERRIGHT>{}) + , nPageUsage(SvxPageUsage::All) + , pStyleDlg(nullptr) + , m_xBtnEdit(m_xBuilder->weld_button("buttonEdit")) +{ + SetExchangeSupport(); + + SfxViewShell* pSh = SfxViewShell::Current(); + ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( pSh ); + m_xBtnEdit->show(); + + aDataSet.Put( rSet ); + + if ( pViewSh ) + { + ScViewData& rViewData = pViewSh->GetViewData(); + ScDocument* pDoc = rViewData.GetDocument(); + + aStrPageStyle = pDoc->GetPageStyle( rViewData.GetTabNo() ); + } + + m_xBtnEdit->connect_clicked(LINK(this, ScHFPage, BtnHdl)); + m_xTurnOnBox->connect_toggled(LINK(this, ScHFPage, TurnOnHdl)); + + if ( nId == SID_ATTR_PAGE_HEADERSET ) + m_xBtnEdit->set_help_id(HID_SC_HEADER_EDIT); + else + m_xBtnEdit->set_help_id(HID_SC_FOOTER_EDIT); +} + +ScHFPage::~ScHFPage() +{ + pStyleDlg = nullptr; +} + +void ScHFPage::Reset( const SfxItemSet* rSet ) +{ + SvxHFPage::Reset( rSet ); + TurnOnHdl(*m_xTurnOnBox); +} + +bool ScHFPage::FillItemSet( SfxItemSet* rOutSet ) +{ + bool bResult = SvxHFPage::FillItemSet( rOutSet ); + + if ( nId == SID_ATTR_PAGE_HEADERSET ) + { + rOutSet->Put( aDataSet.Get( ATTR_PAGE_HEADERLEFT ) ); + rOutSet->Put( aDataSet.Get( ATTR_PAGE_HEADERRIGHT ) ); + } + else + { + rOutSet->Put( aDataSet.Get( ATTR_PAGE_FOOTERLEFT ) ); + rOutSet->Put( aDataSet.Get( ATTR_PAGE_FOOTERRIGHT ) ); + } + + return bResult; +} + +void ScHFPage::ActivatePage( const SfxItemSet& rSet ) +{ + sal_uInt16 nPageWhich = GetWhich( SID_ATTR_PAGE ); + const SvxPageItem& rPageItem = static_cast<const SvxPageItem&>( + rSet.Get(nPageWhich)); + + nPageUsage = rPageItem.GetPageUsage(); + + if ( pStyleDlg ) + aStrPageStyle = pStyleDlg->GetStyleSheet().GetName(); + + aDataSet.Put( rSet.Get(ATTR_PAGE) ); + + SvxHFPage::ActivatePage( rSet ); +} + +DeactivateRC ScHFPage::DeactivatePage( SfxItemSet* pSetP ) +{ + if ( DeactivateRC::LeavePage == SvxHFPage::DeactivatePage( pSetP ) ) + if ( pSetP ) + FillItemSet( pSetP ); + + return DeactivateRC::LeavePage; +} + +// Handler: + +IMPL_LINK_NOARG(ScHFPage, TurnOnHdl, weld::ToggleButton&, void) +{ + SvxHFPage::TurnOnHdl(*m_xTurnOnBox); + + if (m_xTurnOnBox->get_active()) + m_xBtnEdit->set_sensitive(true); + else + m_xBtnEdit->set_sensitive(false); +} + +IMPL_LINK_NOARG(ScHFPage, BtnHdl, weld::Button&, void) +{ + SfxViewShell* pViewSh = SfxViewShell::Current(); + + if ( !pViewSh ) + { + OSL_FAIL( "Current ViewShell not found." ); + return; + } + + if (m_xCntSharedBox->get_sensitive() && !m_xCntSharedBox->get_active()) + { + sal_uInt16 nResId = ( nId == SID_ATTR_PAGE_HEADERSET ) + ? RID_SCDLG_HFED_HEADER + : RID_SCDLG_HFED_FOOTER; + + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + + VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScHFEditDlg( + GetFrameWeld(), aDataSet, aStrPageStyle, nResId)); + pDlg->StartExecuteAsync([this, pDlg](sal_Int32 nResult){ + if ( nResult == RET_OK ) + { + aDataSet.Put( *pDlg->GetOutputItemSet() ); + } + }); + } + else + { + OUString aText; + SfxSingleTabDialogController aDlg(GetFrameWeld(), &aDataSet); + bool bRightPage = m_xCntSharedBox->get_active() || (SvxPageUsage::Left != nPageUsage); + + if ( nId == SID_ATTR_PAGE_HEADERSET ) + { + aText = ScResId( STR_PAGEHEADER ); + if ( bRightPage ) + aDlg.SetTabPage(ScRightHeaderEditPage::Create(aDlg.get_content_area(), &aDlg, &aDataSet)); + else + aDlg.SetTabPage(ScLeftHeaderEditPage::Create(aDlg.get_content_area(), &aDlg, &aDataSet)); + } + else + { + aText = ScResId( STR_PAGEFOOTER ); + if ( bRightPage ) + aDlg.SetTabPage(ScRightFooterEditPage::Create(aDlg.get_content_area(), &aDlg, &aDataSet)); + else + aDlg.SetTabPage(ScLeftFooterEditPage::Create(aDlg.get_content_area(), &aDlg, &aDataSet)); + } + + SvxNumType eNumType = aDataSet.Get(ATTR_PAGE).GetNumType(); + static_cast<ScHFEditPage*>(aDlg.GetTabPage())->SetNumType(eNumType); + + aText += " (" + ScResId( STR_PAGESTYLE ) + + ": " + aStrPageStyle + ")"; + + aDlg.set_title(aText); + + if (aDlg.run() == RET_OK) + { + aDataSet.Put(*aDlg.GetOutputItemSet()); + } + } +} + + +ScHeaderPage::ScHeaderPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) + : ScHFPage(pPage, pController, rSet, SID_ATTR_PAGE_HEADERSET) +{ +} + +std::unique_ptr<SfxTabPage> ScHeaderPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet) +{ + return std::make_unique<ScHeaderPage>(pPage, pController, *rCoreSet); +} + +const sal_uInt16* ScHeaderPage::GetRanges() +{ + return SvxHeaderPage::GetRanges(); +} + + +ScFooterPage::ScFooterPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet) + : ScHFPage( pPage, pController, rSet, SID_ATTR_PAGE_FOOTERSET ) +{ +} + +std::unique_ptr<SfxTabPage> ScFooterPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet) +{ + return std::make_unique<ScFooterPage>(pPage, pController, *rCoreSet); +} + +const sal_uInt16* ScFooterPage::GetRanges() +{ + return SvxHeaderPage::GetRanges(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/pagedlg/tphfedit.cxx b/sc/source/ui/pagedlg/tphfedit.cxx new file mode 100644 index 000000000..db2a91e5e --- /dev/null +++ b/sc/source/ui/pagedlg/tphfedit.cxx @@ -0,0 +1,274 @@ +/* -*- 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 <scitems.hxx> +#include <editeng/eeitem.hxx> + +#include <editeng/editobj.hxx> +#include <editeng/editstat.hxx> +#include <editeng/editview.hxx> +#include <editeng/adjustitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/sfxdlg.hxx> +#include <vcl/cursor.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> + +#include <tphfedit.hxx> +#include <editutil.hxx> +#include <global.hxx> +#include <patattr.hxx> +#include <scresid.hxx> +#include <globstr.hrc> +#include <strings.hrc> +#include <tabvwsh.hxx> +#include <prevwsh.hxx> +#include <AccessibleEditObject.hxx> + +#include <scabstdlg.hxx> +#include <memory> + + +static void lcl_GetFieldData( ScHeaderFieldData& rData ) +{ + SfxViewShell* pShell = SfxViewShell::Current(); + if (pShell) + { + if (dynamic_cast<const ScTabViewShell*>( pShell) != nullptr) + static_cast<ScTabViewShell*>(pShell)->FillFieldData(rData); + else if (dynamic_cast<const ScPreviewShell*>( pShell) != nullptr) + static_cast<ScPreviewShell*>(pShell)->FillFieldData(rData); + } +} + + +ScEditWindow::ScEditWindow(ScEditWindowLocation eLoc, weld::Window* pDialog) + : eLocation(eLoc) + , mbRTL(ScGlobal::IsSystemRTL()) + , mpDialog(pDialog) + , pAcc(nullptr) +{ +} + +void ScEditWindow::makeEditEngine() +{ + m_xEditEngine.reset(new ScHeaderEditEngine(EditEngine::CreatePool())); +} + +ScHeaderEditEngine* ScEditWindow::GetEditEngine() const +{ + return static_cast<ScHeaderEditEngine*>(m_xEditEngine.get()); +} + +void ScEditWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea) +{ + OutputDevice& rDevice = pDrawingArea->get_ref_device(); + Size aSize = rDevice.LogicToPixel(Size(80, 120), MapMode(MapUnit::MapAppFont)); + pDrawingArea->set_size_request(aSize.Width(), aSize.Height()); + + WeldEditView::SetDrawingArea(pDrawingArea); + + ScHeaderFieldData aData; + lcl_GetFieldData(aData); + // fields + GetEditEngine()->SetData(aData); + if (mbRTL) + m_xEditEngine->SetDefaultHorizontalTextDirection(EEHorizontalTextDirection::R2L); + + if (pAcc) + { + OUString sName; + switch (eLocation) + { + case Left: + sName = ScResId(STR_ACC_LEFTAREA_NAME); + break; + case Center: + sName = ScResId(STR_ACC_CENTERAREA_NAME); + break; + case Right: + sName = ScResId(STR_ACC_RIGHTAREA_NAME); + break; + } + + pAcc->InitAcc(nullptr, m_xEditView.get(), nullptr, + sName, pDrawingArea->get_tooltip_text()); + } +} + +ScEditWindow::~ScEditWindow() +{ + // delete Accessible object before deleting EditEngine and EditView + if (pAcc) + { + css::uno::Reference< css::accessibility::XAccessible > xTemp = xAcc; + if (xTemp.is()) + pAcc->dispose(); + } +} + +void ScEditWindow::SetNumType(SvxNumType eNumType) +{ + ScHeaderEditEngine* pEditEngine = GetEditEngine(); + pEditEngine->SetNumType(eNumType); + pEditEngine->UpdateFields(); +} + +std::unique_ptr<EditTextObject> ScEditWindow::CreateTextObject() +{ + // reset paragraph attributes + // (GetAttribs at creation of format dialog always returns the set items) + + const SfxItemSet& rEmpty = m_xEditEngine->GetEmptyItemSet(); + sal_Int32 nParCnt = m_xEditEngine->GetParagraphCount(); + for (sal_Int32 i=0; i<nParCnt; i++) + m_xEditEngine->SetParaAttribs( i, rEmpty ); + + return m_xEditEngine->CreateTextObject(); +} + +void ScEditWindow::SetFont( const ScPatternAttr& rPattern ) +{ + auto pSet = std::make_unique<SfxItemSet>( m_xEditEngine->GetEmptyItemSet() ); + rPattern.FillEditItemSet( pSet.get() ); + // FillEditItemSet adjusts font height to 1/100th mm, + // but for header/footer twips is needed, as in the PatternAttr: + pSet->Put( rPattern.GetItem(ATTR_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT) ); + pSet->Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CJK) ); + pSet->Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT).CloneSetWhich(EE_CHAR_FONTHEIGHT_CTL) ); + if (mbRTL) + pSet->Put( SvxAdjustItem( SvxAdjust::Right, EE_PARA_JUST ) ); + GetEditEngine()->SetDefaults( std::move(pSet) ); +} + +void ScEditWindow::SetText( const EditTextObject& rTextObject ) +{ + GetEditEngine()->SetTextCurrentDefaults(rTextObject); +} + +void ScEditWindow::InsertField( const SvxFieldItem& rFld ) +{ + m_xEditView->InsertField( rFld ); +} + +void ScEditWindow::SetCharAttributes() +{ + SfxObjectShell* pDocSh = SfxObjectShell::Current(); + + SfxViewShell* pViewSh = SfxViewShell::Current(); + + ScTabViewShell* pTabViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() ); + + OSL_ENSURE( pDocSh, "Current DocShell not found" ); + OSL_ENSURE( pViewSh, "Current ViewShell not found" ); + + if ( pDocSh && pViewSh ) + { + if(pTabViewSh!=nullptr) pTabViewSh->SetInFormatDialog(true); + + SfxItemSet aSet( m_xEditView->GetAttribs() ); + + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + + ScopedVclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScCharDlg( + mpDialog, &aSet, pDocSh, false)); + pDlg->SetText( ScResId( STR_TEXTATTRS ) ); + if ( pDlg->Execute() == RET_OK ) + { + aSet.ClearItem(); + aSet.Put( *pDlg->GetOutputItemSet() ); + m_xEditView->SetAttribs( aSet ); + } + + if(pTabViewSh!=nullptr) pTabViewSh->SetInFormatDialog(false); + } +} + +bool ScEditWindow::KeyInput( const KeyEvent& rKEvt ) +{ + sal_uInt16 nKey = rKEvt.GetKeyCode().GetModifier() + + rKEvt.GetKeyCode().GetCode(); + + if ( nKey == KEY_TAB || nKey == KEY_TAB + KEY_SHIFT ) + { + return false; + } + else if ( !m_xEditView->PostKeyEvent( rKEvt ) ) + { + return false; + } + else if ( !rKEvt.GetKeyCode().IsMod1() && !rKEvt.GetKeyCode().IsShift() && + rKEvt.GetKeyCode().IsMod2() && rKEvt.GetKeyCode().GetCode() == KEY_DOWN ) + { + aObjectSelectLink.Call(*this); + return true; + } + return true; +} + +void ScEditWindow::GetFocus() +{ + assert(m_GetFocusLink); + m_GetFocusLink(*this); + + css::uno::Reference< css::accessibility::XAccessible > xTemp = xAcc; + if (xTemp.is() && pAcc) + { + pAcc->GotFocus(); + } + else + pAcc = nullptr; + + WeldEditView::GetFocus(); +} + +void ScEditWindow::LoseFocus() +{ + css::uno::Reference< css::accessibility::XAccessible > xTemp = xAcc; + if (xTemp.is() && pAcc) + { + pAcc->LostFocus(); + } + else + pAcc = nullptr; + WeldEditView::LoseFocus(); +} + +bool ScEditWindow::MouseButtonDown(const MouseEvent& rMEvt) +{ + bool bHadFocus = HasFocus(); + bool bRet = WeldEditView::MouseButtonDown(rMEvt); + if (!bHadFocus) + { + assert(HasFocus()); + GetFocus(); + } + return bRet; +} + +css::uno::Reference< css::accessibility::XAccessible > ScEditWindow::CreateAccessible() +{ + pAcc = new ScAccessibleEditControlObject(this); + css::uno::Reference< css::accessibility::XAccessible > xAccessible = pAcc; + xAcc = xAccessible; + return pAcc; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/pagedlg/tptable.cxx b/sc/source/ui/pagedlg/tptable.cxx new file mode 100644 index 000000000..692fc245f --- /dev/null +++ b/sc/source/ui/pagedlg/tptable.cxx @@ -0,0 +1,535 @@ +/* -*- 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 . + */ + +#undef SC_DLLIMPLEMENTATION + +#include <scitems.hxx> + +#include <vcl/event.hxx> +#include <vcl/settings.hxx> +#include <osl/diagnose.h> + +#include <tptable.hxx> +#include <global.hxx> +#include <attrib.hxx> +#include <bitmaps.hlst> + +// Static Data + +const sal_uInt16 ScTablePage::pPageTableRanges[] = +{ + ATTR_PAGE_NOTES, ATTR_PAGE_FIRSTPAGENO, + 0 +}; + +static bool lcl_PutVObjModeItem(sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ToggleButton& rBtn); + +static bool lcl_PutScaleItem( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ComboBox& rListBox, + sal_uInt16 nLBEntry, + const weld::MetricSpinButton& rEd, + sal_uInt16 nValue ); + +static bool lcl_PutScaleItem2( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ComboBox& rListBox, + sal_uInt16 nLBEntry, + const weld::SpinButton& rEd1, + sal_uInt16 nOrigScalePageWidth, + const weld::SpinButton& rEd2, + sal_uInt16 nOrigScalePageHeight ); + +static bool lcl_PutScaleItem3( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ComboBox& rListBox, + sal_uInt16 nLBEntry, + const weld::SpinButton& rEd, + sal_uInt16 nValue ); + +static bool lcl_PutBoolItem( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + bool bIsChecked, + bool bSavedValue ); + +#define PAGENO_HDL LINK(this,ScTablePage,PageNoHdl) +#define PAGEDIR_HDL LINK(this,ScTablePage,PageDirHdl) + +namespace { + +bool WAS_DEFAULT(sal_uInt16 w, SfxItemSet const & s) +{ return SfxItemState::DEFAULT==s.GetItemState(w); } + +} + +#define GET_BOOL(sid,set) static_cast<const SfxBoolItem&>((set).Get(GetWhich((sid)))).GetValue() +#define GET_USHORT(sid,set) static_cast<const SfxUInt16Item&>((set).Get(GetWhich((sid)))).GetValue() +#define GET_SHOW(sid,set) ( static_cast<const ScViewObjectModeItem&>((set).Get(GetWhich((sid)))).GetValue() \ + == VOBJ_MODE_SHOW ) +// List box entries "Scaling mode" +#define SC_TPTABLE_SCALE_PERCENT 0 +#define SC_TPTABLE_SCALE_TO 1 +#define SC_TPTABLE_SCALE_TO_PAGES 2 + +ScTablePage::ScTablePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs) + : SfxTabPage(pPage, pController, "modules/scalc/ui/sheetprintpage.ui", "SheetPrintPage", &rCoreAttrs) + , m_nOrigScalePageWidth(0) + , m_nOrigScalePageHeight(0) + , m_xBtnTopDown(m_xBuilder->weld_radio_button("radioBTN_TOPDOWN")) + , m_xBtnLeftRight(m_xBuilder->weld_radio_button("radioBTN_LEFTRIGHT")) + , m_xBmpPageDir(m_xBuilder->weld_image("imageBMP_PAGEDIR")) + , m_xBtnPageNo(m_xBuilder->weld_check_button("checkBTN_PAGENO")) + , m_xEdPageNo(m_xBuilder->weld_spin_button("spinED_PAGENO")) + , m_xBtnHeaders(m_xBuilder->weld_check_button("checkBTN_HEADER")) + , m_xBtnGrid(m_xBuilder->weld_check_button("checkBTN_GRID")) + , m_xBtnNotes(m_xBuilder->weld_check_button("checkBTN_NOTES")) + , m_xBtnObjects(m_xBuilder->weld_check_button("checkBTN_OBJECTS")) + , m_xBtnCharts(m_xBuilder->weld_check_button("checkBTN_CHARTS")) + , m_xBtnDrawings(m_xBuilder->weld_check_button("checkBTN_DRAWINGS")) + , m_xBtnFormulas(m_xBuilder->weld_check_button("checkBTN_FORMULAS")) + , m_xBtnNullVals(m_xBuilder->weld_check_button("checkBTN_NULLVALS")) + , m_xLbScaleMode(m_xBuilder->weld_combo_box("comboLB_SCALEMODE")) + , m_xBxScaleAll(m_xBuilder->weld_widget("boxSCALEALL")) + , m_xEdScaleAll(m_xBuilder->weld_metric_spin_button("spinED_SCALEALL", FieldUnit::PERCENT)) + , m_xGrHeightWidth(m_xBuilder->weld_widget("gridWH")) + , m_xEdScalePageWidth(m_xBuilder->weld_spin_button("spinED_SCALEPAGEWIDTH")) + , m_xCbScalePageWidth(m_xBuilder->weld_check_button("labelWP")) + , m_xEdScalePageHeight(m_xBuilder->weld_spin_button("spinED_SCALEPAGEHEIGHT")) + , m_xCbScalePageHeight(m_xBuilder->weld_check_button("labelHP")) + , m_xBxScalePageNum(m_xBuilder->weld_widget("boxNP")) + , m_xEdScalePageNum(m_xBuilder->weld_spin_button("spinED_SCALEPAGENUM")) +{ + SetExchangeSupport(); + + m_xBtnPageNo->connect_toggled(PAGENO_HDL); + m_xBtnTopDown->connect_toggled(PAGEDIR_HDL); + m_xBtnLeftRight->connect_toggled(PAGEDIR_HDL); + m_xLbScaleMode->connect_changed(LINK(this,ScTablePage,ScaleHdl)); + m_xCbScalePageWidth->connect_toggled(LINK(this, ScTablePage, ToggleHdl)); + m_xCbScalePageHeight->connect_toggled(LINK(this, ScTablePage, ToggleHdl)); +} + +void ScTablePage::ShowImage() +{ + OUString aImg(m_xBtnLeftRight->get_active() ? OUString(BMP_LEFTRIGHT) : OUString(BMP_TOPDOWN)); + m_xBmpPageDir->set_from_icon_name(aImg); +} + +ScTablePage::~ScTablePage() +{ +} + +std::unique_ptr<SfxTabPage> ScTablePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet) +{ + return std::make_unique<ScTablePage>(pPage, pController, *rCoreSet); +} + +void ScTablePage::Reset( const SfxItemSet* rCoreSet ) +{ + bool bTopDown = GET_BOOL( SID_SCATTR_PAGE_TOPDOWN, *rCoreSet ); + sal_uInt16 nWhich = 0; + + // sal_Bool flags + m_xBtnNotes->set_active( GET_BOOL(SID_SCATTR_PAGE_NOTES,*rCoreSet) ); + m_xBtnGrid->set_active( GET_BOOL(SID_SCATTR_PAGE_GRID,*rCoreSet) ); + m_xBtnHeaders->set_active( GET_BOOL(SID_SCATTR_PAGE_HEADERS,*rCoreSet) ); + m_xBtnFormulas->set_active( GET_BOOL(SID_SCATTR_PAGE_FORMULAS,*rCoreSet) ); + m_xBtnNullVals->set_active( GET_BOOL(SID_SCATTR_PAGE_NULLVALS,*rCoreSet) ); + m_xBtnTopDown->set_active( bTopDown ); + m_xBtnLeftRight->set_active( !bTopDown ); + + // first printed page: + sal_uInt16 nPage = GET_USHORT(SID_SCATTR_PAGE_FIRSTPAGENO,*rCoreSet); + m_xBtnPageNo->set_active( nPage != 0 ); + m_xEdPageNo->set_value( (nPage != 0) ? nPage : 1 ); + PageNoHdl(nullptr); + + // object representation: + m_xBtnCharts->set_active( GET_SHOW( SID_SCATTR_PAGE_CHARTS, *rCoreSet ) ); + m_xBtnObjects->set_active( GET_SHOW( SID_SCATTR_PAGE_OBJECTS, *rCoreSet ) ); + m_xBtnDrawings->set_active( GET_SHOW( SID_SCATTR_PAGE_DRAWINGS, *rCoreSet ) ); + + // scaling: + nWhich = GetWhich(SID_SCATTR_PAGE_SCALE); + if ( rCoreSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT ) + { + sal_uInt16 nScale = static_cast<const SfxUInt16Item&>(rCoreSet->Get(nWhich)).GetValue(); + if( nScale > 0 ) + m_xLbScaleMode->set_active(SC_TPTABLE_SCALE_PERCENT); + m_xEdScaleAll->set_value((nScale > 0) ? nScale : 100, FieldUnit::PERCENT); + } + + nWhich = GetWhich(SID_SCATTR_PAGE_SCALETO); + if ( rCoreSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT ) + { + const ScPageScaleToItem& rItem = static_cast< const ScPageScaleToItem& >( rCoreSet->Get( nWhich ) ); + sal_uInt16 nWidth = rItem.GetWidth(); + sal_uInt16 nHeight = rItem.GetHeight(); + + /* width==0 and height==0 is invalid state, used as "not selected". + Dialog shows width=height=1 then. */ + if (nWidth || nHeight) + m_xLbScaleMode->set_active(SC_TPTABLE_SCALE_TO); + else + nWidth = nHeight = 1; + + if (nWidth) + m_xEdScalePageWidth->set_value(nWidth); + else + m_xEdScalePageWidth->set_text(OUString()); + + m_xEdScalePageWidth->set_sensitive(nWidth != 0); + m_xCbScalePageWidth->set_active(nWidth != 0); + + if(nHeight) + m_xEdScalePageHeight->set_value(nHeight); + else + m_xEdScalePageHeight->set_text(OUString()); + + m_xEdScalePageHeight->set_sensitive(nHeight != 0); + m_xCbScalePageHeight->set_active(nHeight != 0); + } + + nWhich = GetWhich(SID_SCATTR_PAGE_SCALETOPAGES); + if ( rCoreSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT ) + { + sal_uInt16 nPages = static_cast<const SfxUInt16Item&>(rCoreSet->Get(nWhich)).GetValue(); + if( nPages > 0 ) + m_xLbScaleMode->set_active(SC_TPTABLE_SCALE_TO_PAGES); + m_xEdScalePageNum->set_value( (nPages > 0) ? nPages : 1 ); + } + + if (m_xLbScaleMode->get_active() == -1) + { + // fall back to 100% + OSL_FAIL( "ScTablePage::Reset - missing scaling item" ); + m_xLbScaleMode->set_active(SC_TPTABLE_SCALE_PERCENT); + m_xEdScaleAll->set_value(100, FieldUnit::PERCENT); + } + + PageDirHdl(*m_xBtnTopDown); + ScaleHdl(*m_xLbScaleMode); + + // remember for FillItemSet + m_xBtnFormulas->save_state(); + m_xBtnNullVals->save_state(); + m_xBtnNotes->save_state(); + m_xBtnGrid->save_state(); + m_xBtnHeaders->save_state(); + m_xBtnTopDown->save_state(); + m_xBtnLeftRight->save_state(); + m_xLbScaleMode->save_value(); + m_xBtnCharts->save_state(); + m_xBtnObjects->save_state(); + m_xBtnDrawings->save_state(); + m_xBtnPageNo->save_state(); + m_xEdPageNo->save_value(); + m_xEdScaleAll->save_value(); + m_nOrigScalePageWidth = m_xEdScalePageWidth->get_sensitive() ? m_xEdScalePageWidth->get_value() : 0; + m_nOrigScalePageHeight = m_xEdScalePageHeight->get_sensitive() ? m_xEdScalePageHeight->get_value() : 0; + m_xEdScalePageNum->save_value(); +} + +bool ScTablePage::FillItemSet( SfxItemSet* rCoreSet ) +{ + const SfxItemSet& rOldSet = GetItemSet(); + sal_uInt16 nWhichPageNo = GetWhich(SID_SCATTR_PAGE_FIRSTPAGENO); + bool bDataChanged = false; + + // sal_Bool flags + bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_NOTES), + *rCoreSet, rOldSet, + m_xBtnNotes->get_active(), + m_xBtnNotes->get_saved_state() != TRISTATE_FALSE ); + + bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_GRID), + *rCoreSet, rOldSet, + m_xBtnGrid->get_active(), + m_xBtnGrid->get_saved_state() != TRISTATE_FALSE ); + + bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_HEADERS), + *rCoreSet, rOldSet, + m_xBtnHeaders->get_active(), + m_xBtnHeaders->get_saved_state() != TRISTATE_FALSE ); + + bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_TOPDOWN), + *rCoreSet, rOldSet, + m_xBtnTopDown->get_active(), + m_xBtnTopDown->get_saved_state() != TRISTATE_FALSE ); + + bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_FORMULAS), + *rCoreSet, rOldSet, + m_xBtnFormulas->get_active(), + m_xBtnFormulas->get_saved_state() != TRISTATE_FALSE ); + + bDataChanged |= lcl_PutBoolItem( GetWhich(SID_SCATTR_PAGE_NULLVALS), + *rCoreSet, rOldSet, + m_xBtnNullVals->get_active(), + m_xBtnNullVals->get_saved_state() != TRISTATE_FALSE ); + + // first printed page: + bool bUseValue = m_xBtnPageNo->get_active(); + + if ( WAS_DEFAULT(nWhichPageNo,rOldSet) + && ( (!bUseValue && 0 == m_xBtnPageNo->get_saved_state()) + || ( bUseValue && 1 == m_xBtnPageNo->get_saved_state() + && ! m_xEdPageNo->get_value_changed_from_saved() ) ) ) + { + rCoreSet->ClearItem( nWhichPageNo ); + } + else + { + sal_uInt16 nPage = static_cast<sal_uInt16>( m_xBtnPageNo->get_active() + ? m_xEdPageNo->get_value() + : 0 ); + + rCoreSet->Put( SfxUInt16Item( nWhichPageNo, nPage ) ); + bDataChanged = true; + } + + // object representation: + bDataChanged |= lcl_PutVObjModeItem( GetWhich(SID_SCATTR_PAGE_CHARTS), + *rCoreSet, rOldSet, *m_xBtnCharts ); + + bDataChanged |= lcl_PutVObjModeItem( GetWhich(SID_SCATTR_PAGE_OBJECTS), + *rCoreSet, rOldSet, *m_xBtnObjects ); + + bDataChanged |= lcl_PutVObjModeItem( GetWhich(SID_SCATTR_PAGE_DRAWINGS), + *rCoreSet, rOldSet, *m_xBtnDrawings ); + + // scaling: + if( !m_xEdScalePageWidth->get_sensitive() && !m_xEdScalePageHeight->get_sensitive() ) + { + m_xLbScaleMode->set_active(SC_TPTABLE_SCALE_PERCENT); + m_xEdScaleAll->set_value(100, FieldUnit::PERCENT); + } + + bDataChanged |= lcl_PutScaleItem( GetWhich(SID_SCATTR_PAGE_SCALE), + *rCoreSet, rOldSet, + *m_xLbScaleMode, SC_TPTABLE_SCALE_PERCENT, + *m_xEdScaleAll, static_cast<sal_uInt16>(m_xEdScaleAll->get_value(FieldUnit::PERCENT)) ); + + bDataChanged |= lcl_PutScaleItem2( GetWhich(SID_SCATTR_PAGE_SCALETO), + *rCoreSet, rOldSet, + *m_xLbScaleMode, SC_TPTABLE_SCALE_TO, + *m_xEdScalePageWidth, m_nOrigScalePageWidth, + *m_xEdScalePageHeight, m_nOrigScalePageHeight ); + + bDataChanged |= lcl_PutScaleItem3( GetWhich(SID_SCATTR_PAGE_SCALETOPAGES), + *rCoreSet, rOldSet, + *m_xLbScaleMode, SC_TPTABLE_SCALE_TO_PAGES, + *m_xEdScalePageNum, static_cast<sal_uInt16>(m_xEdScalePageNum->get_value()) ); + + return bDataChanged; +} + +DeactivateRC ScTablePage::DeactivatePage( SfxItemSet* pSetP ) +{ + if ( pSetP ) + FillItemSet( pSetP ); + + return DeactivateRC::LeavePage; +} + +// Handler: + +IMPL_LINK_NOARG(ScTablePage, PageDirHdl, weld::ToggleButton&, void) +{ + ShowImage(); +} + +IMPL_LINK(ScTablePage, PageNoHdl, weld::ToggleButton&, rBtn, void) +{ + PageNoHdl(&rBtn); +} + +void ScTablePage::PageNoHdl(const weld::ToggleButton* pBtn) +{ + if (m_xBtnPageNo->get_active()) + { + m_xEdPageNo->set_sensitive(true); + if (pBtn) + m_xEdPageNo->grab_focus(); + } + else + m_xEdPageNo->set_sensitive(false); +} + +IMPL_LINK_NOARG(ScTablePage, ScaleHdl, weld::ComboBox&, void) +{ + // controls for Box "Reduce/enlarge" + m_xBxScaleAll->set_visible(m_xLbScaleMode->get_active() == SC_TPTABLE_SCALE_PERCENT); + + // controls for Grid "Scale to width/height" + m_xGrHeightWidth->set_visible(m_xLbScaleMode->get_active() == SC_TPTABLE_SCALE_TO); + + // controls for Box "Scale to pages" + m_xBxScalePageNum->set_visible(m_xLbScaleMode->get_active() == SC_TPTABLE_SCALE_TO_PAGES); +} + +IMPL_LINK(ScTablePage, ToggleHdl, weld::ToggleButton&, rBox, void) +{ + if (&rBox == m_xCbScalePageWidth.get()) + { + if (!rBox.get_active()) + { + m_xEdScalePageWidth->set_text(OUString()); + m_xEdScalePageWidth->set_sensitive(false); + } + else + { + m_xEdScalePageWidth->set_value(1); + m_xEdScalePageWidth->set_sensitive(true); + } + } + else + { + if (!rBox.get_active()) + { + m_xEdScalePageHeight->set_text(OUString()); + m_xEdScalePageHeight->set_sensitive(false); + } + else + { + m_xEdScalePageHeight->set_value(1); + m_xEdScalePageHeight->set_sensitive(true); + } + } +} + +// Helper functions for FillItemSet: + +static bool lcl_PutBoolItem( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + bool bIsChecked, + bool bSavedValue ) +{ + bool bDataChanged = ( bSavedValue == bIsChecked + && WAS_DEFAULT(nWhich,rOldSet) ); + + if ( bDataChanged ) + rCoreSet.ClearItem(nWhich); + else + rCoreSet.Put( SfxBoolItem( nWhich, bIsChecked ) ); + + return bDataChanged; +} + +static bool lcl_PutVObjModeItem( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ToggleButton& rBtn ) +{ + bool bIsChecked = rBtn.get_active(); + bool bDataChanged = rBtn.get_saved_state() == (bIsChecked ? 1 : 0) + && WAS_DEFAULT(nWhich,rOldSet); + + if ( bDataChanged ) + rCoreSet.ClearItem( nWhich ); + + else + rCoreSet.Put( ScViewObjectModeItem( nWhich, bIsChecked + ? VOBJ_MODE_SHOW + : VOBJ_MODE_HIDE ) ); + return bDataChanged; +} + +static bool lcl_PutScaleItem( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ComboBox& rListBox, + sal_uInt16 nLBEntry, + const weld::MetricSpinButton& rEd, + sal_uInt16 nValue ) +{ + bool bIsSel = (rListBox.get_active() == nLBEntry); + bool bDataChanged = (rListBox.get_value_changed_from_saved()) || + rEd.get_value_changed_from_saved() || + !WAS_DEFAULT( nWhich, rOldSet ); + + if( bDataChanged ) + rCoreSet.Put( SfxUInt16Item( nWhich, bIsSel ? nValue : 0 ) ); + else + rCoreSet.ClearItem( nWhich ); + + return bDataChanged; +} + +static bool lcl_PutScaleItem2( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ComboBox& rListBox, + sal_uInt16 nLBEntry, + const weld::SpinButton& rEd1, + sal_uInt16 nOrigScalePageWidth, + const weld::SpinButton& rEd2, + sal_uInt16 nOrigScalePageHeight ) +{ + sal_uInt16 nValue1 = rEd1.get_sensitive() ? rEd1.get_value() : 0; + sal_uInt16 nValue2 = rEd2.get_sensitive() ? rEd2.get_value() : 0; + bool bIsSel = (rListBox.get_active() == nLBEntry); + bool bDataChanged = (rListBox.get_value_changed_from_saved()) || + nValue1 != nOrigScalePageWidth || + nValue1 != nOrigScalePageHeight || + !WAS_DEFAULT( nWhich, rOldSet ); + + if( bDataChanged ) + { + ScPageScaleToItem aItem; + if( bIsSel ) + aItem.Set( nValue1, nValue2 ); + rCoreSet.Put( aItem ); + } + else + rCoreSet.ClearItem( nWhich ); + + return bDataChanged; +} + +static bool lcl_PutScaleItem3( sal_uInt16 nWhich, + SfxItemSet& rCoreSet, + const SfxItemSet& rOldSet, + const weld::ComboBox& rListBox, + sal_uInt16 nLBEntry, + const weld::SpinButton& rEd, + sal_uInt16 nValue ) +{ + bool bIsSel = (rListBox.get_active() == nLBEntry); + bool bDataChanged = (rListBox.get_value_changed_from_saved()) || + rEd.get_value_changed_from_saved() || + !WAS_DEFAULT( nWhich, rOldSet ); + + if( bDataChanged ) + rCoreSet.Put( SfxUInt16Item( nWhich, bIsSel ? nValue : 0 ) ); + else + rCoreSet.ClearItem( nWhich ); + + return bDataChanged; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |