Coverage Report

Created: 2025-12-08 09:28

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