Update git submodules
[LibreOffice.git] / sd / source / ui / view / outlnvsh.cxx
blobf55ad226fa4e2e98566aa56aee65439c5954bec1
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 <OutlineViewShell.hxx>
21 #include <Outliner.hxx>
23 #include <helpids.h>
24 #include <app.hrc>
25 #include <svx/hyperdlg.hxx>
26 #include <svx/zoomslideritem.hxx>
27 #include <svx/svdundo.hxx>
29 #include <sfx2/infobar.hxx>
30 #include <sfx2/objface.hxx>
31 #include <sfx2/zoomitem.hxx>
32 #include <editeng/editview.hxx>
33 #include <editeng/eeitem.hxx>
34 #include <editeng/flditem.hxx>
35 #include <editeng/editund2.hxx>
36 #include <sfx2/shell.hxx>
37 #include <sfx2/request.hxx>
38 #include <svx/hlnkitem.hxx>
39 #include <svx/svdotext.hxx>
40 #include <svx/svdoutl.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <sfx2/viewfrm.hxx>
43 #include <vcl/commandevent.hxx>
44 #include <vcl/settings.hxx>
46 #include <sal/log.hxx>
47 #include <svl/stritem.hxx>
48 #include <svl/whiter.hxx>
49 #include <editeng/editstat.hxx>
50 #include <svl/itempool.hxx>
51 #include <sfx2/tplpitem.hxx>
52 #include <sfx2/sidebar/SidebarChildWindow.hxx>
53 #include <vcl/EnumContext.hxx>
54 #include <sot/formats.hxx>
55 #include <com/sun/star/linguistic2/XThesaurus.hpp>
56 #include <editeng/unolingu.hxx>
57 #include <editeng/outlobj.hxx>
58 #include <svl/cjkoptions.hxx>
59 #include <svtools/cliplistener.hxx>
60 #include <svl/srchitem.hxx>
61 #include <editeng/editobj.hxx>
62 #include <fubullet.hxx>
64 #include <strings.hrc>
66 #include <Window.hxx>
67 #include <drawdoc.hxx>
68 #include <sdresid.hxx>
69 #include <sdpage.hxx>
70 #include <fuoltext.hxx>
71 #include <FrameView.hxx>
72 #include <zoomlist.hxx>
73 #include <stlsheet.hxx>
74 #include <SdUnoOutlineView.hxx>
75 #include <SpellDialogChildWindow.hxx>
77 #include <AccessibleOutlineView.hxx>
78 #include <ViewShellBase.hxx>
79 #include <DrawController.hxx>
80 #include <DrawDocShell.hxx>
81 #include <OutlineView.hxx>
82 #include <framework/FrameworkHelper.hxx>
83 #include <sfx2/devtools/DevelopmentToolChildWindow.hxx>
85 #include <memory>
87 #define ShellClass_OutlineViewShell
88 using namespace sd;
89 #include <sdslots.hxx>
91 using namespace ::com::sun::star;
92 using namespace ::com::sun::star::uno;
93 using namespace ::com::sun::star::linguistic2;
95 namespace sd {
97 #define MIN_ZOOM 10 // minimum zoom factor
98 #define MAX_ZOOM 1000 // maximum zoom factor
101 * Declare SFX-Slotmap and standard interface
103 SFX_IMPL_INTERFACE(OutlineViewShell, SfxShell)
105 void OutlineViewShell::InitInterface_Impl()
107 GetStaticInterface()->RegisterPopupMenu(u"outline"_ustr);
109 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_TOOLS, SfxVisibilityFlags::Standard | SfxVisibilityFlags::FullScreen | SfxVisibilityFlags::Server,
110 ToolbarId::Outline_Toolbox);
111 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION, SfxVisibilityFlags::Standard | SfxVisibilityFlags::Client | SfxVisibilityFlags::Viewer | SfxVisibilityFlags::ReadonlyDoc,
112 ToolbarId::Draw_Viewer_Toolbox);
114 GetStaticInterface()->RegisterChildWindow(SfxInfoBarContainerChild::GetChildWindowId());
115 GetStaticInterface()->RegisterChildWindow(SvxHlinkDlgWrapper::GetChildWindowId());
116 GetStaticInterface()->RegisterChildWindow(::sd::SpellDialogChildWindow::GetChildWindowId());
117 GetStaticInterface()->RegisterChildWindow(SID_SEARCH_DLG);
118 GetStaticInterface()->RegisterChildWindow(sfx2::sidebar::SidebarChildWindow::GetChildWindowId());
119 GetStaticInterface()->RegisterChildWindow(DevelopmentToolChildWindow::GetChildWindowId());
124 * common initialization part of both constructors
126 void OutlineViewShell::Construct()
128 bool bModified = GetDoc()->IsChanged();
130 meShellType = ST_OUTLINE;
131 Size aSize(29700, 21000);
132 Point aWinPos (0, 0);
133 Point aViewOrigin(0, 0);
134 GetActiveWindow()->SetMinZoomAutoCalc(false);
135 GetActiveWindow()->SetMinZoom( MIN_ZOOM );
136 GetActiveWindow()->SetMaxZoom( MAX_ZOOM );
137 InitWindows(aViewOrigin, aSize, aWinPos);
138 pOlView.reset( new OutlineView(*GetDocSh(), GetActiveWindow(), *this) );
139 mpView = pOlView.get(); // Pointer of base class ViewShell
141 SetPool( &GetDoc()->GetPool() );
143 SetZoom(69);
145 // Apply settings of FrameView
146 ReadFrameViewData(mpFrameView);
148 ::Outliner& rOutl = pOlView->GetOutliner();
149 rOutl.SetUpdateLayout(true);
151 if (!bModified)
153 rOutl.ClearModifyFlag();
156 pLastPage = GetActualPage();
158 SetName( u"OutlineViewShell"_ustr );
160 GetActiveWindow()->SetHelpId( HID_SDOUTLINEVIEWSHELL );
163 Reference<drawing::XDrawSubController> OutlineViewShell::CreateSubController()
165 Reference<drawing::XDrawSubController> xSubController;
167 if (IsMainViewShell())
169 // Create uno sub controller for the main view shell.
170 xSubController.set( new SdUnoOutlineView(*this) );
173 return xSubController;
177 * Default constructor, windows must not center themselves automatically
179 OutlineViewShell::OutlineViewShell (
180 SfxViewFrame* /*pFrame*/,
181 ViewShellBase& rViewShellBase,
182 vcl::Window* pParentWindow,
183 FrameView* pFrameViewArgument)
184 : ViewShell(pParentWindow, rViewShellBase),
185 pLastPage( nullptr ),
186 bPastePossible(false),
187 mbInitialized(false)
190 if (pFrameViewArgument != nullptr)
191 mpFrameView = pFrameViewArgument;
192 else
193 mpFrameView = new FrameView(GetDoc());
195 mpFrameView->Connect();
197 Construct();
199 SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::OutlineText));
201 m_StrOldPageName.clear();
203 doShow();
206 OutlineViewShell::~OutlineViewShell()
208 DisposeFunctions();
210 pOlView.reset();
212 mpFrameView->Disconnect();
214 if ( mxClipEvtLstnr.is() )
216 mxClipEvtLstnr->RemoveListener( GetActiveWindow() );
217 mxClipEvtLstnr->ClearCallbackLink(); // prevent callback if another thread is waiting
221 void OutlineViewShell::Shutdown()
223 ViewShell::Shutdown();
225 PrepareClose();
229 * Paint method: the event gets forwarded from pWindow to the Viewshell
230 * and the current function
232 void OutlineViewShell::Paint(const ::tools::Rectangle& rRect, ::sd::Window* pWin)
234 if (pOlView)
236 pOlView->Paint(rRect, pWin);
240 void OutlineViewShell::ArrangeGUIElements ()
242 // Retrieve the current size (thickness) of the scroll bars. That is
243 // the width of the vertical and the height of the horizontal scroll
244 // bar.
245 int nScrollBarSize =
246 GetParentWindow()->GetSettings().GetStyleSettings().GetScrollBarSize();
247 maScrBarWH = Size (nScrollBarSize, nScrollBarSize);
249 ViewShell::ArrangeGUIElements ();
251 ::sd::Window* pWindow = mpContentWindow.get();
252 if (pWindow == nullptr)
253 return;
255 pWindow->SetMinZoomAutoCalc(false);
257 // change OutputArea of the OutlinerView
258 OutlinerView* pOutlinerView = pOlView->GetViewByWindow(pWindow);
260 ::tools::Rectangle aWin(Point(0,0), pWindow->GetOutputSizePixel());
262 aWin = pWindow->PixelToLogic(aWin);
263 pOutlinerView->SetOutputArea(aWin);
265 ::tools::Rectangle aVis = pOutlinerView->GetVisArea();
267 ::tools::Rectangle aText(Point(0,0),
268 Size(pOlView->GetPaperWidth(),
269 pOlView->GetOutliner().GetTextHeight()));
270 if (aWin.GetHeight() > aText.Bottom())
271 aText.SetBottom( aWin.GetHeight() );
273 if (!aWin.IsEmpty()) // not when opening
275 InitWindows(Point(0,0), aText.GetSize(), aVis.TopLeft());
276 UpdateScrollBars();
281 * Handle SfxRequest for the Controller
283 void OutlineViewShell::ExecCtrl(SfxRequest &rReq)
285 sal_uInt16 nSlot = rReq.GetSlot();
286 switch ( nSlot )
288 case SID_MAIL_SCROLLBODY_PAGEDOWN:
290 ExecReq( rReq );
291 break;
294 case SID_OPT_LOCALE_CHANGED:
296 pOlView->GetOutliner().UpdateFields();
297 UpdatePreview( GetActualPage() );
298 rReq.Done();
299 break;
302 default:
303 break;
308 * Activate(): during the first invocation the fields get updated
310 void OutlineViewShell::Activate( bool bIsMDIActivate )
312 if ( ! mbInitialized)
314 mbInitialized = true;
315 SfxRequest aRequest (SID_EDIT_OUTLINER, SfxCallMode::SLOT, GetDoc()->GetItemPool());
316 FuPermanent (aRequest);
319 ViewShell::Activate( bIsMDIActivate );
320 BroadcastContextForActivation(true);
322 pOlView->SetLinks();
323 pOlView->ConnectToApplication();
325 if( bIsMDIActivate )
327 OutlinerView* pOutlinerView = pOlView->GetViewByWindow( GetActiveWindow() );
328 ::Outliner* pOutl = pOutlinerView->GetOutliner();
329 pOutl->UpdateFields();
333 void OutlineViewShell::Deactivate( bool bIsMDIActivate )
335 pOlView->DisconnectFromApplication();
337 // Links must be kept also on deactivated viewshell, to allow drag'n'drop
338 // to function properly
339 ViewShell::Deactivate( bIsMDIActivate );
343 * Set status of Controller-SfxSlots
345 void OutlineViewShell::GetCtrlState(SfxItemSet &rSet)
347 if (SfxItemState::DEFAULT == rSet.GetItemState(SID_HYPERLINK_GETLINK))
349 SvxHyperlinkItem aHLinkItem;
351 OutlinerView* pOLV = pOlView->GetViewByWindow(GetActiveWindow());
352 if (pOLV)
354 const SvxFieldItem* pFieldItem = pOLV->GetFieldAtSelection();
355 if (pFieldItem)
357 ESelection aSel = pOLV->GetSelection();
358 if (abs(aSel.end.nIndex - aSel.start.nIndex) == 1)
360 const SvxFieldData* pField = pFieldItem->GetField();
361 if ( auto pUrlField = dynamic_cast< const SvxURLField *>( pField ) )
363 aHLinkItem.SetName(pUrlField->GetRepresentation());
364 aHLinkItem.SetURL(pUrlField->GetURL());
365 aHLinkItem.SetTargetFrame(pUrlField->GetTargetFrame());
370 rSet.Put(aHLinkItem);
372 rSet.Put( SfxBoolItem( SID_READONLY_MODE, GetDocSh()->IsReadOnly() ) );
374 if ( SfxItemState::DEFAULT == rSet.GetItemState(SID_MAIL_SCROLLBODY_PAGEDOWN) )
375 rSet.Put( SfxBoolItem( SID_MAIL_SCROLLBODY_PAGEDOWN, true ) );
377 if ( !(SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_HALFWIDTH) ||
378 SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_FULLWIDTH) ||
379 SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_HIRAGANA) ||
380 SfxItemState::DEFAULT == rSet.GetItemState(SID_TRANSLITERATE_KATAKANA)) )
381 return;
383 if( !SvtCJKOptions::IsChangeCaseMapEnabled() )
385 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_HALFWIDTH, false );
386 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_FULLWIDTH, false );
387 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_HIRAGANA, false );
388 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_KATAKANA, false );
389 rSet.DisableItem( SID_TRANSLITERATE_HALFWIDTH );
390 rSet.DisableItem( SID_TRANSLITERATE_FULLWIDTH );
391 rSet.DisableItem( SID_TRANSLITERATE_HIRAGANA );
392 rSet.DisableItem( SID_TRANSLITERATE_KATAKANA );
394 else
396 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_HALFWIDTH, true );
397 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_FULLWIDTH, true );
398 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_HIRAGANA, true );
399 GetViewFrame()->GetBindings().SetVisibleState( SID_TRANSLITERATE_KATAKANA, true );
404 * SfxRequests for support functions
406 void OutlineViewShell::FuSupport(SfxRequest &rReq)
408 if( rReq.GetSlot() == SID_STYLE_FAMILY && rReq.GetArgs())
409 GetDocSh()->SetStyleFamily(static_cast<SfxStyleFamily>(rReq.GetArgs()->Get( SID_STYLE_FAMILY ).GetValue()));
411 bool bPreviewState = false;
412 sal_uInt16 nSlot = rReq.GetSlot();
414 std::unique_ptr<OutlineViewModelChangeGuard, o3tl::default_delete<OutlineViewModelChangeGuard>> aGuard;
415 if( pOlView && (
416 (nSlot == SID_TRANSLITERATE_SENTENCE_CASE) ||
417 (nSlot == SID_TRANSLITERATE_TITLE_CASE) ||
418 (nSlot == SID_TRANSLITERATE_TOGGLE_CASE) ||
419 (nSlot == SID_TRANSLITERATE_UPPER) ||
420 (nSlot == SID_TRANSLITERATE_LOWER) ||
421 (nSlot == SID_TRANSLITERATE_HALFWIDTH) ||
422 (nSlot == SID_TRANSLITERATE_FULLWIDTH) ||
423 (nSlot == SID_TRANSLITERATE_HIRAGANA) ||
424 (nSlot == SID_TRANSLITERATE_KATAKANA) ||
425 (nSlot == SID_CUT) ||
426 (nSlot == SID_PASTE) ||
427 (nSlot == SID_PASTE_UNFORMATTED) ||
428 (nSlot == SID_DELETE)))
430 aGuard.reset( new OutlineViewModelChangeGuard( *pOlView ) );
433 switch ( nSlot )
435 case SID_CUT:
437 if(HasCurrentFunction())
439 GetCurrentFunction()->DoCut();
441 else if (pOlView)
443 pOlView->DoCut();
445 rReq.Done();
446 bPreviewState = true;
448 break;
450 case SID_COPY:
452 if(HasCurrentFunction())
454 GetCurrentFunction()->DoCopy();
456 else if (pOlView)
458 pOlView->DoCopy();
460 rReq.Done();
461 bPreviewState = true;
463 break;
465 case SID_PASTE:
467 OutlineViewPageChangesGuard aGuard2(pOlView.get());
469 if(HasCurrentFunction())
471 GetCurrentFunction()->DoPaste();
473 else if (pOlView)
475 pOlView->DoPaste();
477 rReq.Done();
478 bPreviewState = true;
480 break;
482 case SID_PASTE_UNFORMATTED:
484 OutlineViewPageChangesGuard aGuard2(pOlView.get());
486 if(HasCurrentFunction())
488 GetCurrentFunction()->DoPasteUnformatted();
490 else if(pOlView)
492 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( GetActiveWindow() ) );
493 if (aDataHelper.GetTransferable().is())
495 sal_Int8 nAction = DND_ACTION_COPY;
496 pOlView->InsertData( aDataHelper,
497 GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(), GetActiveWindow()->GetOutputSizePixel() ).Center() ),
498 nAction, false, SotClipboardFormatId::STRING);
502 rReq.Ignore ();
504 break;
505 case SID_DELETE:
507 if( pOlView )
509 OutlinerView* pOutlView = pOlView->GetViewByWindow(GetActiveWindow());
510 if (pOutlView)
512 OutlineViewPageChangesGuard aGuard2(pOlView.get());
514 vcl::KeyCode aKCode(KEY_DELETE);
515 KeyEvent aKEvt( 0, aKCode );
516 pOutlView->PostKeyEvent(aKEvt);
518 rtl::Reference<FuPoor> xFunc( GetCurrentFunction() );
519 FuOutlineText* pFuOutlineText = dynamic_cast< FuOutlineText* >( xFunc.get() );
520 if( pFuOutlineText )
521 pFuOutlineText->UpdateForKeyPress (aKEvt);
524 rReq.Done();
525 bPreviewState = true;
527 break;
529 case SID_DRAWINGMODE:
530 case SID_SLIDE_MASTER_MODE:
531 case SID_NOTES_MODE:
532 case SID_NOTES_MASTER_MODE:
533 case SID_HANDOUT_MASTER_MODE:
534 case SID_SLIDE_SORTER_MODE:
535 case SID_OUTLINE_MODE:
536 framework::FrameworkHelper::Instance(GetViewShellBase())->HandleModeChangeSlot(
537 nSlot,
538 rReq);
539 rReq.Done();
540 break;
542 case SID_RULER:
543 SetRuler( !HasRuler() );
544 Invalidate( SID_RULER );
545 rReq.Done();
546 break;
548 case SID_ZOOM_PREV:
550 if (mpZoomList->IsPreviousPossible())
552 SetZoomRect(mpZoomList->GetPreviousZoomRect());
554 rReq.Done ();
556 break;
558 case SID_ZOOM_NEXT:
560 if (mpZoomList->IsNextPossible())
562 SetZoomRect(mpZoomList->GetNextZoomRect());
564 rReq.Done ();
566 break;
568 case SID_AUTOSPELL_CHECK:
570 GetDoc()->SetOnlineSpell(!GetDoc()->GetOnlineSpell());
571 rReq.Done ();
573 break;
575 case SID_TRANSLITERATE_SENTENCE_CASE:
576 case SID_TRANSLITERATE_TITLE_CASE:
577 case SID_TRANSLITERATE_TOGGLE_CASE:
578 case SID_TRANSLITERATE_UPPER:
579 case SID_TRANSLITERATE_LOWER:
580 case SID_TRANSLITERATE_HALFWIDTH:
581 case SID_TRANSLITERATE_FULLWIDTH:
582 case SID_TRANSLITERATE_HIRAGANA:
583 case SID_TRANSLITERATE_KATAKANA:
585 OutlinerView* pOLV = pOlView ? pOlView->GetViewByWindow( GetActiveWindow() ) : nullptr;
586 if( pOLV )
588 TransliterationFlags nType = TransliterationFlags::NONE;
590 switch( nSlot )
592 case SID_TRANSLITERATE_SENTENCE_CASE:
593 nType = TransliterationFlags::SENTENCE_CASE;
594 break;
595 case SID_TRANSLITERATE_TITLE_CASE:
596 nType = TransliterationFlags::TITLE_CASE;
597 break;
598 case SID_TRANSLITERATE_TOGGLE_CASE:
599 nType = TransliterationFlags::TOGGLE_CASE;
600 break;
601 case SID_TRANSLITERATE_UPPER:
602 nType = TransliterationFlags::LOWERCASE_UPPERCASE;
603 break;
604 case SID_TRANSLITERATE_LOWER:
605 nType = TransliterationFlags::UPPERCASE_LOWERCASE;
606 break;
607 case SID_TRANSLITERATE_HALFWIDTH:
608 nType = TransliterationFlags::FULLWIDTH_HALFWIDTH;
609 break;
610 case SID_TRANSLITERATE_FULLWIDTH:
611 nType = TransliterationFlags::HALFWIDTH_FULLWIDTH;
612 break;
613 case SID_TRANSLITERATE_HIRAGANA:
614 nType = TransliterationFlags::KATAKANA_HIRAGANA;
615 break;
616 case SID_TRANSLITERATE_KATAKANA:
617 nType = TransliterationFlags::HIRAGANA_KATAKANA;
618 break;
621 pOLV->TransliterateText( nType );
624 rReq.Done();
625 bPreviewState = true;
627 break;
629 // added Undo/Redo handling
630 case SID_UNDO :
632 OutlineViewPageChangesGuard aGuard2(pOlView.get());
633 ImpSidUndo(rReq);
635 break;
636 case SID_REDO :
638 OutlineViewPageChangesGuard aGuard2(pOlView.get());
639 ImpSidRedo(rReq);
641 break;
643 default:
644 break;
647 if( bPreviewState )
648 Invalidate( SID_PREVIEW_STATE );
650 Invalidate(SID_CUT);
651 Invalidate(SID_COPY);
652 Invalidate(SID_PASTE);
656 * SfxRequests for permanent functions
658 void OutlineViewShell::FuPermanent(SfxRequest &rReq)
660 if(HasCurrentFunction())
662 DeactivateCurrentFunction(true);
665 switch ( rReq.GetSlot() )
667 case SID_EDIT_OUTLINER:
669 ::Outliner& rOutl = pOlView->GetOutliner();
670 rOutl.GetUndoManager().Clear();
671 rOutl.UpdateFields();
673 SetCurrentFunction( FuOutlineText::Create(this,GetActiveWindow(),pOlView.get(),GetDoc(),rReq) );
675 rReq.Done();
677 break;
679 default:
680 break;
683 if(HasOldFunction())
685 GetOldFunction()->Deactivate();
686 SetOldFunction(nullptr);
689 if(HasCurrentFunction())
691 GetCurrentFunction()->Activate();
692 SetOldFunction(GetCurrentFunction());
696 IMPL_LINK( OutlineViewShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void )
698 bPastePossible = pDataHelper->GetFormatCount() != 0 &&
699 ( pDataHelper->HasFormat( SotClipboardFormatId::STRING ) ||
700 pDataHelper->HasFormat( SotClipboardFormatId::RTF ) ||
701 pDataHelper->HasFormat( SotClipboardFormatId::RICHTEXT ) ||
702 pDataHelper->HasFormat( SotClipboardFormatId::HTML ) );
704 SfxBindings& rBindings = GetViewFrame()->GetBindings();
705 rBindings.Invalidate( SID_PASTE );
706 rBindings.Invalidate( SID_PASTE_SPECIAL );
707 rBindings.Invalidate( SID_PASTE_UNFORMATTED );
708 rBindings.Invalidate( SID_CLIPBOARD_FORMAT_ITEMS );
712 * Set Status (Enabled/Disabled) of Menu-SfxSlots
714 void OutlineViewShell::GetMenuState( SfxItemSet &rSet )
716 ViewShell::GetMenuState(rSet);
718 rSet.Put(SfxBoolItem(SID_SLIDE_SORTER_MODE, false));
719 rSet.Put(SfxBoolItem(SID_DRAWINGMODE, false));
720 rSet.Put(SfxBoolItem(SID_SLIDE_MASTER_MODE, false));
721 rSet.Put(SfxBoolItem(SID_OUTLINE_MODE, true));
722 rSet.Put(SfxBoolItem(SID_NOTES_MODE, false));
723 rSet.Put(SfxBoolItem(SID_NOTES_MASTER_MODE, false));
724 rSet.Put(SfxBoolItem(SID_HANDOUT_MASTER_MODE, false));
726 if (!mpZoomList->IsNextPossible())
728 rSet.DisableItem(SID_ZOOM_NEXT);
730 if (!mpZoomList->IsPreviousPossible())
732 rSet.DisableItem(SID_ZOOM_PREV);
735 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ZOOM_IN ) ||
736 SfxItemState::DEFAULT == rSet.GetItemState( SID_ZOOM_OUT ) )
738 if( GetActiveWindow()->GetZoom() <= GetActiveWindow()->GetMinZoom() || GetDocSh()->IsUIActive() )
739 rSet.DisableItem( SID_ZOOM_OUT );
740 if( GetActiveWindow()->GetZoom() >= GetActiveWindow()->GetMaxZoom() || GetDocSh()->IsUIActive() )
741 rSet.DisableItem( SID_ZOOM_IN );
744 ::Outliner& rOutl = pOlView->GetOutliner();
746 // allow 'Select All'?
747 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_SELECTALL ) )
749 sal_Int32 nParaCount = rOutl.GetParagraphCount();
750 bool bDisable = nParaCount == 0;
751 if (!bDisable && nParaCount == 1)
753 OUString aTest = rOutl.GetText(rOutl.GetParagraph(0));
754 if (aTest.isEmpty())
756 bDisable = true;
759 if (bDisable)
760 rSet.DisableItem(SID_SELECTALL);
763 // set status of Ruler
764 rSet.Put( SfxBoolItem( SID_RULER, HasRuler() ) );
766 // Enable formatting?
767 rSet.Put( SfxBoolItem( SID_OUTLINE_FORMAT, !rOutl.IsFlatMode() ) );
769 if( rOutl.IsFlatMode() )
770 rSet.DisableItem( SID_COLORVIEW );
771 else
773 // Enable color view?
774 EEControlBits nCntrl = rOutl.GetControlWord();
775 bool bNoColor = false;
776 if (nCntrl & EEControlBits::NOCOLORS)
777 bNoColor = true;
779 rSet.Put( SfxBoolItem( SID_COLORVIEW, bNoColor ) );
782 // Buttons of toolbar
783 // first the selection dependent ones: COLLAPSE, EXPAND
784 bool bDisableCollapse = true;
785 bool bDisableExpand = true;
786 bool bUnique = true;
787 OutlinerView* pOutlinerView = pOlView->GetViewByWindow(GetActiveWindow());
789 std::vector<Paragraph*> aSelList;
790 pOutlinerView->CreateSelectionList(aSelList);
792 if (!aSelList.empty())
794 sal_Int16 nTmpDepth = rOutl.GetDepth( rOutl.GetAbsPos( aSelList.front() ) );
795 bool bPage = ::Outliner::HasParaFlag( aSelList.front(), ParaFlag::ISPAGE );
797 for (const Paragraph* pPara : aSelList)
799 sal_Int16 nDepth = rOutl.GetDepth( rOutl.GetAbsPos( pPara ) );
801 if( nDepth != nTmpDepth || bPage != ::Outliner::HasParaFlag( pPara, ParaFlag::ISPAGE ))
802 bUnique = false;
804 if (rOutl.HasChildren(pPara))
806 if (!rOutl.IsExpanded(pPara))
807 bDisableExpand = false;
808 else
809 bDisableCollapse = false;
814 if (bDisableExpand)
815 rSet.DisableItem(SID_OUTLINE_EXPAND);
816 if (bDisableCollapse)
817 rSet.DisableItem(SID_OUTLINE_COLLAPSE);
819 // does the selection provide a unique presentation layout?
820 // if not, the templates must not be edited
821 SfxItemSetFixed<SID_STATUS_LAYOUT, SID_STATUS_LAYOUT> aSet(*rSet.GetPool());
822 GetStatusBarState(aSet);
823 OUString aTest = aSet.Get(SID_STATUS_LAYOUT).GetValue();
824 if (aTest.isEmpty())
826 bUnique = false;
829 if (!bUnique)
830 rSet.DisableItem( SID_PRESENTATIONOBJECT );
832 // now the selection independent ones: COLLAPSE_ALL, EXPAND_ALL
833 bool bDisableCollapseAll = true;
834 bool bDisableExpandAll = true;
836 // does the selection contain something collapsible/expandable?
837 if (!bDisableCollapse)
838 bDisableCollapseAll = false;
839 if (!bDisableExpand)
840 bDisableExpandAll = false;
842 // otherwise look through all paragraphs
843 if (bDisableCollapseAll || bDisableExpandAll)
845 sal_Int32 nParaPos = 0;
846 Paragraph* pPara = rOutl.GetParagraph( nParaPos );
847 while (pPara && (bDisableCollapseAll || bDisableExpandAll))
849 if (!rOutl.IsExpanded(pPara) && rOutl.HasChildren(pPara))
850 bDisableExpandAll = false;
852 if (rOutl.IsExpanded(pPara) && rOutl.HasChildren(pPara))
853 bDisableCollapseAll = false;
855 pPara = rOutl.GetParagraph( ++nParaPos );
859 if (bDisableExpandAll)
860 rSet.DisableItem(SID_OUTLINE_EXPAND_ALL);
861 if (bDisableCollapseAll)
862 rSet.DisableItem(SID_OUTLINE_COLLAPSE_ALL);
864 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_PASTE ) )
866 if ( !mxClipEvtLstnr.is() )
868 // create listener
869 mxClipEvtLstnr = new TransferableClipboardListener( LINK( this, OutlineViewShell, ClipboardChanged ) );
870 mxClipEvtLstnr->AddListener( GetActiveWindow() );
872 // get initial state
873 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( GetActiveWindow() ) );
874 bPastePossible = ( aDataHelper.GetFormatCount() != 0 &&
875 ( aDataHelper.HasFormat( SotClipboardFormatId::STRING ) ||
876 aDataHelper.HasFormat( SotClipboardFormatId::RTF ) ||
877 aDataHelper.HasFormat( SotClipboardFormatId::RICHTEXT ) ||
878 aDataHelper.HasFormat( SotClipboardFormatId::HTML ) ) );
881 if( !bPastePossible )
883 rSet.DisableItem( SID_PASTE );
887 if (!pOlView->GetViewByWindow(GetActiveWindow())->HasSelection()
888 || GetObjectShell()->isContentExtractionLocked())
890 rSet.DisableItem(SID_CUT);
891 rSet.DisableItem(SID_COPY);
894 if (pOlView->GetOutliner().IsModified())
896 GetDoc()->SetChanged();
899 // the status has to be set here because of overriding
900 if( !GetDocSh()->IsModified() )
902 rSet.DisableItem( SID_SAVEDOC );
905 if ( GetDocSh()->IsReadOnly() )
907 rSet.DisableItem( SID_AUTOSPELL_CHECK );
909 else
911 if (GetDoc()->GetOnlineSpell())
913 rSet.Put(SfxBoolItem(SID_AUTOSPELL_CHECK, true));
915 else
917 rSet.Put(SfxBoolItem(SID_AUTOSPELL_CHECK, false));
921 // field commands
922 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_MODIFY_FIELD ) )
924 const SvxFieldItem* pFldItem = pOutlinerView->GetFieldAtSelection();
926 if( !( pFldItem && (nullptr != dynamic_cast< const SvxDateField *>( pFldItem->GetField() ) ||
927 nullptr != dynamic_cast< const SvxAuthorField *>( pFldItem->GetField() ) ||
928 nullptr != dynamic_cast< const SvxExtFileField *>( pFldItem->GetField() ) ||
929 nullptr != dynamic_cast< const SvxExtTimeField *>( pFldItem->GetField() ) ) ) )
931 rSet.DisableItem( SID_MODIFY_FIELD );
935 if (SfxItemState::DEFAULT == rSet.GetItemState(SID_EXPAND_PAGE))
937 bool bDisable = true;
938 sal_uInt16 i = 0;
939 sal_uInt16 nCount = GetDoc()->GetSdPageCount(PageKind::Standard);
940 pOlView->SetSelectedPages();
942 while (i < nCount && bDisable)
944 SdPage* pPage = GetDoc()->GetSdPage(i, PageKind::Standard);
946 if (pPage->IsSelected())
948 SdrObject* pObj = pPage->GetPresObj(PresObjKind::Outline);
950 if (pObj!=nullptr )
952 if( !pObj->IsEmptyPresObj() )
954 bDisable = false;
956 else
958 // check if the object is in edit, then if it's temporarily not empty
959 SdrTextObj* pTextObj = DynCastSdrTextObj( pObj );
960 if( pTextObj )
962 if( pTextObj->CanCreateEditOutlinerParaObject() )
964 bDisable = false;
971 i++;
974 if (bDisable)
976 rSet.DisableItem(SID_EXPAND_PAGE);
980 if (SfxItemState::DEFAULT == rSet.GetItemState(SID_SUMMARY_PAGE))
982 bool bDisable = true;
983 sal_uInt16 i = 0;
984 sal_uInt16 nCount = GetDoc()->GetSdPageCount(PageKind::Standard);
985 pOlView->SetSelectedPages();
987 while (i < nCount && bDisable)
989 SdPage* pPage = GetDoc()->GetSdPage(i, PageKind::Standard);
991 if (pPage->IsSelected())
993 SdrObject* pObj = pPage->GetPresObj(PresObjKind::Title);
995 if (pObj && !pObj->IsEmptyPresObj())
997 bDisable = false;
1001 i++;
1004 if (bDisable)
1006 rSet.DisableItem(SID_SUMMARY_PAGE);
1010 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_THESAURUS ) )
1012 if ( !pOlView->IsTextEdit() )
1014 rSet.DisableItem( SID_THESAURUS );
1016 else
1018 LanguageType eLang = GetDoc()->GetLanguage( EE_CHAR_LANGUAGE );
1019 Reference< XThesaurus > xThesaurus( LinguMgr::GetThesaurus() );
1021 if (!xThesaurus.is() || eLang == LANGUAGE_NONE || !xThesaurus->hasLocale( LanguageTag::convertToLocale( eLang)))
1022 rSet.DisableItem( SID_THESAURUS );
1026 // is starting the presentation possible?
1027 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_PRESENTATION ) )
1029 bool bDisable = true;
1030 sal_uInt16 nCount = GetDoc()->GetSdPageCount( PageKind::Standard );
1032 for( sal_uInt16 i = 0; i < nCount && bDisable; i++ )
1034 SdPage* pPage = GetDoc()->GetSdPage(i, PageKind::Standard);
1036 if( !pPage->IsExcluded() )
1037 bDisable = false;
1039 if( bDisable || GetDocSh()->IsPreview())
1041 rSet.DisableItem( SID_PRESENTATION );
1045 FuBullet::GetSlotState( rSet, this, GetViewFrame() );
1050 * gets invoked when ScrollBar is used
1052 void OutlineViewShell::VirtHScrollHdl(ScrollAdaptor* pHScroll)
1054 ::tools::Long nThumb = pHScroll->GetThumbPos();
1055 ::tools::Long nRange = pHScroll->GetRange().Len();
1056 double fX = static_cast<double>(nThumb) / nRange;
1058 Window* pWin = mpContentWindow.get();
1059 OutlinerView* pOutlinerView = pOlView->GetViewByWindow(pWin);
1060 ::tools::Long nViewWidth = pWin->PixelToLogic(
1061 pWin->GetSizePixel()).Width();
1062 ::tools::Long nTextWidth = pOlView->GetPaperWidth();
1063 nViewWidth = std::max(nViewWidth, nTextWidth);
1064 ::tools::Long nCurrentPos = pOutlinerView->GetVisArea().Left();
1065 ::tools::Long nTargetPos = static_cast<::tools::Long>(fX * nViewWidth);
1066 ::tools::Long nDelta = nTargetPos - nCurrentPos;
1068 pOutlinerView->HideCursor();
1069 pOutlinerView->Scroll(-nDelta, 0);
1070 pOutlinerView->ShowCursor(false);
1073 void OutlineViewShell::VirtVScrollHdl(ScrollAdaptor* pVScroll)
1075 ::tools::Long nThumb = pVScroll->GetThumbPos();
1076 ::tools::Long nRange = pVScroll->GetRange().Len();
1077 double fY = static_cast<double>(nThumb) / nRange;
1079 Window* pWin = mpContentWindow.get();
1080 OutlinerView* pOutlinerView = pOlView->GetViewByWindow(pWin);
1081 ::tools::Long nViewHeight = pWin->PixelToLogic(
1082 pWin->GetSizePixel()).Height();
1083 ::tools::Long nTextHeight = pOlView->GetOutliner().GetTextHeight();
1084 nViewHeight += nTextHeight;
1085 ::tools::Long nCurrentPos = pOutlinerView->GetVisArea().Top();
1086 ::tools::Long nTargetPos = static_cast<::tools::Long>(fY * nViewHeight);
1087 ::tools::Long nDelta = nTargetPos - nCurrentPos;
1089 pOutlinerView->HideCursor();
1090 pOutlinerView->Scroll(0, -nDelta);
1091 pOutlinerView->ShowCursor(false);
1095 * PrepareClose, gets called when the Shell shall be destroyed.
1096 * Forwards the invocation to the View
1098 bool OutlineViewShell::PrepareClose( bool bUI )
1100 if( !ViewShell::PrepareClose(bUI) )
1101 return false;
1103 if (pOlView)
1104 pOlView->PrepareClose();
1105 return true;
1109 * Zoom with zoom factor. Inform OutlinerView
1111 void OutlineViewShell::SetZoom(::tools::Long nZoom)
1113 ViewShell::SetZoom(nZoom);
1115 ::sd::Window* pWindow = mpContentWindow.get();
1116 if (pWindow)
1118 // change OutputArea of OutlinerView
1119 OutlinerView* pOutlinerView = pOlView->GetViewByWindow(pWindow);
1120 ::tools::Rectangle aWin(Point(0,0), pWindow->GetOutputSizePixel());
1121 aWin = pWindow->PixelToLogic(aWin);
1122 pOutlinerView->SetOutputArea(aWin);
1125 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
1126 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1130 * Zoom with zoom rectangle. Inform OutlinerView
1132 void OutlineViewShell::SetZoomRect(const ::tools::Rectangle& rZoomRect)
1134 ViewShell::SetZoomRect(rZoomRect);
1136 ::sd::Window* pWindow = mpContentWindow.get();
1137 if (pWindow)
1139 // change OutputArea of OutlinerView
1140 OutlinerView* pOutlinerView = pOlView->GetViewByWindow(pWindow);
1141 ::tools::Rectangle aWin(Point(0,0), pWindow->GetOutputSizePixel());
1142 aWin = pWindow->PixelToLogic(aWin);
1143 pOutlinerView->SetOutputArea(aWin);
1146 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
1147 GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1151 * Before saving: Update Model of the Drawing Engine, then forward the
1152 * invocation to the ObjectShell.
1154 void OutlineViewShell::Execute(SfxRequest& rReq)
1156 bool bForwardCall = true;
1158 switch(rReq.GetSlot())
1160 case SID_SAVEDOC:
1161 case SID_SAVEASDOC:
1162 PrepareClose();
1163 break;
1165 case SID_SEARCH_ITEM:
1166 // Forward this request to the common (old) code of the
1167 // document shell.
1168 GetDocSh()->Execute (rReq);
1169 bForwardCall = false;
1170 break;
1172 case SID_SPELL_DIALOG:
1174 SfxViewFrame* pViewFrame = GetViewFrame();
1175 if (rReq.GetArgs() != nullptr)
1176 pViewFrame->SetChildWindow (SID_SPELL_DIALOG,
1177 static_cast<const SfxBoolItem&>(rReq.GetArgs()->
1178 Get(SID_SPELL_DIALOG)).GetValue());
1179 else
1180 pViewFrame->ToggleChildWindow(SID_SPELL_DIALOG);
1182 pViewFrame->GetBindings().Invalidate(SID_SPELL_DIALOG);
1183 rReq.Done ();
1185 bForwardCall = false;
1187 break;
1189 default:
1190 SAL_WARN("sd", "OutlineViewShell::Execute(): can not handle slot " << rReq.GetSlot());
1191 break;
1195 if (bForwardCall)
1196 static_cast<DrawDocShell*>(GetViewFrame()->GetObjectShell())->ExecuteSlot( rReq );
1200 * Read FrameViews data and set actual views data
1202 void OutlineViewShell::ReadFrameViewData(FrameView* pView)
1204 ::Outliner& rOutl = pOlView->GetOutliner();
1206 rOutl.SetFlatMode( pView->IsNoAttribs() );
1208 EEControlBits nCntrl = rOutl.GetControlWord();
1210 if ( pView->IsNoColors() )
1211 rOutl.SetControlWord(nCntrl | EEControlBits::NOCOLORS);
1212 else
1213 rOutl.SetControlWord(nCntrl & ~EEControlBits::NOCOLORS);
1215 sal_uInt16 nPage = mpFrameView->GetSelectedPage();
1216 pLastPage = GetDoc()->GetSdPage( nPage, PageKind::Standard );
1217 pOlView->SetActualPage(pLastPage);
1221 * Write actual views data to FrameView
1223 void OutlineViewShell::WriteFrameViewData()
1225 ::Outliner& rOutl = pOlView->GetOutliner();
1227 EEControlBits nCntrl = rOutl.GetControlWord();
1228 bool bNoColor = false;
1229 if (nCntrl & EEControlBits::NOCOLORS)
1230 bNoColor = true;
1231 mpFrameView->SetNoColors(bNoColor);
1232 mpFrameView->SetNoAttribs( rOutl.IsFlatMode() );
1233 SdPage* pActualPage = pOlView->GetActualPage();
1234 DBG_ASSERT(pActualPage, "No current page");
1235 if( pActualPage )
1236 mpFrameView->SetSelectedPage((pActualPage->GetPageNum() - 1) / 2);
1240 * Handle SfxRequests for the StatusBar
1242 void OutlineViewShell::ExecStatusBar(SfxRequest&)
1246 void OutlineViewShell::GetStatusBarState(SfxItemSet& rSet)
1248 // Zoom-Item
1249 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOM ) )
1251 sal_uInt16 nZoom = static_cast<sal_uInt16>(GetActiveWindow()->GetZoom());
1253 std::unique_ptr<SvxZoomItem> pZoomItem(new SvxZoomItem( SvxZoomType::PERCENT, nZoom ));
1255 // limit area
1256 SvxZoomEnableFlags nZoomValues = SvxZoomEnableFlags::ALL;
1257 nZoomValues &= ~SvxZoomEnableFlags::OPTIMAL;
1258 nZoomValues &= ~SvxZoomEnableFlags::WHOLEPAGE;
1259 nZoomValues &= ~SvxZoomEnableFlags::PAGEWIDTH;
1261 pZoomItem->SetValueSet( nZoomValues );
1262 rSet.Put( std::move(pZoomItem) );
1265 if( SfxItemState::DEFAULT == rSet.GetItemState( SID_ATTR_ZOOMSLIDER ) )
1267 if (GetDocSh()->IsUIActive() || !GetActiveWindow() )
1269 rSet.DisableItem( SID_ATTR_ZOOMSLIDER );
1271 else
1273 sd::Window * pActiveWindow = GetActiveWindow();
1274 SvxZoomSliderItem aZoomItem( static_cast<sal_uInt16>(pActiveWindow->GetZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMinZoom()), static_cast<sal_uInt16>(pActiveWindow->GetMaxZoom()) ) ;
1275 aZoomItem.AddSnappingPoint(100);
1276 rSet.Put( aZoomItem );
1280 // page view and layout
1282 sal_uInt16 nPageCount = GetDoc()->GetSdPageCount( PageKind::Standard );
1283 OUString aPageStr, aLayoutStr;
1285 ::sd::Window* pWin = GetActiveWindow();
1286 OutlinerView* pActiveView = pOlView->GetViewByWindow( pWin );
1288 std::vector<Paragraph*> aSelList;
1289 pActiveView->CreateSelectionList(aSelList);
1291 Paragraph *pFirstPara = nullptr;
1292 Paragraph *pLastPara = nullptr;
1294 if (!aSelList.empty())
1296 pFirstPara = *(aSelList.begin());
1297 pLastPara = *(aSelList.rbegin());
1300 if( !::Outliner::HasParaFlag(pFirstPara,ParaFlag::ISPAGE) )
1301 pFirstPara = pOlView->GetPrevTitle( pFirstPara );
1303 if( !::Outliner::HasParaFlag(pLastPara, ParaFlag::ISPAGE) )
1304 pLastPara = pOlView->GetPrevTitle( pLastPara );
1306 // only one page selected?
1307 if( pFirstPara == pLastPara )
1309 // how many pages are we before the selected page?
1310 sal_uLong nPos = 0;
1311 while( pFirstPara )
1313 pFirstPara = pOlView->GetPrevTitle( pFirstPara );
1314 if( pFirstPara )
1315 nPos++;
1318 if( nPos >= GetDoc()->GetSdPageCount( PageKind::Standard ) )
1319 nPos = 0;
1321 SdPage* pPage = GetDoc()->GetSdPage( static_cast<sal_uInt16>(nPos), PageKind::Standard );
1323 if (GetDoc()->GetDocumentType() == DocumentType::Draw)
1324 aPageStr = SdResId(STR_SD_PAGE_COUNT_DRAW);
1325 else
1326 aPageStr = SdResId(STR_SD_PAGE_COUNT);
1328 aPageStr = aPageStr.replaceFirst("%1", OUString::number(static_cast<sal_Int32>(nPos + 1)));
1329 aPageStr = aPageStr.replaceFirst("%2", OUString::number(nPageCount));
1331 aLayoutStr = pPage->GetLayoutName();
1332 sal_Int32 nIndex = aLayoutStr.indexOf(SD_LT_SEPARATOR);
1333 if (nIndex != -1)
1334 aLayoutStr = aLayoutStr.copy(0, nIndex);
1335 //Now, CurrentPage property change is already sent for DrawView and OutlineView, so it is not necessary to send again here
1336 if(m_StrOldPageName!=aPageStr)
1338 GetViewShellBase().GetDrawController()->fireSwitchCurrentPage(nPos);
1339 m_StrOldPageName = aPageStr;
1342 rSet.Put( SfxStringItem( SID_STATUS_PAGE, aPageStr ) );
1343 rSet.Put( SfxStringItem( SID_STATUS_LAYOUT, aLayoutStr ) );
1346 void OutlineViewShell::Command( const CommandEvent& rCEvt, ::sd::Window* pWin )
1348 if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
1350 GetActiveWindow()->ReleaseMouse();
1352 OutlinerView* pOLV = pOlView->GetViewByWindow(GetActiveWindow());
1353 Point aPos(rCEvt.GetMousePosPixel());
1355 if (pOLV && pOLV->IsWrongSpelledWordAtPos(aPos))
1357 // Popup for Online-Spelling now handled by DrawDocShell
1358 Link<SpellCallbackInfo&,void> aLink = LINK(GetDocSh(), DrawDocShell, OnlineSpellCallback);
1360 pOLV->ExecuteSpellPopup(aPos, aLink);
1361 pOLV->GetEditView().Invalidate();
1363 else
1365 GetViewFrame()->GetDispatcher()->ExecutePopup(u"outline"_ustr);
1368 else
1370 ViewShell::Command( rCEvt, pWin );
1372 // if necessary communicate the new context to the Preview
1373 Invalidate( SID_PREVIEW_STATE );
1378 bool OutlineViewShell::KeyInput(const KeyEvent& rKEvt, ::sd::Window* pWin)
1380 bool bReturn = false;
1381 OutlineViewPageChangesGuard aGuard(pOlView.get());
1383 if (pWin == nullptr && HasCurrentFunction())
1385 bReturn = GetCurrentFunction()->KeyInput(rKEvt);
1388 // no, forward to base class
1389 else
1391 bReturn = ViewShell::KeyInput(rKEvt, pWin);
1394 Invalidate(SID_STYLE_EDIT);
1395 Invalidate(SID_STYLE_NEW);
1396 Invalidate(SID_STYLE_DELETE);
1397 Invalidate(SID_STYLE_HIDE);
1398 Invalidate(SID_STYLE_SHOW);
1399 Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE);
1400 Invalidate(SID_STYLE_NEW_BY_EXAMPLE);
1401 Invalidate(SID_STYLE_WATERCAN);
1402 Invalidate(SID_STYLE_FAMILY5);
1404 // check and distinguish cursor movements- or input-keys
1405 vcl::KeyCode aKeyGroup( rKEvt.GetKeyCode().GetGroup() );
1406 if( (aKeyGroup != KEYGROUP_CURSOR && aKeyGroup != KEYGROUP_FKEYS) ||
1407 (GetActualPage() != pLastPage) )
1409 Invalidate( SID_PREVIEW_STATE );
1412 return bReturn;
1416 * Status of Attribute-Items
1418 void OutlineViewShell::GetAttrState( SfxItemSet& rSet )
1420 SfxWhichIter aIter( rSet );
1421 sal_uInt16 nWhich = aIter.FirstWhich();
1422 SfxAllItemSet aAllSet( *rSet.GetPool() );
1424 while ( nWhich )
1426 sal_uInt16 nSlotId = SfxItemPool::IsWhich(nWhich)
1427 ? GetPool().GetSlotId(nWhich)
1428 : nWhich;
1430 switch ( nSlotId )
1432 case SID_STYLE_FAMILY2:
1433 case SID_STYLE_FAMILY3:
1435 rSet.DisableItem( nWhich );
1437 break;
1439 case SID_STYLE_FAMILY5:
1441 SfxStyleSheet* pStyleSheet = pOlView->GetViewByWindow(GetActiveWindow())->GetStyleSheet();
1443 if( pStyleSheet )
1445 pStyleSheet = static_cast<SdStyleSheet*>(pStyleSheet)->GetPseudoStyleSheet();
1447 if (pStyleSheet)
1449 SfxTemplateItem aItem( nWhich, pStyleSheet->GetName() );
1450 aAllSet.Put( aItem );
1454 if( !pStyleSheet )
1456 SfxTemplateItem aItem( nWhich, OUString() );
1457 aAllSet.Put( aItem );
1458 // rSet.DisableItem( nWhich );
1461 break;
1463 case SID_STYLE_EDIT:
1465 std::unique_ptr<SfxUInt16Item> pFamilyItem;
1466 GetViewFrame()->GetBindings().QueryState(SID_STYLE_FAMILY, pFamilyItem);
1467 if (pFamilyItem && static_cast<SfxStyleFamily>(pFamilyItem->GetValue()) == SfxStyleFamily::Pseudo)
1469 SfxItemSetFixed<SID_STATUS_LAYOUT, SID_STATUS_LAYOUT> aSet(*rSet.GetPool());
1470 GetStatusBarState(aSet);
1471 OUString aRealStyle = aSet.Get(SID_STATUS_LAYOUT).GetValue();
1472 if (aRealStyle.isEmpty())
1474 // no unique layout name found
1475 rSet.DisableItem(nWhich);
1479 break;
1481 case SID_STYLE_UPDATE_BY_EXAMPLE:
1483 ::sd::Window* pActWin = GetActiveWindow();
1484 OutlinerView* pOV = pOlView->GetViewByWindow(pActWin);
1485 ESelection aESel(pOV->GetSelection());
1487 if (aESel.HasRange())
1488 // spanned selection, i.e. StyleSheet and/or
1489 // attribution not necessarily unique
1490 rSet.DisableItem(nWhich);
1492 break;
1494 case SID_STYLE_NEW:
1495 case SID_STYLE_DELETE:
1496 case SID_STYLE_HIDE:
1497 case SID_STYLE_SHOW:
1498 case SID_STYLE_NEW_BY_EXAMPLE:
1499 case SID_STYLE_WATERCAN:
1501 rSet.DisableItem(nWhich);
1503 break;
1506 nWhich = aIter.NextWhich();
1509 rSet.Put( aAllSet, false );
1512 void OutlineViewShell::MouseButtonUp(const MouseEvent& rMEvt, ::sd::Window* pWin)
1514 // first the base classes
1515 ViewShell::MouseButtonUp(rMEvt, pWin);
1517 Invalidate(SID_STYLE_EDIT);
1518 Invalidate(SID_STYLE_NEW);
1519 Invalidate(SID_STYLE_DELETE);
1520 Invalidate(SID_STYLE_HIDE);
1521 Invalidate(SID_STYLE_SHOW);
1522 Invalidate(SID_STYLE_UPDATE_BY_EXAMPLE);
1523 Invalidate(SID_STYLE_NEW_BY_EXAMPLE);
1524 Invalidate(SID_STYLE_WATERCAN);
1525 Invalidate(SID_STYLE_FAMILY5);
1527 // if necessary communicate the new context to the Preview
1528 if( GetActualPage() != pLastPage )
1529 Invalidate( SID_PREVIEW_STATE );
1532 SdPage* OutlineViewShell::getCurrentPage() const
1534 // since there are no master pages in outline view, we can
1535 // for now use the GetActualPage method
1536 return const_cast<OutlineViewShell*>(this)->GetActualPage();
1540 * Returns the first selected page.
1541 * If nothing is selected, the first page is returned.
1543 SdPage* OutlineViewShell::GetActualPage()
1545 return pOlView->GetActualPage();
1548 void OutlineViewShell::UpdatePreview( SdPage* pPage )
1550 const bool bNewPage = pPage != pLastPage;
1551 pLastPage = pPage;
1552 if (bNewPage)
1554 OutlineViewPageChangesGuard aGuard(pOlView.get());
1555 SetCurrentPage(pPage);
1559 void OutlineViewShell::UpdateTitleObject( SdPage* pPage, Paragraph const * pPara )
1561 DBG_ASSERT( pPage, "sd::OutlineViewShell::UpdateTitleObject(), pPage == 0?" );
1562 DBG_ASSERT( pPara, "sd::OutlineViewShell::UpdateTitleObject(), pPara == 0?" );
1564 if( !pPage || !pPara )
1565 return;
1567 ::Outliner& rOutliner = pOlView->GetOutliner();
1568 SdrTextObj* pTO = OutlineView::GetTitleTextObject( pPage );
1570 OUString aTest = rOutliner.GetText(pPara);
1571 bool bText = !aTest.isEmpty();
1573 if( bText )
1575 bool bNewObject = false;
1576 // create a title object if we don't have one but have text
1577 if( !pTO )
1579 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateTitleObject(), no undo for model change!?" );
1580 pTO = OutlineView::CreateTitleTextObject(pPage);
1581 bNewObject = true;
1584 // if we have a title object and a text, set the text
1585 std::optional<OutlinerParaObject> pOPO;
1586 if (pTO)
1587 pOPO = rOutliner.CreateParaObject(rOutliner.GetAbsPos(pPara), 1);
1588 if (pOPO)
1590 pOPO->SetOutlinerMode( OutlinerMode::TitleObject );
1591 assert(pTO);
1592 pOPO->SetVertical( pTO->IsVerticalWriting() );
1593 if( pTO->GetOutlinerParaObject() && (pOPO->GetTextObject() == pTO->GetOutlinerParaObject()->GetTextObject()) )
1595 // do nothing, same text already set
1597 else
1599 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateTitleObject(), no undo for model change!?" );
1600 if( !bNewObject && pOlView->isRecordingUndo() )
1601 pOlView->AddUndo(GetDoc()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTO,0));
1603 pTO->SetOutlinerParaObject( std::move(pOPO) );
1604 pTO->SetEmptyPresObj( false );
1605 pTO->ActionChanged();
1609 else if( pTO )
1611 // no text but object available?
1612 // outline object available, but we have no text
1613 if(pPage->IsPresObj(pTO))
1615 // if it is not already empty
1616 if( !pTO->IsEmptyPresObj() )
1618 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateTitleObject(), no undo for model change!?" );
1620 // make it empty
1621 if( pOlView->isRecordingUndo() )
1622 pOlView->AddUndo(GetDoc()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTO,0));
1623 pPage->RestoreDefaultText( pTO );
1624 pTO->SetEmptyPresObj(true);
1625 pTO->ActionChanged();
1628 else
1630 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateTitleObject(), no undo for model change!?" );
1631 // outline object is not part of the layout, delete it
1632 if( pOlView->isRecordingUndo() )
1633 pOlView->AddUndo(GetDoc()->GetSdrUndoFactory().CreateUndoRemoveObject(*pTO));
1634 pPage->RemoveObject(pTO->GetOrdNum());
1639 void OutlineViewShell::UpdateOutlineObject( SdPage* pPage, Paragraph* pPara )
1641 DBG_ASSERT( pPage, "sd::OutlineViewShell::UpdateOutlineObject(), pPage == 0?" );
1642 DBG_ASSERT( pPara, "sd::OutlineViewShell::UpdateOutlineObject(), pPara == 0?" );
1644 if( !pPage || !pPara )
1645 return;
1647 ::Outliner& rOutliner = pOlView->GetOutliner();
1648 std::optional<OutlinerParaObject> pOPO;
1649 SdrTextObj* pTO = nullptr;
1651 OutlinerMode eOutlinerMode = OutlinerMode::TitleObject;
1652 pTO = static_cast<SdrTextObj*>(pPage->GetPresObj( PresObjKind::Text ));
1653 if( !pTO )
1655 eOutlinerMode = OutlinerMode::OutlineObject;
1656 pTO = OutlineView::GetOutlineTextObject( pPage );
1659 // how many paragraphs in the outline?
1660 sal_Int32 nTitlePara = rOutliner.GetAbsPos( pPara );
1661 sal_Int32 nPara = nTitlePara + 1;
1662 sal_Int32 nParasInLayout = 0;
1663 pPara = rOutliner.GetParagraph( nPara );
1664 while( pPara && !::Outliner::HasParaFlag(pPara, ParaFlag::ISPAGE) )
1666 nParasInLayout++;
1667 pPara = rOutliner.GetParagraph( ++nPara );
1669 if( nParasInLayout )
1671 // create an OutlinerParaObject
1672 pOPO = rOutliner.CreateParaObject( nTitlePara + 1, nParasInLayout );
1675 if( pOPO )
1677 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateOutlineObject(), no undo for model change!?" );
1678 bool bNewObject = false;
1680 // do we need an outline text object?
1681 if( !pTO )
1683 pTO = OutlineView::CreateOutlineTextObject( pPage );
1684 bNewObject = true;
1687 // page object, outline text in Outliner:
1688 // apply text
1689 if( pTO )
1691 pOPO->SetVertical( pTO->IsVerticalWriting() );
1692 pOPO->SetOutlinerMode( eOutlinerMode );
1693 if( pTO->GetOutlinerParaObject() && (pOPO->GetTextObject() == pTO->GetOutlinerParaObject()->GetTextObject()) )
1695 // do nothing, same text already set
1697 else
1699 if( !bNewObject && pOlView->isRecordingUndo() )
1700 pOlView->AddUndo(GetDoc()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTO,0));
1702 pTO->SetOutlinerParaObject( std::move(pOPO) );
1703 pTO->SetEmptyPresObj( false );
1704 pTO->ActionChanged();
1708 else if( pTO )
1710 // page object but no outline text:
1711 // if the object is in the outline of the page -> default text
1713 // otherwise delete object
1714 if( pPage->IsPresObj(pTO) )
1716 if( !pTO->IsEmptyPresObj() )
1718 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateOutlineObject(), no undo for model change!?" );
1720 // delete old OutlinerParaObject, too
1721 if( pOlView->isRecordingUndo() )
1722 pOlView->AddUndo(GetDoc()->GetSdrUndoFactory().CreateUndoObjectSetText(*pTO,0));
1723 pPage->RestoreDefaultText( pTO );
1724 pTO->SetEmptyPresObj(true);
1725 pTO->ActionChanged();
1728 else
1730 DBG_ASSERT( pOlView->isRecordingUndo(), "sd::OutlineViewShell::UpdateOutlineObject(), no undo for model change!?" );
1731 if( pOlView->isRecordingUndo() )
1732 pOlView->AddUndo(GetDoc()->GetSdrUndoFactory().CreateUndoRemoveObject(*pTO));
1733 pPage->RemoveObject(pTO->GetOrdNum());
1739 * Fill Outliner from Stream
1741 ErrCode OutlineViewShell::ReadRtf(SvStream& rInput)
1743 ErrCode bRet = ERRCODE_NONE;
1745 ::Outliner& rOutl = pOlView->GetOutliner();
1747 OutlineViewPageChangesGuard aGuard( pOlView.get() );
1748 OutlineViewModelChangeGuard aGuard2( *pOlView );
1750 bRet = rOutl.Read( rInput, OUString(), EETextFormat::Rtf, GetDocSh()->GetHeaderAttributes() );
1752 SdPage* pPage = GetDoc()->GetSdPage( GetDoc()->GetSdPageCount(PageKind::Standard) - 1, PageKind::Standard );
1753 SfxStyleSheet* pTitleSheet = pPage->GetStyleSheetForPresObj( PresObjKind::Title );
1754 SfxStyleSheet* pOutlSheet = pPage->GetStyleSheetForPresObj( PresObjKind::Outline );
1756 sal_Int32 nParaCount = rOutl.GetParagraphCount();
1757 if ( nParaCount > 0 )
1759 for ( sal_Int32 nPara = 0; nPara < nParaCount; nPara++ )
1761 pOlView->UpdateParagraph( nPara );
1763 sal_Int16 nDepth = rOutl.GetDepth( nPara );
1765 if( (nDepth == 0) || !nPara )
1767 Paragraph* pPara = rOutl.GetParagraph( nPara );
1768 rOutl.SetDepth(pPara, -1);
1769 rOutl.SetParaFlag(pPara, ParaFlag::ISPAGE);
1771 rOutl.SetStyleSheet( nPara, pTitleSheet );
1773 if( nPara ) // first slide already exists
1774 pOlView->InsertSlideForParagraph( pPara );
1776 else
1778 rOutl.SetDepth( rOutl.GetParagraph( nPara ), nDepth - 1 );
1779 OUString aStyleSheetName = pOutlSheet->GetName();
1780 if (!aStyleSheetName.isEmpty())
1781 aStyleSheetName = aStyleSheetName.copy(0, aStyleSheetName.getLength() - 1);
1782 aStyleSheetName += OUString::number( nDepth );
1783 SfxStyleSheetBasePool* pStylePool = GetDoc()->GetStyleSheetPool();
1784 SfxStyleSheet* pStyle = static_cast<SfxStyleSheet*>( pStylePool->Find( aStyleSheetName, pOutlSheet->GetFamily() ) );
1785 DBG_ASSERT( pStyle, "AutoStyleSheetName - Style not found!" );
1786 if ( pStyle )
1787 rOutl.SetStyleSheet( nPara, pStyle );
1792 rOutl.GetUndoManager().Clear();
1794 return bRet;
1797 void OutlineViewShell::WriteUserDataSequence ( css::uno::Sequence < css::beans::PropertyValue >& rSequence )
1799 WriteFrameViewData();
1801 ViewShell::WriteUserDataSequence( rSequence );
1804 void OutlineViewShell::ReadUserDataSequence ( const css::uno::Sequence < css::beans::PropertyValue >& rSequence )
1806 WriteFrameViewData();
1808 ViewShell::ReadUserDataSequence( rSequence );
1810 ReadFrameViewData( mpFrameView );
1813 void OutlineViewShell::VisAreaChanged(const ::tools::Rectangle& rRect)
1815 ViewShell::VisAreaChanged( rRect );
1817 GetViewShellBase().GetDrawController()->FireVisAreaChanged(rRect);
1820 /** If there is a valid controller then create a new instance of
1821 <type>AccessibleDrawDocumentView</type>. Otherwise return an empty
1822 reference.
1824 css::uno::Reference<css::accessibility::XAccessible>
1825 OutlineViewShell::CreateAccessibleDocumentView (::sd::Window* pWindow)
1827 OSL_ASSERT (GetViewShell()!=nullptr);
1828 if (GetViewShell()->GetController() != nullptr)
1830 rtl::Reference<::accessibility::AccessibleOutlineView> pDocumentView =
1831 new ::accessibility::AccessibleOutlineView (
1832 pWindow,
1833 this,
1834 GetViewShell()->GetController(),
1835 pWindow->GetAccessibleParentWindow()->GetAccessible());
1836 pDocumentView->Init();
1837 return pDocumentView;
1840 SAL_WARN("sd", "OutlineViewShell::CreateAccessibleDocumentView: no controller");
1841 return css::uno::Reference< css::accessibility::XAccessible >();
1844 void OutlineViewShell::GetState (SfxItemSet& rSet)
1846 // Iterate over all requested items in the set.
1847 SfxWhichIter aIter( rSet );
1848 sal_uInt16 nWhich = aIter.FirstWhich();
1849 while (nWhich)
1851 switch (nWhich)
1853 case SID_SEARCH_ITEM:
1854 case SID_SEARCH_OPTIONS:
1855 // Call common (old) implementation in the document shell.
1856 GetDocSh()->GetState (rSet);
1857 break;
1858 default:
1859 SAL_WARN("sd", "OutlineViewShell::GetState(): can not handle which id " << nWhich);
1860 break;
1862 nWhich = aIter.NextWhich();
1866 void OutlineViewShell::SetCurrentPage (SdPage* pPage)
1868 // Adapt the selection of the model.
1869 for (sal_uInt16 i=0; i<GetDoc()->GetSdPageCount(PageKind::Standard); i++)
1870 GetDoc()->SetSelected(
1871 GetDoc()->GetSdPage(i, PageKind::Standard),
1872 false);
1873 GetDoc()->SetSelected (pPage, true);
1875 DrawController& rController(*GetViewShellBase().GetDrawController());
1876 rController.FireSelectionChangeListener();
1877 rController.FireSwitchCurrentPage (pPage);
1879 pOlView->SetActualPage(pPage);
1882 } // end of namespace sd
1884 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */