/* -*- 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 .
*/
SwFormatContentControl::SwFormatContentControl( const std::shared_ptr<SwContentControl>& pContentControl, sal_uInt16 nWhich)
: SfxPoolItem(nWhich)
, m_pContentControl(pContentControl)
, m_pTextAttr(nullptr)
{
setNonShareable(); if (!pContentControl)
{
SAL_WARN("sw.core", "SwFormatContentControl ctor: no pContentControl?");
} // Not calling m_pContentControl->SetFormatContentControl(this) here; only from SetTextAttr.
}
SwFormatContentControl::~SwFormatContentControl()
{ if (m_pContentControl // SwFormatContentControl is not shareable, so ptr compare is OK
&& areSfxPoolItemPtrsEqual(m_pContentControl->GetFormatContentControl(), this))
{
NotifyChangeTextNode(nullptr);
m_pContentControl->SetFormatContentControl(nullptr);
}
}
SwFormatContentControl* SwFormatContentControl::Clone(SfxItemPool* /*pPool*/) const
{ // If this is indeed a copy, then DoCopy will be called later. if (m_pContentControl)
{ returnnew SwFormatContentControl(m_pContentControl, Which());
} else
{ returnnew SwFormatContentControl(Which());
}
}
void SwFormatContentControl::SetTextAttr(SwTextContentControl* pTextAttr)
{ if (m_pTextAttr && pTextAttr)
{
SAL_WARN("sw.core", "SwFormatContentControl::SetTextAttr: already has a text attribute");
} if (!m_pTextAttr && !pTextAttr)
{
SAL_WARN("sw.core", "SwFormatContentControl::SetTextAttr: no attribute to remove");
}
m_pTextAttr = pTextAttr; if (!m_pContentControl)
{
SAL_WARN("sw.core", "inserted SwFormatContentControl has no SwContentControl");
} // The SwContentControl should be able to find the current text attribute. if (m_pContentControl)
{ if (pTextAttr)
{
m_pContentControl->SetFormatContentControl(this);
} // SwFormatContentControl is not shareable, so ptr compare is OK elseif (areSfxPoolItemPtrsEqual(m_pContentControl->GetFormatContentControl(), this))
{ // The text attribute is gone, so de-register from text node.
NotifyChangeTextNode(nullptr);
m_pContentControl->SetFormatContentControl(nullptr);
}
}
}
void SwFormatContentControl::NotifyChangeTextNode(SwTextNode* pTextNode)
{ // Not deleting m_pTextAttr here, SwNodes::ChgNode() doesn't do that, either. if (!m_pContentControl)
{
SAL_WARN("sw.core", "SwFormatContentControl::NotifyChangeTextNode: no content control?");
} if (m_pContentControl // SwFormatContentControl is not shareable, so ptr compare is OK
&& areSfxPoolItemPtrsEqual(m_pContentControl->GetFormatContentControl(), this))
{ // Not calling Modify, that would call SwXContentControl::SwClientNotify.
m_pContentControl->NotifyChangeTextNode(pTextNode);
}
}
SwTextNode* SwFormatContentControl::GetTextNode() const
{ if (!m_pContentControl)
{ return nullptr;
}
return m_pContentControl->GetTextNode();
}
// This SwFormatContentControl has been cloned and points at the same SwContentControl as the // source: this function copies the SwContentControl. void SwFormatContentControl::DoCopy(SwTextNode& rTargetTextNode)
{ if (!m_pContentControl)
{
SAL_WARN("sw.core", "SwFormatContentControl::DoCopy: called for SwFormatContentControl " "with no SwContentControl."); return;
}
void SwContentControl::NotifyChangeTextNode(SwTextNode* pTextNode)
{
m_pTextNode = pTextNode; if (m_pTextNode && (GetRegisteredIn() != m_pTextNode))
{
m_pTextNode->Add(*this);
} elseif (!m_pTextNode)
{
EndListeningAll();
} if (!pTextNode)
{ // If the text node is gone, then invalidate clients (e.g. UNO object).
GetNotifier().Broadcast(SfxHint(SfxHintId::Deinitializing));
}
}
const OUString aText = GetTextAttr()->ToString(); for (size_t i = 0; i < nLen; ++i)
{ if (GetTextAttr()[i].ToString() == aText) return i;
}
assert(!GetDropDown() && "DropDowns must always have an associated list item"); return std::nullopt;
}
bool SwContentControl::ShouldOpenPopup(const vcl::KeyCode& rKeyCode)
{ switch (GetType())
{ case SwContentControlType::DROP_DOWN_LIST: case SwContentControlType::COMBO_BOX: case SwContentControlType::DATE:
{ // Alt-down opens the popup. return rKeyCode.IsMod2() && rKeyCode.GetCode() == KEY_DOWN;
} default: break;
}
returnfalse;
}
// NOTE: call SetReadWrite separately to implement true (un)locking. // This is mostly a theoretical function; the lock state is mainly kept for round-tripping purposes. // It is implemented here primarily for pointless VBA control, but with the intention that it // could be made functionally useful as well for checkboxes/dropdowns/pictures. // Returns whether the content (bControl=false) cannot be modified, // or if the control cannot be deleted.
std::optional<bool> SwContentControl::GetLock(bool bControl) const
{
std::optional<bool> oLock; if (m_aLock.isEmpty()) return oLock; elseif (m_aLock.equalsIgnoreAsciiCase("sdtContentLocked"))
oLock = true; elseif (m_aLock.equalsIgnoreAsciiCase("unlocked"))
oLock = false; elseif (m_aLock.equalsIgnoreAsciiCase("sdtLocked"))
oLock = bControl; elseif (m_aLock.equalsIgnoreAsciiCase("contentLocked"))
oLock = !bControl;
assert(oLock.has_value() && "invalid or unknown lock state"); return oLock;
}
OUString SwTextContentControl::ToString() const
{ if (!GetTextNode()) return OUString();
// Don't select the text attribute itself at the start.
sal_Int32 nStart = GetStart() + 1; // Don't select the CH_TXTATR_BREAKWORD itself at the end.
sal_Int32 nEnd = *End() - 1;
// save the cursor // NOTE: needs further testing to see if this is adequate (i.e. in auto-run macros...)
pDocShell->GetWrtShell()->Push();
// visit the control in the text (which makes any necessary visual changes) // NOTE: simply going to a checkbox causes a toggle, unless bOnlyRefresh auto& rFormatContentControl = static_cast<SwFormatContentControl&>(GetAttr());
pDocShell->GetWrtShell()->GotoContentControl(rFormatContentControl, /*bOnlyRefresh=*/true);
SwTextContentControl* SwContentControlManager::Get(size_t nIndex)
{ // Only sort now: the items may not have an associated text node by the time they are inserted // into the container.
std::sort(m_aContentControls.begin(), m_aContentControls.end(),
[](SwTextContentControl*& pLhs, SwTextContentControl*& pRhs) -> bool {
SwNodeOffset nIdxLHS = pLhs->GetTextNode()->GetIndex();
SwNodeOffset nIdxRHS = pRhs->GetTextNode()->GetIndex(); if (nIdxLHS == nIdxRHS)
{ return pLhs->GetStart() < pRhs->GetStart();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.