android: Update app-specific/MIME type icons
[LibreOffice.git] / sd / source / ui / annotations / annotationwindow.cxx
bloba5ab1eb0b784351356a071c52f3fdfeb10045b56
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <editeng/eeitem.hxx>
21 #include <editeng/udlnitem.hxx>
22 #include <editeng/langitem.hxx>
23 #include <editeng/editview.hxx>
24 #include <editeng/editstat.hxx>
25 #include <editeng/outliner.hxx>
26 #include <editeng/editeng.hxx>
27 #include <editeng/outlobj.hxx>
28 #include <editeng/postitem.hxx>
29 #include <editeng/wghtitem.hxx>
30 #include <editeng/crossedoutitem.hxx>
31 #include <svx/svxids.hrc>
32 #include <unotools/useroptions.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <sfx2/bindings.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <svl/stritem.hxx>
39 #include <vcl/commandevent.hxx>
40 #include <vcl/commandinfoprovider.hxx>
41 #include <vcl/vclenum.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/gradient.hxx>
44 #include <vcl/settings.hxx>
45 #include <vcl/ptrstyle.hxx>
47 #include <strings.hrc>
48 #include "annotationwindow.hxx"
49 #include "annotationmanagerimpl.hxx"
51 #include <com/sun/star/office/XAnnotation.hpp>
52 #include <DrawDocShell.hxx>
53 #include <ViewShell.hxx>
54 #include <drawdoc.hxx>
55 #include <textapi.hxx>
56 #include <sdresid.hxx>
58 #include <memory>
60 using namespace ::sd;
61 using namespace ::com::sun::star;
62 using namespace ::com::sun::star::uno;
63 using namespace ::com::sun::star::office;
64 using namespace ::com::sun::star::text;
66 #define METABUTTON_WIDTH 16
67 #define METABUTTON_HEIGHT 18
68 #define POSTIT_META_HEIGHT sal_Int32(30)
70 namespace sd {
72 void AnnotationTextWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect)
74 Size aSize = GetOutputSizePixel();
76 const bool bHighContrast = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
77 if (!bHighContrast)
79 rRenderContext.DrawGradient(::tools::Rectangle(Point(0,0), rRenderContext.PixelToLogic(aSize)),
80 Gradient(css::awt::GradientStyle_LINEAR, mrContents.maColorLight, mrContents.maColor));
83 DoPaint(rRenderContext, rRect);
86 void AnnotationTextWindow::EditViewScrollStateChange()
88 mrContents.SetScrollbar();
91 bool AnnotationTextWindow::KeyInput(const KeyEvent& rKeyEvt)
93 const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
94 sal_uInt16 nKey = rKeyCode.GetCode();
96 bool bDone = false;
98 if ((rKeyCode.IsMod1() && rKeyCode.IsMod2()) && ((nKey == KEY_PAGEUP) || (nKey == KEY_PAGEDOWN)))
100 SfxDispatcher* pDispatcher = mrContents.DocShell()->GetViewShell()->GetViewFrame()->GetDispatcher();
101 if( pDispatcher )
102 pDispatcher->Execute( nKey == KEY_PAGEDOWN ? SID_NEXT_POSTIT : SID_PREVIOUS_POSTIT );
103 bDone = true;
105 else if (nKey == KEY_INSERT)
107 if (!rKeyCode.IsMod1() && !rKeyCode.IsMod2())
108 mrContents.ToggleInsMode();
109 bDone = true;
111 else
113 ::tools::Long aOldHeight = mrContents.GetPostItTextHeight();
115 /// HACK: need to switch off processing of Undo/Redo in Outliner
116 if ( !( (nKey == KEY_Z || nKey == KEY_Y) && rKeyCode.IsMod1()) )
118 bool bIsProtected = mrContents.IsProtected();
119 if (!bIsProtected || !EditEngine::DoesKeyChangeText(rKeyEvt) )
121 if (EditView* pEditView = GetEditView())
123 bDone = pEditView->PostKeyEvent(rKeyEvt);
124 if (!bDone && rKeyEvt.GetKeyCode().IsMod1() && !rKeyEvt.GetKeyCode().IsMod2())
126 if (nKey == KEY_A)
128 EditEngine* pEditEngine = GetEditEngine();
129 sal_Int32 nPar = pEditEngine->GetParagraphCount();
130 if (nPar)
132 sal_Int32 nLen = pEditEngine->GetTextLen(nPar - 1);
133 pEditView->SetSelection(ESelection(0, 0, nPar - 1, nLen));
135 bDone = true;
141 if (bDone)
143 mrContents.ResizeIfNecessary(aOldHeight, mrContents.GetPostItTextHeight());
147 return bDone;
150 AnnotationTextWindow::AnnotationTextWindow(AnnotationWindow& rContents)
151 : mrContents(rContents)
155 EditView* AnnotationTextWindow::GetEditView() const
157 OutlinerView* pOutlinerView = mrContents.GetOutlinerView();
158 if (!pOutlinerView)
159 return nullptr;
160 return &pOutlinerView->GetEditView();
163 EditEngine* AnnotationTextWindow::GetEditEngine() const
165 OutlinerView* pOutlinerView = mrContents.GetOutlinerView();
166 if (!pOutlinerView)
167 return nullptr;
168 return pOutlinerView->GetEditView().GetEditEngine();
171 void AnnotationTextWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
173 Size aSize(0, 0);
174 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
176 SetOutputSizePixel(aSize);
178 weld::CustomWidgetController::SetDrawingArea(pDrawingArea);
180 EnableRTL(false);
182 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
183 Color aBgColor = rStyleSettings.GetWindowColor();
185 OutputDevice& rDevice = pDrawingArea->get_ref_device();
187 rDevice.SetMapMode(MapMode(MapUnit::Map100thMM));
188 rDevice.SetBackground(aBgColor);
190 Size aOutputSize(rDevice.PixelToLogic(aSize));
192 EditView* pEditView = GetEditView();
193 pEditView->setEditViewCallbacks(this);
195 EditEngine* pEditEngine = GetEditEngine();
196 pEditEngine->SetPaperSize(aOutputSize);
197 pEditEngine->SetRefDevice(&rDevice);
199 pEditView->SetOutputArea(::tools::Rectangle(Point(0, 0), aOutputSize));
200 pEditView->SetBackgroundColor(aBgColor);
202 pDrawingArea->set_cursor(PointerStyle::Text);
204 InitAccessible();
207 // see SwAnnotationWin in sw for something similar
208 AnnotationWindow::AnnotationWindow(weld::Window* pParent, const ::tools::Rectangle& rRect,
209 DrawDocShell* pDocShell,
210 const Reference<XAnnotation>& xAnnotation)
211 : mxBuilder(Application::CreateBuilder(pParent, "modules/simpress/ui/annotation.ui"))
212 , mxPopover(mxBuilder->weld_popover("Annotation"))
213 , mxContainer(mxBuilder->weld_widget("container"))
214 , mpDocShell(pDocShell)
215 , mpDoc(pDocShell->GetDoc())
216 , mbReadonly(pDocShell->IsReadOnly())
217 , mbProtected(false)
219 mxContainer->set_size_request(320, 240);
220 mxPopover->popup_at_rect(pParent, rRect);
222 InitControls();
223 setAnnotation(xAnnotation);
224 FillMenuButton();
226 DoResize();
228 mxTextControl->GrabFocus();
231 AnnotationWindow::~AnnotationWindow()
235 void AnnotationWindow::InitControls()
237 // window control for author and date
238 mxMeta = mxBuilder->weld_label("meta");
239 mxMeta->set_direction(AllSettings::GetLayoutRTL());
241 maLabelFont = Application::GetSettings().GetStyleSettings().GetLabelFont();
242 maLabelFont.SetFontHeight(8);
244 // we should leave this setting alone, but for this we need a better layout algo
245 // with variable meta size height
246 mxMeta->set_font(maLabelFont);
248 mpOutliner.reset( new ::Outliner(GetAnnotationPool(),OutlinerMode::TextObject) );
249 SdDrawDocument::SetCalcFieldValueHdl( mpOutliner.get() );
250 mpOutliner->SetUpdateLayout( true );
252 if (OutputDevice* pDev = mpDoc->GetRefDevice())
253 mpOutliner->SetRefDevice( pDev );
255 mpOutlinerView.reset( new OutlinerView ( mpOutliner.get(), nullptr) );
256 mpOutliner->InsertView(mpOutlinerView.get() );
258 //create Scrollbars
259 mxVScrollbar = mxBuilder->weld_scrolled_window("scrolledwindow", true);
261 // actual window which holds the user text
262 mxTextControl.reset(new AnnotationTextWindow(*this));
263 mxTextControlWin.reset(new weld::CustomWeld(*mxBuilder, "editview", *mxTextControl));
264 mxTextControl->SetPointer(PointerStyle::Text);
266 Rescale();
267 OutputDevice& rDevice = mxTextControl->GetDrawingArea()->get_ref_device();
269 mxVScrollbar->set_direction(false);
270 mxVScrollbar->connect_vadjustment_changed(LINK(this, AnnotationWindow, ScrollHdl));
272 mpOutlinerView->SetBackgroundColor(COL_TRANSPARENT);
273 mpOutlinerView->SetOutputArea(rDevice.PixelToLogic(::tools::Rectangle(0, 0, 1, 1)));
275 mxMenuButton = mxBuilder->weld_menu_button("menubutton");
276 if (mbReadonly)
277 mxMenuButton->hide();
278 else
280 mxMenuButton->set_size_request(METABUTTON_WIDTH, METABUTTON_HEIGHT);
281 mxMenuButton->connect_selected(LINK(this, AnnotationWindow, MenuItemSelectedHdl));
284 EEControlBits nCntrl = mpOutliner->GetControlWord();
285 nCntrl |= EEControlBits::PASTESPECIAL | EEControlBits::AUTOCORRECT | EEControlBits::USECHARATTRIBS | EEControlBits::NOCOLORS;
286 mpOutliner->SetControlWord(nCntrl);
288 mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
289 mpOutliner->EnableUndo( false );
291 mpOutliner->ClearModifyFlag();
292 mpOutliner->GetUndoManager().Clear();
293 mpOutliner->EnableUndo( true );
295 SetLanguage(SvxLanguageItem(mpDoc->GetLanguage(EE_CHAR_LANGUAGE), SID_ATTR_LANGUAGE));
297 mxTextControl->GrabFocus();
300 IMPL_LINK(AnnotationWindow, MenuItemSelectedHdl, const OUString&, rIdent, void)
302 SfxDispatcher* pDispatcher = mpDocShell->GetViewShell()->GetViewFrame()->GetDispatcher();
303 if (!pDispatcher)
304 return;
306 if (rIdent == ".uno:ReplyToAnnotation")
308 const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( mxAnnotation ) );
309 pDispatcher->ExecuteList(SID_REPLYTO_POSTIT,
310 SfxCallMode::ASYNCHRON, { &aItem });
312 else if (rIdent == ".uno:DeleteAnnotation")
314 const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( mxAnnotation ) );
315 pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON,
316 { &aItem });
318 else if (rIdent == ".uno:DeleteAllAnnotationByAuthor")
320 const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, mxAnnotation->getAuthor() );
321 pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT,
322 SfxCallMode::ASYNCHRON, { &aItem });
324 else if (rIdent == ".uno:DeleteAllAnnotation")
325 pDispatcher->Execute( SID_DELETEALL_POSTIT );
328 void AnnotationWindow::FillMenuButton()
330 SvtUserOptions aUserOptions;
331 OUString sCurrentAuthor( aUserOptions.GetFullName() );
332 OUString sAuthor( mxAnnotation->getAuthor() );
334 OUString aStr(mxMenuButton->get_item_label(".uno:DeleteAllAnnotationByAuthor"));
335 OUString aReplace( sAuthor );
336 if( aReplace.isEmpty() )
337 aReplace = SdResId( STR_ANNOTATION_NOAUTHOR );
338 aStr = aStr.replaceFirst("%1", aReplace);
339 mxMenuButton->set_item_label(".uno:DeleteAllAnnotationByAuthor", aStr);
341 bool bShowReply = sAuthor != sCurrentAuthor && !mbReadonly;
342 mxMenuButton->set_item_visible(".uno:ReplyToAnnotation", bShowReply);
343 mxMenuButton->set_item_visible("separator", bShowReply);
344 mxMenuButton->set_item_visible(".uno:DeleteAnnotation", mxAnnotation.is() && !mbReadonly);
345 mxMenuButton->set_item_visible(".uno:DeleteAllAnnotationByAuthor", !mbReadonly);
346 mxMenuButton->set_item_visible(".uno:DeleteAllAnnotation", !mbReadonly);
349 void AnnotationWindow::StartEdit()
351 GetOutlinerView()->SetSelection(ESelection(EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT,EE_PARA_MAX_COUNT,EE_TEXTPOS_MAX_COUNT));
352 GetOutlinerView()->ShowCursor();
355 void AnnotationWindow::SetMapMode(const MapMode& rNewMapMode)
357 OutputDevice& rDevice = mxTextControl->GetDrawingArea()->get_ref_device();
358 rDevice.SetMapMode(rNewMapMode);
361 void AnnotationWindow::Rescale()
363 MapMode aMode(MapUnit::Map100thMM);
364 aMode.SetOrigin( Point() );
365 mpOutliner->SetRefMapMode( aMode );
366 SetMapMode( aMode );
368 if (mxMeta)
370 vcl::Font aFont = maLabelFont;
371 sal_Int32 nHeight = ::tools::Long(aFont.GetFontHeight() * aMode.GetScaleY());
372 aFont.SetFontHeight( nHeight );
373 mxMeta->set_font(aFont);
377 void AnnotationWindow::DoResize()
379 OutputDevice& rDevice = mxTextControl->GetDrawingArea()->get_ref_device();
381 ::tools::Long aHeight = mxContainer->get_preferred_size().Height();
382 ::tools::ULong aWidth = mxContainer->get_preferred_size().Width();
384 aHeight -= POSTIT_META_HEIGHT;
386 mpOutliner->SetPaperSize( rDevice.PixelToLogic( Size(aWidth, aHeight) ) ) ;
387 ::tools::Long aTextHeight = rDevice.LogicToPixel(mpOutliner->CalcTextSize()).Height();
389 if( aTextHeight > aHeight )
391 const int nThickness = mxVScrollbar->get_scroll_thickness();
392 if (nThickness)
394 // we need vertical scrollbars and have to reduce the width
395 aWidth -= nThickness;
396 mpOutliner->SetPaperSize(rDevice.PixelToLogic(Size(aWidth, aHeight)));
398 mxVScrollbar->set_vpolicy(VclPolicyType::ALWAYS);
400 else
402 mxVScrollbar->set_vpolicy(VclPolicyType::NEVER);
405 ::tools::Rectangle aOutputArea = rDevice.PixelToLogic(::tools::Rectangle(0, 0, aWidth, aHeight));
406 if (mxVScrollbar->get_vpolicy() == VclPolicyType::NEVER)
408 // if we do not have a scrollbar anymore, we want to see the complete text
409 mpOutlinerView->SetVisArea(aOutputArea);
411 mpOutlinerView->SetOutputArea(aOutputArea);
412 mpOutlinerView->ShowCursor(true, true);
414 int nUpper = mpOutliner->GetTextHeight();
415 int nCurrentDocPos = mpOutlinerView->GetVisArea().Top();
416 int nStepIncrement = mpOutliner->GetTextHeight() / 10;
417 int nPageIncrement = rDevice.PixelToLogic(Size(0,aHeight)).Height() * 8 / 10;
418 int nPageSize = rDevice.PixelToLogic(Size(0,aHeight)).Height();
420 /* limit the page size to below nUpper because gtk's gtk_scrolled_window_start_deceleration has
421 effectively...
423 lower = gtk_adjustment_get_lower
424 upper = gtk_adjustment_get_upper - gtk_adjustment_get_page_size
426 and requires that upper > lower or the deceleration animation never ends
428 nPageSize = std::min(nPageSize, nUpper);
430 mxVScrollbar->vadjustment_configure(nCurrentDocPos, 0, nUpper,
431 nStepIncrement, nPageIncrement, nPageSize);
434 void AnnotationWindow::SetScrollbar()
436 mxVScrollbar->vadjustment_set_value(mpOutlinerView->GetVisArea().Top());
439 void AnnotationWindow::ResizeIfNecessary(::tools::Long aOldHeight, ::tools::Long aNewHeight)
441 if (aOldHeight != aNewHeight)
442 DoResize();
443 else
444 SetScrollbar();
447 void AnnotationWindow::SetLanguage(const SvxLanguageItem &aNewItem)
449 mpOutliner->SetModifyHdl( Link<LinkParamNone*,void>() );
450 ESelection aOld = GetOutlinerView()->GetSelection();
452 ESelection aNewSelection( 0, 0, mpOutliner->GetParagraphCount()-1, EE_TEXTPOS_ALL );
453 GetOutlinerView()->SetSelection( aNewSelection );
454 SfxItemSet aEditAttr(GetOutlinerView()->GetAttribs());
455 aEditAttr.Put(aNewItem);
456 GetOutlinerView()->SetAttribs( aEditAttr );
458 GetOutlinerView()->SetSelection(aOld);
460 mxTextControl->Invalidate();
463 void AnnotationWindow::ToggleInsMode()
465 if( mpOutlinerView )
467 SfxBindings &rBnd = mpDocShell->GetViewShell()->GetViewFrame()->GetBindings();
468 rBnd.Invalidate(SID_ATTR_INSERT);
469 rBnd.Update(SID_ATTR_INSERT);
473 ::tools::Long AnnotationWindow::GetPostItTextHeight()
475 OutputDevice& rDevice = mxTextControl->GetDrawingArea()->get_ref_device();
476 return mpOutliner ? rDevice.LogicToPixel(mpOutliner->CalcTextSize()).Height() : 0;
479 IMPL_LINK(AnnotationWindow, ScrollHdl, weld::ScrolledWindow&, rScrolledWindow, void)
481 ::tools::Long nDiff = GetOutlinerView()->GetEditView().GetVisArea().Top() - rScrolledWindow.vadjustment_get_value();
482 GetOutlinerView()->Scroll( 0, nDiff );
485 TextApiObject* getTextApiObject( const Reference< XAnnotation >& xAnnotation )
487 if( xAnnotation.is() )
489 Reference< XText > xText( xAnnotation->getTextRange() );
490 return TextApiObject::getImplementation( xText );
492 return nullptr;
495 void AnnotationWindow::setAnnotation( const Reference< XAnnotation >& xAnnotation )
497 if( (xAnnotation == mxAnnotation) || !xAnnotation.is() )
498 return;
500 mxAnnotation = xAnnotation;
502 SetColor();
504 SvtUserOptions aUserOptions;
505 mbProtected = aUserOptions.GetFullName() != xAnnotation->getAuthor();
507 mpOutliner->Clear();
508 TextApiObject* pTextApi = getTextApiObject( mxAnnotation );
510 if( pTextApi )
512 std::optional< OutlinerParaObject > pOPO( pTextApi->CreateText() );
513 mpOutliner->SetText(*pOPO);
516 mpOutliner->ClearModifyFlag();
517 mpOutliner->GetUndoManager().Clear();
519 //TODO Invalidate();
521 OUString sMeta( xAnnotation->getAuthor() );
522 OUString sDateTime( getAnnotationDateTimeString(xAnnotation) );
524 if( !sDateTime.isEmpty() )
526 if( !sMeta.isEmpty() )
527 sMeta += "\n";
529 sMeta += sDateTime;
531 mxMeta->set_label(sMeta);
534 void AnnotationWindow::SetColor()
536 sal_uInt16 nAuthorIdx = mpDoc->GetAnnotationAuthorIndex( mxAnnotation->getAuthor() );
538 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
539 const bool bHighContrast = rStyleSettings.GetHighContrastMode();
540 if( bHighContrast )
542 maColor = rStyleSettings.GetWindowColor();
543 maColorDark = maColor;
544 maColorLight = rStyleSettings.GetWindowTextColor();
546 else
548 maColor = AnnotationManagerImpl::GetColor( nAuthorIdx );
549 maColorDark = AnnotationManagerImpl::GetColorDark( nAuthorIdx );
550 maColorLight = AnnotationManagerImpl::GetColorLight( nAuthorIdx );
553 mpOutliner->ForceAutoColor( bHighContrast || SvtAccessibilityOptions::GetIsAutomaticFontColor() );
555 mxPopover->set_background(maColor);
556 mxMenuButton->set_background(maColor);
558 mxMeta->set_font_color(bHighContrast ? maColorLight : maColorDark);
560 mxVScrollbar->customize_scrollbars(maColorLight,
561 maColorDark,
562 maColor);
563 mxVScrollbar->set_scroll_thickness(GetPrefScrollbarWidth());
566 void AnnotationWindow::SaveToDocument()
568 Reference< XAnnotation > xAnnotation( mxAnnotation );
570 // write changed text back to annotation
571 if (mpOutliner->IsModified())
573 TextApiObject* pTextApi = getTextApiObject( xAnnotation );
575 if( pTextApi )
577 std::optional<OutlinerParaObject> pOPO = mpOutliner->CreateParaObject();
578 if( pOPO )
580 if( mpDoc->IsUndoEnabled() )
581 mpDoc->BegUndo( SdResId( STR_ANNOTATION_UNDO_EDIT ) );
583 pTextApi->SetText( *pOPO );
584 pOPO.reset();
586 // set current time to changed annotation
587 xAnnotation->setDateTime( getCurrentDateTime() );
589 if( mpDoc->IsUndoEnabled() )
590 mpDoc->EndUndo();
592 mpDocShell->SetModified();
597 mpOutliner->ClearModifyFlag();
599 mpOutliner->GetUndoManager().Clear();
602 bool AnnotationTextWindow::Command(const CommandEvent& rCEvt)
604 if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
606 const bool bReadOnly = mrContents.DocShell()->IsReadOnly();
607 if (bReadOnly)
608 return true;
610 SfxDispatcher* pDispatcher = mrContents.DocShell()->GetViewShell()->GetViewFrame()->GetDispatcher();
611 if( !pDispatcher )
612 return true;
614 if (IsMouseCaptured())
616 // so the menu can capture it and the EditView doesn't get the button release and change its
617 // selection on a successful button click
618 ReleaseMouse();
621 ::tools::Rectangle aRect(rCEvt.GetMousePosPixel(), Size(1, 1));
622 weld::Widget* pPopupParent = GetDrawingArea();
623 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/simpress/ui/annotationtagmenu.ui"));
624 std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu("menu"));
626 auto xAnnotation = mrContents.getAnnotation();
628 SvtUserOptions aUserOptions;
629 OUString sCurrentAuthor( aUserOptions.GetFullName() );
630 OUString sAuthor( xAnnotation->getAuthor() );
632 OUString aStr(xMenu->get_label(".uno:DeleteAllAnnotationByAuthor"));
633 OUString aReplace( sAuthor );
634 if( aReplace.isEmpty() )
635 aReplace = SdResId( STR_ANNOTATION_NOAUTHOR );
636 aStr = aStr.replaceFirst("%1", aReplace);
637 xMenu->set_label(".uno:DeleteAllAnnotationByAuthor", aStr);
639 bool bShowReply = sAuthor != sCurrentAuthor && !bReadOnly;
640 xMenu->set_visible(".uno:ReplyToAnnotation", bShowReply);
641 xMenu->set_visible("separator", bShowReply);
642 xMenu->set_visible(".uno:DeleteAnnotation", xAnnotation.is() && !bReadOnly);
643 xMenu->set_visible(".uno:DeleteAllAnnotationByAuthor", !bReadOnly);
644 xMenu->set_visible(".uno:DeleteAllAnnotation", !bReadOnly);
646 int nInsertPos = 2;
648 auto xFrame = mrContents.DocShell()->GetViewShell()->GetViewFrame()->GetFrame().GetFrameInterface();
649 OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
651 bool bEditable = !mrContents.IsProtected() && !bReadOnly;
652 if (bEditable)
654 SfxItemSet aSet(mrContents.GetOutlinerView()->GetAttribs());
656 xMenu->insert(nInsertPos++, ".uno:Bold",
657 vcl::CommandInfoProvider::GetMenuLabelForCommand(
658 vcl::CommandInfoProvider::GetCommandProperties(".uno:Bold", aModuleName)),
659 nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Bold", xFrame),
660 TRISTATE_TRUE);
662 if ( aSet.GetItemState( EE_CHAR_WEIGHT ) == SfxItemState::SET )
664 if( aSet.Get( EE_CHAR_WEIGHT ).GetWeight() == WEIGHT_BOLD )
665 xMenu->set_active(".uno:Bold", true);
668 xMenu->insert(nInsertPos++, ".uno:Italic",
669 vcl::CommandInfoProvider::GetMenuLabelForCommand(
670 vcl::CommandInfoProvider::GetCommandProperties(".uno:Italic", aModuleName)),
671 nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Italic", xFrame),
672 TRISTATE_TRUE);
674 if ( aSet.GetItemState( EE_CHAR_ITALIC ) == SfxItemState::SET )
676 if( aSet.Get( EE_CHAR_ITALIC ).GetPosture() != ITALIC_NONE )
677 xMenu->set_active(".uno:Italic", true);
681 xMenu->insert(nInsertPos++, ".uno:Underline",
682 vcl::CommandInfoProvider::GetMenuLabelForCommand(
683 vcl::CommandInfoProvider::GetCommandProperties(".uno:Underline", aModuleName)),
684 nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Underline", xFrame),
685 TRISTATE_TRUE);
687 if ( aSet.GetItemState( EE_CHAR_UNDERLINE ) == SfxItemState::SET )
689 if( aSet.Get( EE_CHAR_UNDERLINE ).GetLineStyle() != LINESTYLE_NONE )
690 xMenu->set_active(".uno:Underline", true);
693 xMenu->insert(nInsertPos++, ".uno:Strikeout",
694 vcl::CommandInfoProvider::GetMenuLabelForCommand(
695 vcl::CommandInfoProvider::GetCommandProperties(".uno:Strikeout", aModuleName)),
696 nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Strikeout", xFrame),
697 TRISTATE_TRUE);
699 if ( aSet.GetItemState( EE_CHAR_STRIKEOUT ) == SfxItemState::SET )
701 if( aSet.Get( EE_CHAR_STRIKEOUT ).GetStrikeout() != STRIKEOUT_NONE )
702 xMenu->set_active(".uno:Strikeout", true);
705 xMenu->insert_separator(nInsertPos++, "separator2");
708 xMenu->insert(nInsertPos++, ".uno:Copy",
709 vcl::CommandInfoProvider::GetMenuLabelForCommand(
710 vcl::CommandInfoProvider::GetCommandProperties(".uno:Copy", aModuleName)),
711 nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Copy", xFrame),
712 TRISTATE_INDET);
714 xMenu->insert(nInsertPos++, ".uno:Paste",
715 vcl::CommandInfoProvider::GetMenuLabelForCommand(
716 vcl::CommandInfoProvider::GetCommandProperties(".uno:Paste", aModuleName)),
717 nullptr, nullptr, vcl::CommandInfoProvider::GetXGraphicForCommand(".uno:Paste", xFrame),
718 TRISTATE_INDET);
720 bool bCanPaste = false;
721 if (bEditable)
723 TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromClipboard(GetClipboard()));
724 bCanPaste = aDataHelper.GetFormatCount() != 0;
727 xMenu->insert_separator(nInsertPos++, "separator3");
729 xMenu->set_sensitive(".uno:Copy", mrContents.GetOutlinerView()->HasSelection());
730 xMenu->set_sensitive(".uno:Paste", bCanPaste);
732 auto sId = xMenu->popup_at_rect(pPopupParent, aRect);
734 if (sId == ".uno:ReplyToAnnotation")
736 const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( xAnnotation ) );
737 pDispatcher->ExecuteList(SID_REPLYTO_POSTIT,
738 SfxCallMode::ASYNCHRON, { &aItem });
740 else if (sId == ".uno:DeleteAnnotation")
742 const SfxUnoAnyItem aItem( SID_DELETE_POSTIT, Any( xAnnotation ) );
743 pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON,
744 { &aItem });
746 else if (sId == ".uno:DeleteAllAnnotationByAuthor")
748 const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor );
749 pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT,
750 SfxCallMode::ASYNCHRON, { &aItem });
752 else if (sId == ".uno:DeleteAllAnnotation")
753 pDispatcher->Execute( SID_DELETEALL_POSTIT );
754 else if (sId == ".uno:Copy")
756 mrContents.GetOutlinerView()->Copy();
758 else if (sId == ".uno:Paste")
760 mrContents.GetOutlinerView()->PasteSpecial();
761 mrContents.DoResize();
763 else if (!sId.isEmpty())
765 SfxItemSet aEditAttr(mrContents.GetOutlinerView()->GetAttribs());
766 SfxItemSet aNewAttr(mrContents.GetOutliner()->GetEmptyItemSet());
768 if (sId == ".uno:Bold")
770 FontWeight eFW = aEditAttr.Get( EE_CHAR_WEIGHT ).GetWeight();
771 aNewAttr.Put( SvxWeightItem( eFW == WEIGHT_NORMAL ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
773 else if (sId == ".uno:Italic")
775 FontItalic eFI = aEditAttr.Get( EE_CHAR_ITALIC ).GetPosture();
776 aNewAttr.Put( SvxPostureItem( eFI == ITALIC_NORMAL ? ITALIC_NONE : ITALIC_NORMAL, EE_CHAR_ITALIC ) );
778 else if (sId == ".uno:Underline")
780 FontLineStyle eFU = aEditAttr. Get( EE_CHAR_UNDERLINE ).GetLineStyle();
781 aNewAttr.Put( SvxUnderlineItem( eFU == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, EE_CHAR_UNDERLINE ) );
783 else if (sId == ".uno:Strikeout")
785 FontStrikeout eFSO = aEditAttr.Get( EE_CHAR_STRIKEOUT ).GetStrikeout();
786 aNewAttr.Put( SvxCrossedOutItem( eFSO == STRIKEOUT_SINGLE ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, EE_CHAR_STRIKEOUT ) );
789 mrContents.GetOutlinerView()->SetAttribs( aNewAttr );
792 return true;
794 return WeldEditView::Command(rCEvt);
799 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */