Coverage Report

Created: 2026-08-14 10:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/sw/source/uibase/docvw/AnnotationWin.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <config_wasm_strip.h>
21
22
#include <AnnotationWin.hxx>
23
24
#include <PostItMgr.hxx>
25
26
#include <strings.hrc>
27
28
#include <uiobject.hxx>
29
30
#include <vcl/svapp.hxx>
31
#include <vcl/uitest/logger.hxx>
32
#include <vcl/uitest/eventdescription.hxx>
33
#include <vcl/weld/Container.hxx>
34
35
#include <svl/undo.hxx>
36
#include <svtools/svparser.hxx>
37
#include <unotools/localedatawrapper.hxx>
38
#include <unotools/syslocale.hxx>
39
#include <svl/languageoptions.hxx>
40
#include <osl/diagnose.h>
41
42
#include <editeng/eeitem.hxx>
43
#include <editeng/postitem.hxx>
44
#include <editeng/fhgtitem.hxx>
45
#include <editeng/langitem.hxx>
46
#include <editeng/editund2.hxx>
47
48
#include <editeng/editview.hxx>
49
#include <editeng/outliner.hxx>
50
#include <editeng/editeng.hxx>
51
#include <editeng/editobj.hxx>
52
#include <editeng/outlobj.hxx>
53
54
#include <comphelper/lok.hxx>
55
#include <comphelper/random.hxx>
56
#include <docufld.hxx>
57
#include <txtfld.hxx>
58
#include <ndtxt.hxx>
59
#include <view.hxx>
60
#include <viewopt.hxx>
61
#include <wrtsh.hxx>
62
#include <docsh.hxx>
63
#include <doc.hxx>
64
#include <IDocumentUndoRedo.hxx>
65
#if ENABLE_YRS
66
#include <IDocumentState.hxx>
67
#endif
68
#include <SwUndoField.hxx>
69
#include <edtwin.hxx>
70
#include "ShadowOverlayObject.hxx"
71
#include "AnchorOverlayObject.hxx"
72
#include "OverlayRanges.hxx"
73
#include "SidebarTxtControl.hxx"
74
#include "SidebarWinAcc.hxx"
75
76
#include <memory>
77
78
namespace{
79
80
void collectUIInformation( const OUString& aevent , const OUString& aID )
81
0
{
82
0
    EventDescription aDescription;
83
0
    aDescription.aID =  aID;
84
0
    aDescription.aParameters = {{"" ,  ""}};
85
0
    aDescription.aAction = aevent;
86
0
    aDescription.aParent = "MainWindow";
87
0
    aDescription.aKeyWord = "SwEditWinUIObject";
88
0
    UITestLogger::getInstance().logEvent(aDescription);
89
0
}
90
91
}
92
93
namespace SwPostItHelper {
94
95
void ImportHTML(Outliner& rOutliner, const OUString& rHtml)
96
0
{
97
0
    OString sHtmlContent(rHtml.toUtf8());
98
0
    SvMemoryStream aHTMLStream(const_cast<char*>(sHtmlContent.getStr()),
99
0
                               sHtmlContent.getLength(), StreamMode::READ);
100
0
    SvKeyValueIteratorRef xValues(new SvKeyValueIterator);
101
    // Insert newlines for divs, not normally done, so to keep things simple
102
    // only enable that for this case.
103
0
    xValues->Append(SvKeyValue("newline-on-div", "true"));
104
0
    xValues->Append(SvKeyValue("content-type", "text/html;charset=utf-8"));
105
0
    rOutliner.Read(aHTMLStream, "", EETextFormat::Html, xValues.get());
106
0
}
107
108
}
109
110
namespace sw::annotation {
111
112
// see AnnotationContents in sd for something similar
113
SwAnnotationWin::SwAnnotationWin( SwEditWin& rEditWin,
114
                                  SwPostItMgr& aMgr,
115
                                  SwAnnotationItem& rSidebarItem,
116
                                  SwFormatField* aField )
117
0
    : InterimItemWindow(&rEditWin, u"modules/swriter/ui/annotation.ui"_ustr, u"Annotation"_ustr)
118
0
    , mrMgr(aMgr)
119
0
    , mrView(rEditWin.GetView())
120
0
    , mnDeleteEventId(nullptr)
121
0
    , meSidebarPosition(sw::sidebarwindows::SidebarPosition::NONE)
122
0
    , mPageBorder(0)
123
0
    , mbAnchorRectChanged(false)
124
0
    , mbResolvedStateUpdated(false)
125
0
    , mbMouseOver(false)
126
0
    , mLayoutStatus(SwPostItHelper::INVISIBLE)
127
0
    , mbReadonly(false)
128
0
    , mbIsFollow(false)
129
0
    , mpSidebarItem(&rSidebarItem)
130
0
    , mpAnchorFrame(rSidebarItem.maLayoutInfo.mpAnchorFrame)
131
0
    , mpFormatField(aField)
132
0
    , mpField( static_cast<SwPostItField*>(aField->GetField()))
133
0
{
134
0
    set_id("Comment"+OUString::number(mpField->GetPostItId()));
135
136
0
    m_xContainer->connect_mouse_move(LINK(this, SwAnnotationWin, MouseMoveHdl));
137
138
0
    mpShadow = sidebarwindows::ShadowOverlayObject::CreateShadowOverlayObject( mrView );
139
0
    if ( mpShadow )
140
0
    {
141
0
        mpShadow->setVisible(false);
142
0
    }
143
144
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
145
0
    if (rSidebarItem.maLayoutInfo.mpAnchorFrame)
146
0
    {
147
0
        mrMgr.ConnectSidebarWinToFrame( *(rSidebarItem.maLayoutInfo.mpAnchorFrame),
148
0
                                      mpSidebarItem->GetFormatField(),
149
0
                                      *this );
150
0
    }
151
0
#endif
152
153
0
    if (SupportsDoubleBuffering())
154
        // When double-buffering, allow parents to paint on our area. That's
155
        // necessary when parents paint the complete buffer.
156
0
        SetParentClipMode(ParentClipMode::NoClip);
157
0
}
Unexecuted instantiation: sw::annotation::SwAnnotationWin::SwAnnotationWin(SwEditWin&, SwPostItMgr&, SwAnnotationItem&, SwFormatField*)
Unexecuted instantiation: sw::annotation::SwAnnotationWin::SwAnnotationWin(SwEditWin&, SwPostItMgr&, SwAnnotationItem&, SwFormatField*)
158
159
SwAnnotationWin::~SwAnnotationWin()
160
0
{
161
0
    disposeOnce();
162
0
}
163
164
void SwAnnotationWin::dispose()
165
0
{
166
0
#if !ENABLE_WASM_STRIP_ACCESSIBILITY
167
0
    mrMgr.DisconnectSidebarWinFromFrame( *(mpSidebarItem->maLayoutInfo.mpAnchorFrame),
168
0
                                       *this );
169
0
#endif
170
0
    Disable();
171
172
0
    mxSidebarTextControlWin.reset();
173
0
    mxSidebarTextControl.reset();
174
175
0
    mxMetadataAuthor.reset();
176
0
    mxMetadataResolved.reset();
177
0
    mxMetadataDate.reset();
178
0
    mxVScrollbar.reset();
179
180
0
    mpAnchor.reset();
181
0
    mpShadow.reset();
182
183
0
    mpTextRangeOverlay.reset();
184
185
0
    mxMenuButton.reset();
186
187
0
    if (mnDeleteEventId)
188
0
        Application::RemoveUserEvent(mnDeleteEventId);
189
190
0
    mpOutliner.reset();
191
0
    mpOutlinerView.reset();
192
193
0
    InterimItemWindow::dispose();
194
0
}
195
196
void SwAnnotationWin::SetPostItText()
197
0
{
198
    //If the cursor was visible, then make it visible again after
199
    //changing text, e.g. fdo#33599
200
0
    vcl::Cursor *pCursor = GetOutlinerView()->GetEditView().GetCursor();
201
0
    bool bCursorVisible = pCursor && pCursor->IsVisible();
202
203
    //If the new text is the same as the old text, keep the same insertion
204
    //point .e.g. fdo#33599
205
0
    mpField = static_cast<SwPostItField*>(mpFormatField->GetField());
206
0
    OUString sNewText = mpField->GetPar2();
207
0
    bool bTextUnchanged = sNewText == mpOutliner->GetEditEngine().GetText();
208
0
    ESelection aOrigSelection(GetOutlinerView()->GetEditView().GetSelection());
209
210
    // get text from SwPostItField and insert into our textview
211
0
    mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
212
0
    mpOutliner->EnableUndo( false );
213
#if ENABLE_YRS
214
    auto const mode = mrView.GetDocShell()->GetDoc()->getIDocumentState().SetYrsMode(IYrsTransactionSupplier::Mode::Replay);
215
#endif
216
0
    if( mpField->GetTextObject() )
217
0
        mpOutliner->SetText( *mpField->GetTextObject() );
218
0
    else
219
0
    {
220
0
        mpOutliner->Clear();
221
0
        GetOutlinerView()->SetStyleSheet(SwResId(STR_POOLCOLL_COMMENT));
222
0
        GetOutlinerView()->InsertText(sNewText);
223
0
    }
224
#if ENABLE_YRS
225
    mrView.GetDocShell()->GetDoc()->getIDocumentState().SetYrsMode(mode);
226
#endif
227
228
0
    mpOutliner->ClearModifyFlag();
229
0
    mpOutliner->GetUndoManager().Clear();
230
0
    mpOutliner->EnableUndo( true );
231
0
    mpOutliner->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
232
0
    if (bTextUnchanged)
233
0
        GetOutlinerView()->GetEditView().SetSelection(aOrigSelection);
234
0
    if (bCursorVisible)
235
0
        GetOutlinerView()->ShowCursor();
236
0
    Invalidate();
237
0
}
238
239
void SwAnnotationWin::GeneratePostItName()
240
0
{
241
0
    if (mpField && mpField->GetName().isEmpty())
242
0
    {
243
0
        mpField->SetName(sw::mark::MarkBase::GenerateNewName(u"__Annotation__"));
244
0
    }
245
0
}
246
247
void SwAnnotationWin::SetResolved(bool resolved)
248
0
{
249
0
    bool oldState = IsResolved();
250
0
    static_cast<SwPostItField*>(mpFormatField->GetField())->SetResolved(resolved);
251
0
    if (SwWrtShell* pWrtShell = mrView.GetWrtShellPtr())
252
0
    {
253
0
        const SwViewOption* pVOpt = pWrtShell->GetViewOptions();
254
0
        mpSidebarItem->mbShow = !IsResolved() || (pVOpt->IsResolvedPostIts());
255
0
    }
256
257
0
    mpTextRangeOverlay.reset();
258
259
0
    if(IsResolved())
260
0
        mxMetadataResolved->show();
261
0
    else
262
0
        mxMetadataResolved->hide();
263
264
0
    if(IsResolved() != oldState)
265
0
    {
266
0
        mbResolvedStateUpdated = true;
267
#if ENABLE_YRS
268
        // for undo, before UpdateData()
269
        mrView.GetDocShell()->GetDoc()->getIDocumentState().YrsNotifySetResolved(
270
            GetOutlinerView()->GetEditView().GetYrsCommentId(),
271
            *static_cast<SwPostItField const*>(mpFormatField->GetField()));
272
#endif
273
0
    }
274
0
    UpdateData();
275
0
    Invalidate();
276
0
    collectUIInformation(u"SETRESOLVED"_ustr,get_id());
277
0
}
278
279
void SwAnnotationWin::ToggleResolved()
280
0
{
281
0
    SetResolved(!IsResolved());
282
0
}
283
284
void SwAnnotationWin::ToggleResolvedForThread()
285
0
{
286
0
    auto pTop = GetTopReplyNote();
287
0
    pTop->ToggleResolved();
288
0
    mrMgr.UpdateResolvedStatus(pTop);
289
0
    mrMgr.LayoutPostIts();
290
0
}
291
292
sal_uInt32 SwAnnotationWin::GetParaId()
293
0
{
294
0
    auto pField = static_cast<SwPostItField*>(mpFormatField->GetField());
295
0
    auto nParaId = pField->GetParaId();
296
0
    if (nParaId == 0)
297
0
    {
298
        // The parent annotation does not have a paraId. This happens when the annotation was just
299
        // created, and not imported. paraIds are regenerated upon export, thus this new paraId
300
        // is only generated so that children annotations can refer to it
301
0
        nParaId = CreateUniqueParaId();
302
0
        pField->SetParaId(nParaId);
303
0
    }
304
0
    return nParaId;
305
0
}
306
307
sal_uInt32 SwAnnotationWin::CreateUniqueParaId()
308
0
{
309
0
    return comphelper::rng::uniform_uint_distribution(0, std::numeric_limits<sal_uInt32>::max());
310
0
}
311
312
void SwAnnotationWin::DeleteThread()
313
0
{
314
    // Go to the top and delete each comment one by one
315
0
    SwAnnotationWin* topNote = GetTopReplyNote();
316
0
    for (SwAnnotationWin* current = topNote;;)
317
0
    {
318
0
        SwAnnotationWin* next = mrMgr.GetNextPostIt(KEY_PAGEDOWN, current);
319
0
        current->mnDeleteEventId = Application::PostUserEvent( LINK( current, SwAnnotationWin, DeleteHdl), nullptr, true );
320
0
        if (!next || next->GetTopReplyNote() != topNote)
321
0
            return;
322
0
        current = next;
323
0
    }
324
0
}
325
326
bool SwAnnotationWin::IsResolved() const
327
0
{
328
0
    return static_cast<SwPostItField*>(mpFormatField->GetField())->GetResolved();
329
0
}
330
331
bool SwAnnotationWin::IsThreadResolved()
332
0
{
333
    /// First Get the top note
334
    // then iterate downwards checking resolved status
335
0
    SwAnnotationWin* topNote = GetTopReplyNote();
336
0
    for (SwAnnotationWin* current = topNote;;)
337
0
    {
338
0
        if (!current->IsResolved())
339
0
            return false;
340
0
        current = mrMgr.GetNextPostIt(KEY_PAGEDOWN, current);
341
0
        if (!current || current->GetTopReplyNote() != topNote)
342
0
            return true;
343
0
    }
344
0
}
345
346
bool SwAnnotationWin::IsRootNote() const
347
0
{
348
0
    return static_cast<SwPostItField*>(mpFormatField->GetField())->GetParentPostItId() == 0;
349
0
}
350
351
void SwAnnotationWin::SetAsRoot()
352
0
{
353
0
    if (!IsRootNote())
354
0
    {
355
0
        SwPostItField* pPostIt = static_cast<SwPostItField*>(mpFormatField->GetField());
356
0
        pPostIt->SetParentId(0);
357
0
        pPostIt->SetParentPostItId(0);
358
0
        pPostIt->SetParentName(SwMarkName());
359
0
        mrMgr.MoveSubthreadToRoot(this);
360
0
        mpFormatField->Broadcast(SwFormatFieldHint(nullptr, SwFormatFieldHintWhich::CHANGED));
361
0
    }
362
0
}
363
364
void SwAnnotationWin::UpdateData()
365
0
{
366
0
    if ( mpOutliner->IsModified() || mbResolvedStateUpdated )
367
0
    {
368
0
        IDocumentUndoRedo & rUndoRedo(
369
0
            mrView.GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
370
0
        std::unique_ptr<SwField> pOldField;
371
0
        if (rUndoRedo.DoesUndo())
372
0
        {
373
0
            pOldField = mpField->Copy();
374
0
        }
375
0
        mpField->SetPar2(mpOutliner->GetEditEngine().GetText());
376
0
        mpField->SetTextObject(mpOutliner->CreateParaObject());
377
0
        if (rUndoRedo.DoesUndo())
378
0
        {
379
0
            SwTextField *const pTextField = mpFormatField->GetTextField();
380
0
            SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
381
0
            rUndoRedo.AppendUndo(
382
0
                std::make_unique<SwUndoFieldFromDoc>(aPosition, *pOldField, *mpField, true));
383
#if ENABLE_YRS
384
            mrView.GetDocShell()->GetDoc()->getIDocumentState().YrsEndUndo();
385
#endif
386
0
        }
387
        // so we get a new layout of notes (anchor position is still the same and we would otherwise not get one)
388
0
        mrMgr.SetLayout();
389
        // #i98686# if we have several views, all notes should update their text
390
0
        if(mbResolvedStateUpdated)
391
0
            mpFormatField->Broadcast(SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::RESOLVED));
392
0
        else
393
0
            mpFormatField->Broadcast(SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::CHANGED));
394
0
        mrView.GetDocShell()->SetModified();
395
396
0
        UpdateMenu();
397
0
    }
398
0
    mpOutliner->ClearModifyFlag();
399
0
    mpOutliner->GetUndoManager().Clear();
400
0
    mbResolvedStateUpdated = false;
401
0
}
402
403
void SwAnnotationWin::Delete()
404
0
{
405
0
    collectUIInformation(u"DELETE"_ustr,get_id());
406
0
    SwWrtShell* pWrtShell = mrView.GetWrtShellPtr();
407
0
    if (!(pWrtShell && pWrtShell->GotoField(*mpFormatField)))
408
0
        return;
409
410
0
    if ( mrMgr.GetActiveSidebarWin() == this)
411
0
    {
412
0
        mrMgr.SetActiveSidebarWin(nullptr);
413
        // if the note is empty, the previous line will send a delete event, but we are already there
414
0
        if (mnDeleteEventId)
415
0
        {
416
0
            Application::RemoveUserEvent(mnDeleteEventId);
417
0
            mnDeleteEventId = nullptr;
418
0
        }
419
0
    }
420
    // we delete the field directly, the Mgr cleans up the PostIt by listening
421
0
    GrabFocusToDocument();
422
0
    pWrtShell->ClearMark();
423
0
    auto restoreGuard = mrMgr.ConfigureForCommentDelete();
424
0
    pWrtShell->DelRight();
425
0
}
426
427
void SwAnnotationWin::GotoPos()
428
0
{
429
0
    mrView.GetDocShell()->GetWrtShell()->GotoField(*mpFormatField);
430
0
}
431
432
sal_uInt32 SwAnnotationWin::MoveCaret()
433
0
{
434
    // if this is an answer, do not skip over all following ones, but insert directly behind the current one
435
    // but when just leaving a note, skip all following ones as well to continue typing
436
0
    return mrMgr.IsAnswer()
437
0
           ? 1
438
0
           : 1 + CountFollowing();
439
0
}
440
441
// counts how many SwPostItField we have right after the current one
442
sal_uInt32 SwAnnotationWin::CountFollowing()
443
0
{
444
0
    SwTextField* pTextField = mpFormatField->GetTextField();
445
0
    SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
446
447
0
    for (sal_Int32 n = 1;; ++n)
448
0
    {
449
0
        SwTextAttr * pTextAttr = pTextField->GetTextNode().GetTextAttrForCharAt(
450
0
                                            aPosition.GetContentIndex() + n,
451
0
                                            RES_TXTATR_ANNOTATION );
452
0
        if (!pTextAttr)
453
0
            return n - 1;
454
0
        const SwField* pField = pTextAttr->GetFormatField().GetField();
455
0
        if (!pField || pField->Which() != SwFieldIds::Postit)
456
0
            return n - 1;
457
0
    }
458
0
}
459
460
void SwAnnotationWin::InitAnswer(OutlinerParaObject const & rText)
461
0
{
462
    // If tiled annotations is off in lok case, skip adding additional reply text.
463
0
    if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isTiledAnnotations())
464
0
        return;
465
466
    //collect our old meta data
467
0
    SwAnnotationWin* pWin = mrMgr.GetNextPostIt(KEY_PAGEUP, this);
468
0
    if (!pWin)
469
0
        return;
470
471
0
    const SvtSysLocale aSysLocale;
472
0
    const LocaleDataWrapper& rLocalData = aSysLocale.GetLocaleData();
473
0
    SwRewriter aRewriter;
474
0
    aRewriter.AddRule(UndoArg1, pWin->GetAuthor());
475
0
    const OUString aText = aRewriter.Apply(SwResId(STR_REPLY))
476
0
            + " (" + rLocalData.getDate( pWin->GetDate())
477
0
            + ", " + rLocalData.getTime( pWin->GetTime(), false)
478
0
            + "): \"";
479
0
    GetOutlinerView()->InsertText(aText);
480
481
    // insert old, selected text or "..."
482
    // TODO: iterate over all paragraphs, not only first one to find out if it is empty
483
0
    if (rText.GetTextObject().HasText(0))
484
0
        GetOutlinerView()->GetEditView().InsertText(rText.GetTextObject());
485
0
    else
486
0
        GetOutlinerView()->InsertText(u"..."_ustr);
487
0
    GetOutlinerView()->InsertText(u"\"\n"_ustr);
488
489
0
    GetOutlinerView()->SetSelection(ESelection::All());
490
0
    SfxItemSet aAnswerSet( mrView.GetDocShell()->GetPool() );
491
0
    aAnswerSet.Put(SvxFontHeightItem(200,80,EE_CHAR_FONTHEIGHT));
492
0
    aAnswerSet.Put(SvxPostureItem(ITALIC_NORMAL,EE_CHAR_ITALIC));
493
0
    GetOutlinerView()->SetAttribs(aAnswerSet);
494
0
    GetOutlinerView()->SetSelection(ESelection::AtEnd());
495
496
    //remove all attributes and reset our standard ones
497
0
    GetOutlinerView()->GetEditView().RemoveAttribsKeepLanguages(true);
498
    // let's insert an undo step so the initial text can be easily deleted
499
    // but do not use UpdateData() directly, would set modified state again and reentrance into Mgr
500
0
    mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
501
0
    IDocumentUndoRedo & rUndoRedo(
502
0
        mrView.GetDocShell()->GetDoc()->GetIDocumentUndoRedo());
503
0
    std::unique_ptr<SwField> pOldField;
504
0
    if (rUndoRedo.DoesUndo())
505
0
    {
506
0
        pOldField = mpField->Copy();
507
0
    }
508
0
    mpField->SetPar2(mpOutliner->GetEditEngine().GetText());
509
0
    mpField->SetTextObject(mpOutliner->CreateParaObject());
510
0
    if (rUndoRedo.DoesUndo())
511
0
    {
512
0
        SwTextField *const pTextField = mpFormatField->GetTextField();
513
0
        SwPosition aPosition( pTextField->GetTextNode(), pTextField->GetStart() );
514
0
        rUndoRedo.AppendUndo(
515
0
            std::make_unique<SwUndoFieldFromDoc>(aPosition, *pOldField, *mpField, true));
516
#if ENABLE_YRS
517
// no! there is a StartUndo wrapping this        mrView.GetDocShell()->GetDoc()->getIDocumentState().YrsEndUndo();
518
#endif
519
0
    }
520
0
    mpOutliner->SetModifyHdl( LINK( this, SwAnnotationWin, ModifyHdl ) );
521
0
    mpOutliner->ClearModifyFlag();
522
0
    mpOutliner->GetUndoManager().Clear();
523
0
}
524
525
void SwAnnotationWin::UpdateText(const OUString& aText)
526
0
{
527
0
    mpOutliner->Clear();
528
0
    GetOutlinerView()->InsertText(aText);
529
0
    UpdateData();
530
0
}
531
532
void SwAnnotationWin::UpdateHTML(const OUString& rHtml)
533
0
{
534
0
    mpOutliner->Clear();
535
0
    SwPostItHelper::ImportHTML(*mpOutliner, rHtml);
536
0
    UpdateData();
537
0
}
538
539
OString SwAnnotationWin::GetSimpleHtml() const
540
0
{
541
0
    return GetOutlinerView()->GetEditView().GetSimpleHtml();
542
0
}
543
544
bool SwAnnotationWin::IsReadOnly() const
545
0
{
546
0
    return mbReadonly;
547
0
}
548
549
bool SwAnnotationWin::IsReadOnlyOrProtected() const
550
0
{
551
0
    return IsReadOnly() ||
552
0
           GetLayoutStatus() == SwPostItHelper::DELETED ||
553
0
           ( mpFormatField && mpFormatField->IsProtect() );
554
0
}
555
556
OUString SwAnnotationWin::GetAuthor() const
557
0
{
558
0
    return mpField->GetPar1();
559
0
}
560
561
Date SwAnnotationWin::GetDate() const
562
0
{
563
0
    return mpField->GetDate();
564
0
}
565
566
tools::Time SwAnnotationWin::GetTime() const
567
0
{
568
0
    return mpField->GetTime();
569
0
}
570
571
FactoryFunction SwAnnotationWin::GetUITestFactory() const
572
0
{
573
0
    return CommentUIObject::create;
574
0
}
575
576
} // end of namespace sw::annotation
577
578
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */