1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
22 #include <string_view>
24 #include <swtypes.hxx>
26 #include <strings.hrc>
27 #include <unotools.hxx>
28 #include <unoprnms.hxx>
29 #include <i18nutil/unicode.hxx>
30 #include <o3tl/string_view.hxx>
31 #include <rtl/string.h>
32 #include <svtools/colorcfg.hxx>
33 #include <vcl/commandevent.hxx>
34 #include <vcl/jobset.hxx>
35 #include <vcl/settings.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/virdev.hxx>
38 #include <vcl/weld.hxx>
39 #include <com/sun/star/frame/Desktop.hpp>
40 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
41 #include <com/sun/star/view/XScreenCursor.hpp>
42 #include <com/sun/star/view/DocumentZoomType.hpp>
43 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
44 #include <com/sun/star/style/XStyle.hpp>
45 #include <com/sun/star/text/XTextDocument.hpp>
46 #include <com/sun/star/awt/PosSize.hpp>
47 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
48 #include <com/sun/star/container/XNameContainer.hpp>
49 #include <com/sun/star/frame/XLayoutManager.hpp>
50 #include <comphelper/processfactory.hxx>
51 #include <comphelper/propertysequence.hxx>
52 #include <comphelper/servicehelper.hxx>
53 #include <comphelper/string.hxx>
57 #include <swmodule.hxx>
58 #include <TextCursorHelper.hxx>
61 using namespace ::com::sun::star
;
63 constexpr OUStringLiteral cFactory
= u
"private:factory/swriter";
65 static void disableScrollBars(uno::Reference
< beans::XPropertySet
> const & xViewProps
,
66 bool bEnableOnlineMode
)
68 //the scrollbar logic is kind of busted looking in writer, when the hori scrollbar
69 //property is changed then the hori scrollbar is enabled if the property is
70 //true or browse (online) mode is enabled. So...
73 //turn back on online mode if that's what we want
74 //which subverts the (dodgy/buggy) scrollbar setting
76 //To reproduce this problem, in edit->autotext and click through
77 //the examples and see if the preview gets a horizontal scrollbar
78 uno::Any
aFalseSet(uno::Any(false));
79 xViewProps
->setPropertyValue(UNO_NAME_SHOW_ONLINE_LAYOUT
, aFalseSet
);
81 xViewProps
->setPropertyValue(UNO_NAME_SHOW_HORI_SCROLL_BAR
, aFalseSet
);
82 xViewProps
->setPropertyValue(UNO_NAME_SHOW_VERT_SCROLL_BAR
, aFalseSet
);
84 if (bEnableOnlineMode
)
86 xViewProps
->setPropertyValue(UNO_NAME_SHOW_ONLINE_LAYOUT
, uno::Any(true));
90 SwOneExampleFrame::SwOneExampleFrame(sal_uInt32 nFlags
,
91 const Link
<SwOneExampleFrame
&,void>* pInitializedLink
,
93 : m_aLoadedIdle("sw uibase SwOneExampleFrame Loaded")
94 , m_pModuleView(SW_MOD()->GetView())
95 , m_nStyleFlags(nFlags
)
96 , m_bIsInitialized(false)
98 if (pURL
&& !pURL
->isEmpty())
99 m_sArgumentURL
= *pURL
;
101 if( pInitializedLink
)
102 m_aInitializedLink
= *pInitializedLink
;
104 // the controller is asynchronously set
105 m_aLoadedIdle
.SetInvokeHandler(LINK(this, SwOneExampleFrame
, TimeoutHdl
));
106 m_aLoadedIdle
.SetPriority(TaskPriority::HIGH_IDLE
);
109 void SwOneExampleFrame::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
111 CustomWidgetController::SetDrawingArea(pDrawingArea
);
112 m_xVirDev
= VclPtr
<VirtualDevice
>::Create();
113 Size
aSize(m_xVirDev
->LogicToPixel(Size(150, 188), MapMode(MapUnit::MapAppFont
)));
114 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
115 SetOutputSizePixel(aSize
);
119 bool SwOneExampleFrame::Command(const CommandEvent
& rCEvt
)
121 switch (rCEvt
.GetCommand())
123 case CommandEventId::ContextMenu
:
125 //#125881# quickly clicking crashes because the control is not fully initialized
126 if (m_xController
.is())
127 return CreatePopup(rCEvt
.GetMousePosPixel());
133 return CustomWidgetController::Command(rCEvt
);
136 void SwOneExampleFrame::Paint(vcl::RenderContext
& rRenderContext
, const tools::Rectangle
&)
138 Size
aSize(GetOutputSizePixel());
139 // m_xVirDev instead of rRenderContext just to avoid overlays in writer re-triggering
140 // invalidate on rRenderContext if it is a vcl::Window, which is the "classic" gen mode
141 m_xVirDev
->SetOutputSizePixel(aSize
);
143 Color aBgColor
= SW_MOD()->GetColorConfig().GetColorValue(::svtools::DOCCOLOR
).nColor
;
144 m_xVirDev
->DrawWallpaper(tools::Rectangle(Point(), aSize
), aBgColor
);
146 auto pCursor
= dynamic_cast<OTextCursorHelper
*>(m_xCursor
.get());
149 uno::Reference
<view::XViewSettingsSupplier
> xSettings(m_xController
, uno::UNO_QUERY
);
150 uno::Reference
<beans::XPropertySet
> xViewProps
= xSettings
->getViewSettings();
151 uno::Any aZoom
= xViewProps
->getPropertyValue(UNO_NAME_ZOOM_VALUE
);
152 sal_Int16 nZoom
= 100;
155 double fZoom
= 100.0 / nZoom
;
157 m_xVirDev
->Push(vcl::PushFlags::ALL
);
158 m_xVirDev
->SetMapMode(MapMode(MapUnit::MapTwip
));
159 SwDoc
*pDoc
= pCursor
->GetDoc();
160 SwDocShell
* pShell
= pDoc
->GetDocShell();
161 tools::Rectangle
aRect(Point(), m_xVirDev
->PixelToLogic(aSize
));
162 pShell
->SetVisArea(tools::Rectangle(Point(), Size(aRect
.GetWidth() * fZoom
,
163 aRect
.GetHeight() * fZoom
)));
164 pShell
->DoDraw(m_xVirDev
.get(), aRect
.TopLeft(), aRect
.GetSize(), JobSetup(), ASPECT_CONTENT
, true);
168 rRenderContext
.DrawOutDev(Point(), aSize
, Point(), aSize
, *m_xVirDev
);
171 SwOneExampleFrame::~SwOneExampleFrame()
176 void SwOneExampleFrame::CreateControl()
179 OUString
sTempURL(cFactory
);
180 if(!m_sArgumentURL
.isEmpty())
181 sTempURL
= m_sArgumentURL
;
183 uno::Reference
<frame::XDesktop2
> xDesktop
= frame::Desktop::create(::comphelper::getProcessComponentContext());
184 uno::Sequence
<beans::PropertyValue
> args( comphelper::InitPropertySequence({
185 { "DocumentService", uno::Any(OUString("com.sun.star.text.TextDocument")) },
186 { "OpenFlags", uno::Any(OUString("-RB")) },
187 { "Referer", uno::Any(OUString("private:user")) },
188 { "ReadOnly", uno::Any(true) },
189 { "Hidden", uno::Any(true) }
192 m_xModel
.set(xDesktop
->loadComponentFromURL(sTempURL
, "_blank", 0, args
), uno::UNO_QUERY
);
194 m_aLoadedIdle
.Start();
197 void SwOneExampleFrame::DisposeControl()
199 m_aLoadedIdle
.Stop();
206 m_xController
= nullptr;
209 IMPL_LINK( SwOneExampleFrame
, TimeoutHdl
, Timer
*, pTimer
, void )
214 m_xController
= m_xModel
->getCurrentController();
216 if (m_xController
.is())
218 uno::Reference
<frame::XFrame
> xFrame
= m_xController
->getFrame();
219 uno::Reference
< beans::XPropertySet
> xPropSet( xFrame
, uno::UNO_QUERY
);
224 uno::Reference
< frame::XLayoutManager
> xLayoutManager
;
225 uno::Any aValue
= xPropSet
->getPropertyValue("LayoutManager");
226 aValue
>>= xLayoutManager
;
227 if ( xLayoutManager
.is() )
228 xLayoutManager
->setVisible( false );
230 catch (const uno::Exception
&)
235 //now the ViewOptions should be set properly
236 uno::Reference
< view::XViewSettingsSupplier
> xSettings(m_xController
, uno::UNO_QUERY
);
237 uno::Reference
< beans::XPropertySet
> xViewProps
= xSettings
->getViewSettings();
239 const uno::Any
aTrueSet( true );
240 const uno::Any
aFalseSet( false );
242 if( !m_bIsInitialized
)
244 xViewProps
->setPropertyValue(UNO_NAME_SHOW_BREAKS
, aFalseSet
);
245 xViewProps
->setPropertyValue(UNO_NAME_SHOW_DRAWINGS
, aTrueSet
);
246 xViewProps
->setPropertyValue(UNO_NAME_SHOW_FIELD_COMMANDS
, aFalseSet
);
247 xViewProps
->setPropertyValue(UNO_NAME_SHOW_GRAPHICS
, aTrueSet
);
248 xViewProps
->setPropertyValue(UNO_NAME_HIDE_WHITESPACE
, aFalseSet
);
249 xViewProps
->setPropertyValue(UNO_NAME_SHOW_HIDDEN_PARAGRAPHS
, aFalseSet
);
250 xViewProps
->setPropertyValue(UNO_NAME_SHOW_HIDDEN_TEXT
, aFalseSet
);
251 xViewProps
->setPropertyValue(UNO_NAME_SHOW_HORI_RULER
, aFalseSet
);
252 xViewProps
->setPropertyValue(UNO_NAME_SHOW_PARA_BREAKS
, aFalseSet
);
253 xViewProps
->setPropertyValue(UNO_NAME_SHOW_PROTECTED_SPACES
, aFalseSet
);
254 xViewProps
->setPropertyValue(UNO_NAME_SHOW_SOFT_HYPHENS
, aFalseSet
);
255 xViewProps
->setPropertyValue(UNO_NAME_SHOW_SPACES
, aFalseSet
);
256 xViewProps
->setPropertyValue(UNO_NAME_SHOW_TABLES
, aTrueSet
);
257 xViewProps
->setPropertyValue(UNO_NAME_SHOW_TABSTOPS
, aFalseSet
);
258 xViewProps
->setPropertyValue(UNO_NAME_SHOW_VERT_RULER
, aFalseSet
);
260 if(0 ==(m_nStyleFlags
&EX_SHOW_ONLINE_LAYOUT
))
263 aZoom
<<= sal_Int16(view::DocumentZoomType::PAGE_WIDTH_EXACT
);
264 xViewProps
->setPropertyValue(UNO_NAME_ZOOM_TYPE
, aZoom
);
269 aZoom
<<= sal_Int16(view::DocumentZoomType::BY_VALUE
);
270 xViewProps
->setPropertyValue(UNO_NAME_ZOOM_TYPE
, aZoom
);
272 sal_Int16 nZoomValue
= 75;
273 if(EX_SHOW_BUSINESS_CARDS
== m_nStyleFlags
)
277 aZoom
<<= nZoomValue
;
278 xViewProps
->setPropertyValue(UNO_NAME_ZOOM_VALUE
, aZoom
);
281 // set onlinelayout property after setting the zoom
282 disableScrollBars(xViewProps
, (m_nStyleFlags
&EX_SHOW_ONLINE_LAYOUT
) != 0);
283 m_bIsInitialized
= true;
286 uno::Reference
< text::XTextDocument
> xDoc(m_xModel
, uno::UNO_QUERY
);
287 uno::Reference
< text::XText
> xText
= xDoc
->getText();
288 m_xCursor
= xText
->createTextCursor();
290 //From here, a cursor is defined, which goes through the template,
291 //and overwrites the template words where it is necessary.
293 auto pCursor
= dynamic_cast<OTextCursorHelper
*>(m_xCursor
.get());
295 SwDoc
*pDoc
= pCursor
? pCursor
->GetDoc() : nullptr;
296 if (pDoc
&& (m_nStyleFlags
& EX_LOCALIZE_TOC_STRINGS
))
298 SwEditShell
* pSh
= pDoc
->GetEditShell();
302 if (pSh
->GetCurWord() == "HEADING1")
304 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_HEADING1
));
306 else if (pSh
->GetCurWord() == "ENTRY1")
308 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_ENTRY1
));
310 else if (pSh
->GetCurWord() == "HEADING11")
312 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_HEADING11
));
314 else if (pSh
->GetCurWord() == "ENTRY11")
316 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_ENTRY11
));
318 else if (pSh
->GetCurWord() == "HEADING12")
320 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_HEADING12
));
322 else if (pSh
->GetCurWord() == "ENTRY12")
324 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_ENTRY12
));
326 else if (pSh
->GetCurWord() == "TABLE1")
328 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_TABLE1
));
330 else if (pSh
->GetCurWord() == "IMAGE1")
332 pSh
->Overwrite(SwResId(STR_IDXEXAMPLE_IDXTXT_IMAGE1
));
335 while(pSh
->Right(sal_uInt16(1), SwCursorSkipMode::Cells
, true));
337 TOXTypes eTypes
[] = { TOX_INDEX
, TOX_USER
, TOX_CONTENT
};
338 for (auto eType
: eTypes
)
340 const SwTOXType
* pTOXType
= pDoc
->GetTOXType(eType
, 0);
342 pTOXType
->CollectTextMarks(aMarks
);
343 for (auto pMark
: aMarks
)
345 if (pMark
->GetAlternativeText() == "Chapter")
346 pMark
->SetAlternativeText(SwResId(STR_IDXEXAMPLE_IDXMARK_CHAPTER
));
347 else if (pMark
->GetAlternativeText() == "Keyword")
348 pMark
->SetAlternativeText(SwResId(STR_IDXEXAMPLE_IDXMARK_KEYWORD
));
349 else if (pMark
->GetAlternativeText() == "this")
350 pMark
->SetAlternativeText(SwResId(STR_IDXEXAMPLE_IDXMARK_THIS
));
351 else if (pMark
->GetAlternativeText() == "User Directory Entry")
352 pMark
->SetAlternativeText(SwResId(STR_IDXEXAMPLE_IDXMARK_USER_DIR_ENTRY
));
353 else if (pMark
->GetAlternativeText() == "Entry")
354 pMark
->SetAlternativeText(SwResId(STR_IDXEXAMPLE_IDXMARK_ENTRY
));
356 if (pMark
->GetPrimaryKey() == "Primary key")
357 pMark
->SetPrimaryKey(SwResId(STR_IDXEXAMPLE_IDXMARK_PRIMARY_KEY
));
359 if (pMark
->GetSecondaryKey() == "Secondary key")
360 pMark
->SetSecondaryKey(SwResId(STR_IDXEXAMPLE_IDXMARK_SECONDARY_KEY
));
365 uno::Reference
< beans::XPropertySet
> xCursorProp(m_xCursor
, uno::UNO_QUERY
);
366 uno::Any aPageStyle
= xCursorProp
->getPropertyValue(UNO_NAME_PAGE_STYLE_NAME
);
368 aPageStyle
>>= sPageStyle
;
370 uno::Reference
< style::XStyleFamiliesSupplier
> xSSupp( xDoc
, uno::UNO_QUERY
);
371 uno::Reference
< container::XNameAccess
> xStyles
= xSSupp
->getStyleFamilies();
372 uno::Any aPFamily
= xStyles
->getByName( "PageStyles" );
373 uno::Reference
< container::XNameContainer
> xPFamily
;
375 if( EX_SHOW_DEFAULT_PAGE
!= m_nStyleFlags
376 && (aPFamily
>>= xPFamily
) && !sPageStyle
.isEmpty() )
378 uno::Any aPStyle
= xPFamily
->getByName( sPageStyle
);
379 uno::Reference
< style::XStyle
> xPStyle
;
381 uno::Reference
< beans::XPropertySet
> xPProp(xPStyle
, uno::UNO_QUERY
);
382 uno::Any aSize
= xPProp
->getPropertyValue(UNO_NAME_SIZE
);
385 //TODO: set page width to card width
386 aPSize
.Width
= 10000;
388 xPProp
->setPropertyValue(UNO_NAME_SIZE
, aSize
);
390 uno::Any aZero
; aZero
<<= sal_Int32(0);
391 xPProp
->setPropertyValue(UNO_NAME_LEFT_MARGIN
, aZero
);
392 xPProp
->setPropertyValue(UNO_NAME_RIGHT_MARGIN
, aZero
);
395 uno::Reference
<awt::XWindow
> xWin
= xFrame
->getContainerWindow();
396 Size
aWinSize(GetOutputSizePixel());
397 xWin
->setPosSize(0, 0, aWinSize
.Width(), aWinSize
.Height(), awt::PosSize::SIZE
);
399 // can only be done here - the SFX changes the ScrollBar values
400 disableScrollBars(xViewProps
, (m_nStyleFlags
&EX_SHOW_ONLINE_LAYOUT
) != 0);
402 m_aInitializedLink
.Call(*this);
404 uno::Reference
< text::XTextViewCursorSupplier
> xCursorSupp(m_xController
, uno::UNO_QUERY
);
405 uno::Reference
< view::XScreenCursor
> xScrCursor(xCursorSupp
->getViewCursor(), uno::UNO_QUERY
);
407 xScrCursor
->screenUp();
411 SwEditShell
* pSh
= pDoc
->GetEditShell();
412 if( pSh
->ActionCount() )
419 SW_MOD()->SetView(m_pModuleView
);
427 void SwOneExampleFrame::ClearDocument()
431 OTextCursorHelper
* pCursor
= dynamic_cast<OTextCursorHelper
*>(m_xCursor
.get());
434 SwDoc
* pDoc
= pCursor
->GetDoc();
435 SwEditShell
* pSh
= pDoc
->GetEditShell();
436 pSh
->LockPaint(LockPaintReason::ExampleFrame
);
437 pSh
->StartAllAction();
441 pSh
->ClearUpCursors();
443 if( m_aLoadedIdle
.IsActive())
448 m_aLoadedIdle
.Start();
452 m_xCursor
->gotoStart(false);
453 m_xCursor
->gotoEnd(true);
454 m_xCursor
->setString(OUString());
458 bool SwOneExampleFrame::CreatePopup(const Point
& rPt
)
460 if (EX_SHOW_ONLINE_LAYOUT
!= m_nStyleFlags
)
463 std::unique_ptr
<weld::Builder
> xBuilder(Application::CreateBuilder(nullptr, "modules/swriter/ui/previewmenu.ui"));
464 std::unique_ptr
<weld::Menu
> xPop(xBuilder
->weld_menu("previewmenu"));
466 uno::Reference
< view::XViewSettingsSupplier
> xSettings(m_xController
, uno::UNO_QUERY
);
467 uno::Reference
< beans::XPropertySet
> xViewProps
= xSettings
->getViewSettings();
469 uno::Any aZoom
= xViewProps
->getPropertyValue(UNO_NAME_ZOOM_VALUE
);
473 for (auto const nZoomPreset
: { 20, 40, 50, 75, 100 })
475 OUString sTemp
= unicode::formatPercent(nZoomPreset
,
476 Application::GetSettings().GetUILanguageTag());
477 OUString sIdent
= "zoom" + OUString::number(nZoomPreset
);
478 xPop
->set_label(sIdent
, sTemp
);
479 if (nZoom
== nZoomPreset
)
480 xPop
->set_active(sIdent
, true);
483 PopupHdl(xPop
->popup_at_rect(GetDrawingArea(), tools::Rectangle(rPt
, Size(1, 1))));
488 void SwOneExampleFrame::PopupHdl(std::u16string_view rId
)
490 std::u16string_view sZoomValue
;
491 if (o3tl::starts_with(rId
, u
"zoom", &sZoomValue
))
493 sal_Int16 nZoom
= o3tl::toInt32(sZoomValue
);
494 uno::Reference
< view::XViewSettingsSupplier
> xSettings(m_xController
, uno::UNO_QUERY
);
495 uno::Reference
< beans::XPropertySet
> xViewProps
= xSettings
->getViewSettings();
499 xViewProps
->setPropertyValue(UNO_NAME_ZOOM_VALUE
, aZoom
);
500 aZoom
<<= sal_Int16(view::DocumentZoomType::BY_VALUE
);
501 xViewProps
->setPropertyValue(UNO_NAME_ZOOM_TYPE
, aZoom
);
506 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */