/* -*- 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 .
*/
void ImportHTML(Outliner& rOutliner, const OUString& rHtml)
{
OString sHtmlContent(rHtml.toUtf8());
SvMemoryStream aHTMLStream(const_cast<char*>(sHtmlContent.getStr()),
sHtmlContent.getLength(), StreamMode::READ);
SvKeyValueIteratorRef xValues(new SvKeyValueIterator); // Insert newlines for divs, not normally done, so to keep things simple // only enable that for this case.
xValues->Append(SvKeyValue("newline-on-div", "true"));
xValues->Append(SvKeyValue("content-type", "text/html;charset=utf-8"));
rOutliner.Read(aHTMLStream, "", EETextFormat::Html, xValues.get());
}
if (SupportsDoubleBuffering()) // When double-buffering, allow parents to paint on our area. That's // necessary when parents paint the complete buffer.
SetParentClipMode(ParentClipMode::NoClip);
}
if (mnDeleteEventId)
Application::RemoveUserEvent(mnDeleteEventId);
mpOutliner.reset();
mpOutlinerView.reset();
InterimItemWindow::dispose();
}
void SwAnnotationWin::SetPostItText()
{ //If the cursor was visible, then make it visible again after //changing text, e.g. fdo#33599
vcl::Cursor *pCursor = GetOutlinerView()->GetEditView().GetCursor(); bool bCursorVisible = pCursor && pCursor->IsVisible();
//If the new text is the same as the old text, keep the same insertion //point .e.g. fdo#33599
mpField = static_cast<SwPostItField*>(mpFormatField->GetField());
OUString sNewText = mpField->GetPar2(); bool bTextUnchanged = sNewText == mpOutliner->GetEditEngine().GetText();
ESelection aOrigSelection(GetOutlinerView()->GetEditView().GetSelection());
// get text from SwPostItField and insert into our textview
mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
mpOutliner->EnableUndo( false ); #if ENABLE_YRS autoconst mode = mrView.GetDocShell()->GetDoc()->getIDocumentState().SetYrsMode(IYrsTransactionSupplier::Mode::Replay); #endif if( mpField->GetTextObject() )
mpOutliner->SetText( *mpField->GetTextObject() ); else
{
mpOutliner->Clear();
GetOutlinerView()->SetStyleSheet(SwResId(STR_POOLCOLL_COMMENT));
GetOutlinerView()->InsertText(sNewText);
} #if ENABLE_YRS
mrView.GetDocShell()->GetDoc()->getIDocumentState().SetYrsMode(mode); #endif
mpOutliner->ClearModifyFlag();
mpOutliner->GetUndoManager().Clear();
mpOutliner->EnableUndo( true );
mpOutliner->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) ); if (bTextUnchanged)
GetOutlinerView()->GetEditView().SetSelection(aOrigSelection); if (bCursorVisible)
GetOutlinerView()->ShowCursor();
Invalidate();
}
sal_uInt32 SwAnnotationWin::GetParaId()
{ auto pField = static_cast<SwPostItField*>(mpFormatField->GetField()); auto nParaId = pField->GetParaId(); if (nParaId == 0)
{ // The parent annotation does not have a paraId. This happens when the annotation was just // created, and not imported. paraIds are regenerated upon export, thus this new paraId // is only generated so that children annotations can refer to it
nParaId = CreateUniqueParaId();
pField->SetParaId(nParaId);
} return nParaId;
}
void SwAnnotationWin::DeleteThread()
{ // Go to the top and delete each comment one by one
SwAnnotationWin* topNote = GetTopReplyNote(); for (SwAnnotationWin* current = topNote;;)
{
SwAnnotationWin* next = mrMgr.GetNextPostIt(KEY_PAGEDOWN, current);
current->mnDeleteEventId = Application::PostUserEvent( LINK( current, SwAnnotationWin, DeleteHdl), nullptr, true ); if (!next || next->GetTopReplyNote() != topNote) return;
current = next;
}
}
bool SwAnnotationWin::IsThreadResolved()
{ /// First Get the top note // then iterate downwards checking resolved status
SwAnnotationWin* topNote = GetTopReplyNote(); for (SwAnnotationWin* current = topNote;;)
{ if (!current->IsResolved()) returnfalse;
current = mrMgr.GetNextPostIt(KEY_PAGEDOWN, current); if (!current || current->GetTopReplyNote() != topNote) returntrue;
}
}
void SwAnnotationWin::UpdateData()
{ if ( mpOutliner->IsModified() || mbResolvedStateUpdated )
{
IDocumentUndoRedo & rUndoRedo(
mrView.GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
std::unique_ptr<SwField> pOldField; if (rUndoRedo.DoesUndo())
{
pOldField = mpField->Copy();
}
mpField->SetPar2(mpOutliner->GetEditEngine().GetText());
mpField->SetTextObject(mpOutliner->CreateParaObject()); if (rUndoRedo.DoesUndo())
{
SwTextField *const pTextField = mpFormatField->GetTextField();
SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
rUndoRedo.AppendUndo(
std::make_unique<SwUndoFieldFromDoc>(aPosition, *pOldField, *mpField, true));
} // so we get a new layout of notes (anchor position is still the same and we would otherwise not get one)
mrMgr.SetLayout(); // #i98686# if we have several views, all notes should update their text if(mbResolvedStateUpdated)
mpFormatField->Broadcast(SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::RESOLVED)); else
mpFormatField->Broadcast(SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::CHANGED));
mrView.GetDocShell()->SetModified();
}
mpOutliner->ClearModifyFlag();
mpOutliner->GetUndoManager().Clear();
mbResolvedStateUpdated = false;
}
if ( mrMgr.GetActiveSidebarWin() == this)
{
mrMgr.SetActiveSidebarWin(nullptr); // if the note is empty, the previous line will send a delete event, but we are already there if (mnDeleteEventId)
{
Application::RemoveUserEvent(mnDeleteEventId);
mnDeleteEventId = nullptr;
}
} // we delete the field directly, the Mgr cleans up the PostIt by listening
GrabFocusToDocument();
pWrtShell->ClearMark(); auto restoreGuard = mrMgr.ConfigureForCommentDelete();
pWrtShell->DelRight();
}
sal_uInt32 SwAnnotationWin::MoveCaret()
{ // if this is an answer, do not skip over all following ones, but insert directly behind the current one // but when just leaving a note, skip all following ones as well to continue typing return mrMgr.IsAnswer()
? 1
: 1 + CountFollowing();
}
// counts how many SwPostItField we have right after the current one
sal_uInt32 SwAnnotationWin::CountFollowing()
{
SwTextField* pTextField = mpFormatField->GetTextField();
SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
for (sal_Int32 n = 1;; ++n)
{
SwTextAttr * pTextAttr = pTextField->GetTextNode().GetTextAttrForCharAt(
aPosition.GetContentIndex() + n,
RES_TXTATR_ANNOTATION ); if (!pTextAttr) return n - 1; const SwField* pField = pTextAttr->GetFormatField().GetField(); if (!pField || pField->Which() != SwFieldIds::Postit) return n - 1;
}
}
void SwAnnotationWin::InitAnswer(OutlinerParaObject const & rText)
{ // If tiled annotations is off in lok case, skip adding additional reply text. if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations()) return;
//collect our old meta data
SwAnnotationWin* pWin = mrMgr.GetNextPostIt(KEY_PAGEUP, this); if (!pWin) return;
// insert old, selected text or "..." // TODO: iterate over all paragraphs, not only first one to find out if it is empty if (rText.GetTextObject().HasText(0))
GetOutlinerView()->GetEditView().InsertText(rText.GetTextObject()); else
GetOutlinerView()->InsertText(u"..."_ustr);
GetOutlinerView()->InsertText(u"\"\n"_ustr);
//remove all attributes and reset our standard ones
GetOutlinerView()->GetEditView().RemoveAttribsKeepLanguages(true); // let's insert an undo step so the initial text can be easily deleted // but do not use UpdateData() directly, would set modified state again and reentrance into Mgr
mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
IDocumentUndoRedo & rUndoRedo(
mrView.GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
std::unique_ptr<SwField> pOldField; if (rUndoRedo.DoesUndo())
{
pOldField = mpField->Copy();
}
mpField->SetPar2(mpOutliner->GetEditEngine().GetText());
mpField->SetTextObject(mpOutliner->CreateParaObject()); if (rUndoRedo.DoesUndo())
{
SwTextField *const pTextField = mpFormatField->GetTextField();
SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
rUndoRedo.AppendUndo(
std::make_unique<SwUndoFieldFromDoc>(aPosition, *pOldField, *mpField, true));
}
mpOutliner->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
mpOutliner->ClearModifyFlag();
mpOutliner->GetUndoManager().Clear();
}
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.