File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | |||
2 | /* | |||
3 | * This file is part of the LibreOffice project. | |||
4 | * | |||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | |||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |||
8 | * | |||
9 | * This file incorporates work covered by the following license notice: | |||
10 | * | |||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | |||
12 | * contributor license agreements. See the NOTICE file distributed | |||
13 | * with this work for additional information regarding copyright | |||
14 | * ownership. The ASF licenses this file to you under the Apache | |||
15 | * License, Version 2.0 (the "License"); you may not use this file | |||
16 | * except in compliance with the License. You may obtain a copy of | |||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | |||
18 | */ | |||
19 | ||||
20 | #include <sfx2/objface.hxx> | |||
21 | #include <vcl/help.hxx> | |||
22 | #include <vcl/commandevent.hxx> | |||
23 | #include <vcl/settings.hxx> | |||
24 | #include <vcl/svapp.hxx> | |||
25 | #include <vcl/syswin.hxx> | |||
26 | #include <vcl/weld.hxx> | |||
27 | ||||
28 | #include <rtl/ustrbuf.hxx> | |||
29 | #include <svl/whiter.hxx> | |||
30 | #include <svl/stritem.hxx> | |||
31 | #include <svl/eitem.hxx> | |||
32 | #include <sfx2/printer.hxx> | |||
33 | #include <sfx2/bindings.hxx> | |||
34 | #include <sfx2/request.hxx> | |||
35 | #include <sfx2/dispatch.hxx> | |||
36 | #include <editeng/paperinf.hxx> | |||
37 | #include <svx/svdview.hxx> | |||
38 | #include <svx/zoomslideritem.hxx> | |||
39 | #include <tools/svborder.hxx> | |||
40 | ||||
41 | #include <globdoc.hxx> | |||
42 | #include <wdocsh.hxx> | |||
43 | #include <pvprtdat.hxx> | |||
44 | #include <swmodule.hxx> | |||
45 | #include <wrtsh.hxx> | |||
46 | #include <docsh.hxx> | |||
47 | #include <viewopt.hxx> | |||
48 | #include <doc.hxx> | |||
49 | #include <IDocumentDeviceAccess.hxx> | |||
50 | #include <pview.hxx> | |||
51 | #include <view.hxx> | |||
52 | #include <scroll.hxx> | |||
53 | #include <prtopt.hxx> | |||
54 | #include <usrpref.hxx> | |||
55 | #include "viewfunc.hxx" | |||
56 | ||||
57 | #include <helpids.h> | |||
58 | #include <cmdid.h> | |||
59 | #include <strings.hrc> | |||
60 | ||||
61 | #define ShellClass_SwPagePreview | |||
62 | #include <sfx2/msg.hxx> | |||
63 | #include <swslots.hxx> | |||
64 | #include <pagepreviewlayout.hxx> | |||
65 | ||||
66 | #include <svx/svxdlg.hxx> | |||
67 | ||||
68 | #include <memory> | |||
69 | #include <vcl/EnumContext.hxx> | |||
70 | #include <vcl/notebookbar.hxx> | |||
71 | ||||
72 | using namespace ::com::sun::star; | |||
73 | SFX_IMPL_NAMED_VIEWFACTORY(SwPagePreview, "PrintPreview")SfxViewFactory* SwPagePreview::pFactory; SfxViewShell* SwPagePreview ::CreateInstance(SfxViewFrame *pFrame, SfxViewShell *pOldView ) { return new SwPagePreview(pFrame, pOldView); } void SwPagePreview ::RegisterFactory( SfxInterfaceId nPrio ) { pFactory = new SfxViewFactory (&CreateInstance,nPrio,"PrintPreview"); InitFactory(); } void SwPagePreview::InitFactory() | |||
74 | { | |||
75 | SFX_VIEW_REGISTRATION(SwDocShell)SwDocShell::Factory().RegisterViewFactory( *Factory() ); | |||
76 | SFX_VIEW_REGISTRATION(SwWebDocShell)SwWebDocShell::Factory().RegisterViewFactory( *Factory() ); | |||
77 | SFX_VIEW_REGISTRATION(SwGlobalDocShell)SwGlobalDocShell::Factory().RegisterViewFactory( *Factory() ); | |||
78 | } | |||
79 | ||||
80 | SFX_IMPL_INTERFACE(SwPagePreview, SfxViewShell)SfxInterface* SwPagePreview::pInterface = nullptr; SfxInterface * SwPagePreview::GetStaticInterface() { if ( !pInterface ) { pInterface = new SfxInterface( "SwPagePreview", false, GetInterfaceId() , SfxViewShell::GetStaticInterface(), aSwPagePreviewSlots_Impl [0], sal_uInt16(sizeof(aSwPagePreviewSlots_Impl) / sizeof(SfxSlot ) ) ); InitInterface_Impl(); } return pInterface; } SfxInterface * SwPagePreview::GetInterface() const { return GetStaticInterface (); } void SwPagePreview::RegisterInterface(const SfxModule* pMod ) { GetStaticInterface()->Register(pMod); } | |||
81 | ||||
82 | void SwPagePreview::InitInterface_Impl() | |||
83 | { | |||
84 | GetStaticInterface()->RegisterPopupMenu("preview"); | |||
85 | GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT1, | |||
86 | SfxVisibilityFlags::Standard|SfxVisibilityFlags::Client|SfxVisibilityFlags::FullScreen|SfxVisibilityFlags::ReadonlyDoc, | |||
87 | ToolbarId::PView_Toolbox); | |||
88 | } | |||
89 | ||||
90 | ||||
91 | #define SWVIEWFLAGSSfxViewShellFlags::HAS_PRINTOPTIONS SfxViewShellFlags::HAS_PRINTOPTIONS | |||
92 | ||||
93 | #define MIN_PREVIEW_ZOOM25 25 | |||
94 | #define MAX_PREVIEW_ZOOM600 600 | |||
95 | ||||
96 | static sal_uInt16 lcl_GetNextZoomStep(sal_uInt16 nCurrentZoom, bool bZoomIn) | |||
97 | { | |||
98 | static const sal_uInt16 aZoomArr[] = | |||
99 | { | |||
100 | 25, 50, 75, 100, 150, 200, 400, 600 | |||
101 | }; | |||
102 | const int nZoomArrSize = static_cast<int>(SAL_N_ELEMENTS(aZoomArr)(sizeof(sal_n_array_size(aZoomArr)))); | |||
103 | if (bZoomIn) | |||
104 | { | |||
105 | for(int i = nZoomArrSize - 1; i >= 0; --i) | |||
106 | { | |||
107 | if(nCurrentZoom > aZoomArr[i] || !i) | |||
108 | return aZoomArr[i]; | |||
109 | } | |||
110 | } | |||
111 | else | |||
112 | { | |||
113 | for(sal_uInt16 i : aZoomArr) | |||
114 | { | |||
115 | if(nCurrentZoom < i) | |||
116 | return i; | |||
117 | } | |||
118 | } | |||
119 | return bZoomIn ? MAX_PREVIEW_ZOOM600 : MIN_PREVIEW_ZOOM25; | |||
120 | }; | |||
121 | ||||
122 | static void lcl_InvalidateZoomSlots(SfxBindings& rBindings) | |||
123 | { | |||
124 | static sal_uInt16 const aInval[] = | |||
125 | { | |||
126 | SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ZOOM_OUT(10000 + 97), SID_ZOOM_IN(10000 + 98), SID_ATTR_ZOOMSLIDER( 10000 + 1065 ), FN_PREVIEW_ZOOM((20000 + 200) + 51), FN_STAT_ZOOM((20000 + 1180) + 3), | |||
127 | 0 | |||
128 | }; | |||
129 | rBindings.Invalidate( aInval ); | |||
130 | } | |||
131 | ||||
132 | namespace { | |||
133 | ||||
134 | // At first the zoom dialog | |||
135 | class SwPreviewZoomDlg : public weld::GenericDialogController | |||
136 | { | |||
137 | SwPagePreviewWin& m_rParent; | |||
138 | std::unique_ptr<weld::SpinButton> m_xRowEdit; | |||
139 | std::unique_ptr<weld::SpinButton> m_xColEdit; | |||
140 | ||||
141 | public: | |||
142 | SwPreviewZoomDlg(SwPagePreviewWin& rParent) | |||
143 | : GenericDialogController(rParent.GetFrameWeld(), "modules/swriter/ui/previewzoomdialog.ui", "PreviewZoomDialog") | |||
144 | , m_rParent(rParent) | |||
145 | , m_xRowEdit(m_xBuilder->weld_spin_button("rows")) | |||
146 | , m_xColEdit(m_xBuilder->weld_spin_button("cols")) | |||
147 | { | |||
148 | m_xRowEdit->set_value(rParent.GetRow()); | |||
149 | m_xColEdit->set_value(rParent.GetCol()); | |||
150 | } | |||
151 | ||||
152 | void execute() | |||
153 | { | |||
154 | if (run() == RET_OK) | |||
155 | { | |||
156 | m_rParent.CalcWish(sal_uInt8(m_xRowEdit->get_value()), sal_uInt8(m_xColEdit->get_value())); | |||
157 | } | |||
158 | } | |||
159 | }; | |||
160 | ||||
161 | } | |||
162 | ||||
163 | // all for SwPagePreviewWin | |||
164 | SwPagePreviewWin::SwPagePreviewWin( vcl::Window *pParent, SwPagePreview& rPView ) | |||
165 | : Window(pParent, WinBits(WB_CLIPCHILDREN)) | |||
166 | , mpViewShell(nullptr) | |||
167 | , mrView(rPView) | |||
168 | , mbCalcScaleForPreviewLayout(true) | |||
169 | , maPaintedPreviewDocRect(tools::Rectangle(0,0,0,0)) | |||
170 | , mpPgPreviewLayout(nullptr) | |||
171 | { | |||
172 | SetOutDevViewType( OutDevViewType::PrintPreview ); | |||
173 | SetHelpId(HID_PAGEPREVIEW"SW_HID_PAGEPREVIEW"); | |||
174 | SetFillColor( GetBackground().GetColor() ); | |||
175 | SetLineColor( GetBackground().GetColor()); | |||
176 | SetMapMode( MapMode(MapUnit::MapTwip) ); | |||
177 | ||||
178 | const SwMasterUsrPref *pUsrPref = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetUsrPref(false); | |||
179 | mnRow = pUsrPref->GetPagePrevRow(); // 1 row | |||
180 | mnCol = pUsrPref->GetPagePrevCol(); // 1 column | |||
181 | mnSttPage = USHRT_MAX(32767 *2 +1); | |||
182 | } | |||
183 | ||||
184 | SwPagePreviewWin::~SwPagePreviewWin() | |||
185 | { | |||
186 | } | |||
187 | ||||
188 | void SwPagePreviewWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) | |||
189 | { | |||
190 | if (!mpViewShell || !mpViewShell->GetLayout()) | |||
191 | return; | |||
192 | ||||
193 | if (USHRT_MAX(32767 *2 +1) == mnSttPage) // was never calculated ? (Init-Phase!) | |||
194 | { | |||
195 | // This is the size to which I always relate. | |||
196 | if (!maPxWinSize.Height() || !maPxWinSize.Width()) | |||
197 | maPxWinSize = GetOutputSizePixel(); | |||
198 | ||||
199 | tools::Rectangle aRect(rRenderContext.LogicToPixel(rRect)); | |||
200 | mpPgPreviewLayout->Prepare(1, Point(0,0), maPxWinSize, | |||
201 | mnSttPage, maPaintedPreviewDocRect); | |||
202 | SetSelectedPage(1); | |||
203 | mpPgPreviewLayout->Paint(rRenderContext, rRenderContext.PixelToLogic(aRect)); | |||
204 | SetPagePreview(mnRow, mnCol); | |||
205 | } | |||
206 | else | |||
207 | { | |||
208 | MapMode aMM(rRenderContext.GetMapMode()); | |||
209 | aMM.SetScaleX(maScale); | |||
210 | aMM.SetScaleY(maScale); | |||
211 | rRenderContext.SetMapMode(aMM); | |||
212 | mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(true); | |||
213 | mpPgPreviewLayout->Paint(rRenderContext, rRect); | |||
214 | mpPgPreviewLayout->GetParentViewShell().setOutputToWindow(false); | |||
215 | } | |||
216 | } | |||
217 | ||||
218 | void SwPagePreviewWin::CalcWish( sal_uInt8 nNewRow, sal_uInt8 nNewCol ) | |||
219 | { | |||
220 | if( !mpViewShell || !mpViewShell->GetLayout() ) | |||
221 | return; | |||
222 | ||||
223 | const sal_uInt8 nOldCol = mnCol; | |||
224 | mnRow = nNewRow; | |||
225 | mnCol = nNewCol; | |||
226 | const sal_uInt16 nPages = mnRow * mnCol; | |||
227 | const sal_uInt16 nLastSttPg = mrView.GetPageCount()+1 > nPages | |||
228 | ? mrView.GetPageCount()+1 - nPages : 0; | |||
229 | if( mnSttPage > nLastSttPg ) | |||
230 | mnSttPage = nLastSttPg; | |||
231 | ||||
232 | mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize ); | |||
233 | mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize, | |||
234 | mnSttPage, maPaintedPreviewDocRect ); | |||
235 | SetSelectedPage( mnSttPage ); | |||
236 | SetPagePreview(mnRow, mnCol); | |||
237 | maScale = GetMapMode().GetScaleX(); | |||
238 | ||||
239 | // If changes have taken place at the columns, the special case "single column" | |||
240 | // must be considered and corrected if necessary. | |||
241 | if( (1 == nOldCol) != (1 == mnCol) ) | |||
242 | mrView.ScrollDocSzChg(); | |||
243 | ||||
244 | // Order must be maintained! | |||
245 | // additional invalidate page status. | |||
246 | static sal_uInt16 aInval[] = | |||
247 | { | |||
248 | SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ZOOM_OUT(10000 + 97), SID_ZOOM_IN(10000 + 98), | |||
249 | FN_PREVIEW_ZOOM((20000 + 200) + 51), | |||
250 | FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), | |||
251 | FN_STAT_PAGE((20000 + 1180) + 1), FN_STAT_ZOOM((20000 + 1180) + 3), | |||
252 | FN_SHOW_TWO_PAGES((20000 + 1250) + 1), FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2), | |||
253 | 0 | |||
254 | }; | |||
255 | SfxBindings& rBindings = mrView.GetViewFrame()->GetBindings(); | |||
256 | rBindings.Invalidate( aInval ); | |||
257 | rBindings.Update( FN_SHOW_TWO_PAGES((20000 + 1250) + 1) ); | |||
258 | rBindings.Update( FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2) ); | |||
259 | // adjust scrollbars | |||
260 | mrView.ScrollViewSzChg(); | |||
261 | } | |||
262 | ||||
263 | // mnSttPage is Absolute | |||
264 | bool SwPagePreviewWin::MovePage( int eMoveMode ) | |||
265 | { | |||
266 | // number of pages up | |||
267 | const sal_uInt16 nPages = mnRow * mnCol; | |||
268 | sal_uInt16 nNewSttPage = mnSttPage; | |||
269 | const sal_uInt16 nPageCount = mrView.GetPageCount(); | |||
270 | const sal_uInt16 nDefSttPg = GetDefSttPage(); | |||
271 | bool bPaintPageAtFirstCol = true; | |||
272 | ||||
273 | switch( eMoveMode ) | |||
274 | { | |||
275 | case MV_PAGE_UP: | |||
276 | { | |||
277 | const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage ); | |||
278 | const sal_uInt16 nNewAbsSttPage = nRelSttPage - nPages > 0 ? | |||
279 | mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage - nPages ) : | |||
280 | nDefSttPg; | |||
281 | nNewSttPage = nNewAbsSttPage; | |||
282 | ||||
283 | const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() ); | |||
284 | const sal_uInt16 nNewRelSelPage = nRelSelPage - nPages > 0 ? | |||
285 | nRelSelPage - nPages : | |||
286 | 1; | |||
287 | SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewRelSelPage ) ); | |||
288 | ||||
289 | break; | |||
290 | } | |||
291 | case MV_PAGE_DOWN: | |||
292 | { | |||
293 | const sal_uInt16 nRelSttPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( mnSttPage ); | |||
294 | const sal_uInt16 nNewAbsSttPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSttPage + nPages ); | |||
295 | nNewSttPage = std::min(nNewAbsSttPage, nPageCount); | |||
296 | ||||
297 | const sal_uInt16 nRelSelPage = mpPgPreviewLayout->ConvertAbsoluteToRelativePageNum( SelectedPage() ); | |||
298 | const sal_uInt16 nNewAbsSelPage = mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nRelSelPage + nPages ); | |||
299 | SetSelectedPage( std::min(nNewAbsSelPage, nPageCount) ); | |||
300 | ||||
301 | break; | |||
302 | } | |||
303 | case MV_DOC_STT: | |||
304 | nNewSttPage = nDefSttPg; | |||
305 | SetSelectedPage( mpPgPreviewLayout->ConvertRelativeToAbsolutePageNum( nNewSttPage ? nNewSttPage : 1 ) ); | |||
306 | break; | |||
307 | case MV_DOC_END: | |||
308 | // correct calculation of new start page. | |||
309 | nNewSttPage = nPageCount; | |||
310 | SetSelectedPage( nPageCount ); | |||
311 | break; | |||
312 | ||||
313 | case MV_SELPAGE: | |||
314 | // <nNewSttPage> and <SelectedPage()> are already set. | |||
315 | // not start at first column, only if the | |||
316 | // complete preview layout columns doesn't fit into window. | |||
317 | if ( !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() ) | |||
318 | bPaintPageAtFirstCol = false; | |||
319 | break; | |||
320 | case MV_SCROLL: | |||
321 | // check, if paint page at first column | |||
322 | // has to be avoided | |||
323 | if ( !mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() || | |||
324 | !mpPgPreviewLayout->DoesPreviewLayoutColsFitIntoWindow() ) | |||
325 | bPaintPageAtFirstCol = false; | |||
326 | break; | |||
327 | case MV_NEWWINSIZE: | |||
328 | // nothing special to do. | |||
329 | break; | |||
330 | case MV_CALC: | |||
331 | // re-init page preview layout. | |||
332 | mpPgPreviewLayout->ReInit(); | |||
333 | ||||
334 | // correct calculation of new start page. | |||
335 | if( nNewSttPage > nPageCount ) | |||
336 | nNewSttPage = nPageCount; | |||
337 | ||||
338 | // correct selected page number | |||
339 | if( SelectedPage() > nPageCount ) | |||
340 | SetSelectedPage( nNewSttPage ? nNewSttPage : 1 ); | |||
341 | } | |||
342 | ||||
343 | mpPgPreviewLayout->Prepare( nNewSttPage, Point(0,0), maPxWinSize, | |||
344 | nNewSttPage, | |||
345 | maPaintedPreviewDocRect, bPaintPageAtFirstCol ); | |||
346 | if( nNewSttPage == mnSttPage && | |||
347 | eMoveMode != MV_SELPAGE ) | |||
348 | return false; | |||
349 | ||||
350 | SetPagePreview(mnRow, mnCol); | |||
351 | mnSttPage = nNewSttPage; | |||
352 | ||||
353 | // additional invalidate page status. | |||
354 | static sal_uInt16 aInval[] = | |||
355 | { | |||
356 | FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), | |||
357 | FN_STAT_PAGE((20000 + 1180) + 1), 0 | |||
358 | }; | |||
359 | ||||
360 | SfxBindings& rBindings = mrView.GetViewFrame()->GetBindings(); | |||
361 | rBindings.Invalidate( aInval ); | |||
362 | ||||
363 | return true; | |||
364 | } | |||
365 | ||||
366 | void SwPagePreviewWin::SetWinSize( const Size& rNewSize ) | |||
367 | { | |||
368 | // We always want the size as pixel units. | |||
369 | maPxWinSize = LogicToPixel( rNewSize ); | |||
370 | ||||
371 | if( USHRT_MAX(32767 *2 +1) == mnSttPage ) | |||
372 | { | |||
373 | mnSttPage = GetDefSttPage(); | |||
374 | SetSelectedPage( GetDefSttPage() ); | |||
375 | } | |||
376 | ||||
377 | if ( mbCalcScaleForPreviewLayout ) | |||
378 | { | |||
379 | mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize ); | |||
380 | maScale = GetMapMode().GetScaleX(); | |||
381 | } | |||
382 | mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize, | |||
383 | mnSttPage, maPaintedPreviewDocRect ); | |||
384 | if ( mbCalcScaleForPreviewLayout ) | |||
385 | { | |||
386 | SetSelectedPage( mnSttPage ); | |||
387 | mbCalcScaleForPreviewLayout = false; | |||
388 | } | |||
389 | SetPagePreview(mnRow, mnCol); | |||
390 | maScale = GetMapMode().GetScaleX(); | |||
391 | } | |||
392 | ||||
393 | OUString SwPagePreviewWin::GetStatusStr( sal_uInt16 nPageCnt ) const | |||
394 | { | |||
395 | // show physical and virtual page number of | |||
396 | // selected page, if it's visible. | |||
397 | const sal_uInt16 nPageNum = mpPgPreviewLayout->IsPageVisible( mpPgPreviewLayout->SelectedPage() ) | |||
398 | ? mpPgPreviewLayout->SelectedPage() : std::max<sal_uInt16>(mnSttPage, 1); | |||
399 | ||||
400 | OUStringBuffer aStatusStr; | |||
401 | const sal_uInt16 nVirtPageNum = mpPgPreviewLayout->GetVirtPageNumByPageNum( nPageNum ); | |||
402 | if( nVirtPageNum && nVirtPageNum != nPageNum ) | |||
403 | { | |||
404 | aStatusStr.append( OUString::number(nVirtPageNum) ).append( " " ); | |||
405 | } | |||
406 | aStatusStr.append( OUString::number(nPageNum) ).append( " / " ).append( OUString::number(nPageCnt) ); | |||
407 | return aStatusStr.makeStringAndClear(); | |||
408 | } | |||
409 | ||||
410 | void SwPagePreviewWin::KeyInput( const KeyEvent &rKEvt ) | |||
411 | { | |||
412 | const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); | |||
413 | bool bHandled = false; | |||
414 | if(!rKeyCode.GetModifier()) | |||
415 | { | |||
416 | sal_uInt16 nSlot = 0; | |||
417 | switch(rKeyCode.GetCode()) | |||
418 | { | |||
419 | case KEY_ADD : nSlot = SID_ZOOM_OUT(10000 + 97); break; | |||
420 | case KEY_ESCAPE: nSlot = FN_CLOSE_PAGEPREVIEW((20000 + 1250) + 4); break; | |||
421 | case KEY_SUBTRACT : nSlot = SID_ZOOM_IN(10000 + 98); break; | |||
422 | } | |||
423 | if(nSlot) | |||
424 | { | |||
425 | bHandled = true; | |||
426 | mrView.GetViewFrame()->GetDispatcher()->Execute( | |||
427 | nSlot, SfxCallMode::ASYNCHRON ); | |||
428 | } | |||
429 | } | |||
430 | if( !bHandled && !mrView.KeyInput( rKEvt ) ) | |||
431 | Window::KeyInput( rKEvt ); | |||
432 | } | |||
433 | ||||
434 | void SwPagePreviewWin::Command( const CommandEvent& rCEvt ) | |||
435 | { | |||
436 | bool bCallBase = true; | |||
437 | switch( rCEvt.GetCommand() ) | |||
438 | { | |||
439 | case CommandEventId::ContextMenu: | |||
440 | SfxDispatcher::ExecutePopup(); | |||
441 | bCallBase = false; | |||
442 | break; | |||
443 | ||||
444 | case CommandEventId::Wheel: | |||
445 | case CommandEventId::StartAutoScroll: | |||
446 | case CommandEventId::AutoScroll: | |||
447 | { | |||
448 | const CommandWheelData* pData = rCEvt.GetWheelData(); | |||
449 | if( pData ) | |||
450 | { | |||
451 | const CommandWheelData aDataNew(pData->GetDelta(),pData->GetNotchDelta(),COMMAND_WHEEL_PAGESCROLL(sal_uLong(0xFFFFFFFF)), | |||
452 | pData->GetMode(),pData->GetModifier(),pData->IsHorz(), pData->IsDeltaPixel()); | |||
453 | const CommandEvent aEvent( rCEvt.GetMousePosPixel(),rCEvt.GetCommand(),rCEvt.IsMouseEvent(),&aDataNew); | |||
454 | bCallBase = !mrView.HandleWheelCommands( aEvent ); | |||
455 | } | |||
456 | else | |||
457 | bCallBase = !mrView.HandleWheelCommands( rCEvt ); | |||
458 | } | |||
459 | break; | |||
460 | default: | |||
461 | ; | |||
462 | } | |||
463 | ||||
464 | if( bCallBase ) | |||
465 | Window::Command( rCEvt ); | |||
466 | } | |||
467 | ||||
468 | void SwPagePreviewWin::MouseButtonDown( const MouseEvent& rMEvt ) | |||
469 | { | |||
470 | // consider single-click to set selected page | |||
471 | if( MOUSE_LEFT(sal_uInt16(0x0001)) != ( rMEvt.GetModifier() + rMEvt.GetButtons() ) ) | |||
472 | return; | |||
473 | ||||
474 | Point aPreviewPos( PixelToLogic( rMEvt.GetPosPixel() ) ); | |||
475 | Point aDocPos; | |||
476 | bool bPosInEmptyPage; | |||
477 | sal_uInt16 nNewSelectedPage; | |||
478 | bool bIsDocPos = | |||
479 | mpPgPreviewLayout->IsPreviewPosInDocPreviewPage( aPreviewPos, | |||
480 | aDocPos, bPosInEmptyPage, nNewSelectedPage ); | |||
481 | if ( bIsDocPos && rMEvt.GetClicks() == 2 ) | |||
482 | { | |||
483 | // close page preview, set new cursor position and switch to | |||
484 | // normal view. | |||
485 | OUString sNewCursorPos = OUString::number( aDocPos.X() ) + ";" + | |||
486 | OUString::number( aDocPos.Y() ) + ";"; | |||
487 | mrView.SetNewCursorPos( sNewCursorPos ); | |||
488 | ||||
489 | SfxViewFrame *pTmpFrame = mrView.GetViewFrame(); | |||
490 | pTmpFrame->GetBindings().Execute( SID_VIEWSHELL0(5000 + 630), nullptr, | |||
491 | SfxCallMode::ASYNCHRON ); | |||
492 | } | |||
493 | else if ( bIsDocPos || bPosInEmptyPage ) | |||
494 | { | |||
495 | // show clicked page as the selected one | |||
496 | mpPgPreviewLayout->MarkNewSelectedPage( nNewSelectedPage ); | |||
497 | GetViewShell()->ShowPreviewSelection( nNewSelectedPage ); | |||
498 | // adjust position at vertical scrollbar. | |||
499 | if ( mpPgPreviewLayout->DoesPreviewLayoutRowsFitIntoWindow() ) | |||
500 | { | |||
501 | mrView.SetVScrollbarThumbPos( nNewSelectedPage ); | |||
502 | } | |||
503 | // invalidate page status. | |||
504 | static sal_uInt16 aInval[] = | |||
505 | { | |||
506 | FN_STAT_PAGE((20000 + 1180) + 1), 0 | |||
507 | }; | |||
508 | SfxBindings& rBindings = mrView.GetViewFrame()->GetBindings(); | |||
509 | rBindings.Invalidate( aInval ); | |||
510 | } | |||
511 | } | |||
512 | ||||
513 | // Set user prefs or view options | |||
514 | ||||
515 | void SwPagePreviewWin::SetPagePreview( sal_uInt8 nRow, sal_uInt8 nCol ) | |||
516 | { | |||
517 | SwMasterUsrPref *pOpt = const_cast<SwMasterUsrPref *>(SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetUsrPref(false)); | |||
518 | ||||
519 | if (nRow != pOpt->GetPagePrevRow() || nCol != pOpt->GetPagePrevCol()) | |||
520 | { | |||
521 | pOpt->SetPagePrevRow( nRow ); | |||
522 | pOpt->SetPagePrevCol( nCol ); | |||
523 | pOpt->SetModified(); | |||
524 | ||||
525 | // Update scrollbar! | |||
526 | mrView.ScrollViewSzChg(); | |||
527 | } | |||
528 | } | |||
529 | ||||
530 | /** get selected page in document preview */ | |||
531 | sal_uInt16 SwPagePreviewWin::SelectedPage() const | |||
532 | { | |||
533 | return mpPgPreviewLayout->SelectedPage(); | |||
534 | } | |||
535 | ||||
536 | /** set selected page number in document preview */ | |||
537 | void SwPagePreviewWin::SetSelectedPage( sal_uInt16 _nSelectedPageNum ) | |||
538 | { | |||
539 | mpPgPreviewLayout->SetSelectedPage( _nSelectedPageNum ); | |||
540 | } | |||
541 | ||||
542 | /** method to enable/disable book preview */ | |||
543 | bool SwPagePreviewWin::SetBookPreviewMode( const bool _bBookPreview ) | |||
544 | { | |||
545 | return mpPgPreviewLayout->SetBookPreviewMode( _bBookPreview, | |||
546 | mnSttPage, | |||
547 | maPaintedPreviewDocRect ); | |||
548 | } | |||
549 | ||||
550 | void SwPagePreviewWin::DataChanged( const DataChangedEvent& rDCEvt ) | |||
551 | { | |||
552 | Window::DataChanged( rDCEvt ); | |||
553 | ||||
554 | switch( rDCEvt.GetType() ) | |||
555 | { | |||
556 | case DataChangedEventType::SETTINGS: | |||
557 | // Rearrange the scrollbars or trigger resize, because the | |||
558 | // size of the scrollbars may have be changed. Also the | |||
559 | // size of the scrollbars has to be retrieved from the settings | |||
560 | // out of the resize handler. | |||
561 | if( rDCEvt.GetFlags() & AllSettingsFlags::STYLE ) | |||
562 | mrView.InvalidateBorder(); // Scrollbar widths | |||
563 | // zoom has to be disabled if Accessibility support is switched on | |||
564 | lcl_InvalidateZoomSlots(mrView.GetViewFrame()->GetBindings()); | |||
565 | break; | |||
566 | ||||
567 | case DataChangedEventType::PRINTER: | |||
568 | case DataChangedEventType::DISPLAY: | |||
569 | case DataChangedEventType::FONTS: | |||
570 | case DataChangedEventType::FONTSUBSTITUTION: | |||
571 | mrView.GetDocShell()->UpdateFontList(); // Font change | |||
572 | mpViewShell->InvalidateLayout(true); | |||
573 | if ( mpViewShell->GetWin() ) | |||
574 | mpViewShell->GetWin()->Invalidate(); | |||
575 | break; | |||
576 | default: break; | |||
577 | } | |||
578 | } | |||
579 | ||||
580 | /** help method to execute SfxRequest FN_PAGEUP and FN_PAGEDOWN */ | |||
581 | void SwPagePreview::ExecPgUpAndPgDown( const bool _bPgUp, | |||
582 | SfxRequest* _pReq ) | |||
583 | { | |||
584 | SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout(); | |||
585 | // check, if top/bottom of preview is *not* already visible. | |||
586 | if( pPagePreviewLay->GetWinPagesScrollAmount( _bPgUp ? -1 : 1 ) != 0 ) | |||
587 | { | |||
588 | if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() && | |||
589 | pPagePreviewLay->DoesPreviewLayoutColsFitIntoWindow() ) | |||
590 | { | |||
591 | const int eMvMode = _bPgUp ? | |||
592 | SwPagePreviewWin::MV_PAGE_UP : | |||
593 | SwPagePreviewWin::MV_PAGE_DOWN; | |||
594 | if ( ChgPage( eMvMode ) ) | |||
595 | m_pViewWin->Invalidate(); | |||
596 | } | |||
597 | else | |||
598 | { | |||
599 | SwTwips nScrollAmount; | |||
600 | sal_uInt16 nNewSelectedPageNum = 0; | |||
601 | const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol(); | |||
602 | if( _bPgUp ) | |||
603 | { | |||
604 | if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() ) | |||
605 | { | |||
606 | nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( -1 ); | |||
607 | if ( (m_pViewWin->SelectedPage() - nVisPages) > 0 ) | |||
608 | nNewSelectedPageNum = m_pViewWin->SelectedPage() - nVisPages; | |||
609 | else | |||
610 | nNewSelectedPageNum = 1; | |||
611 | } | |||
612 | else | |||
613 | nScrollAmount = - std::min( m_pViewWin->GetOutputSize().Height(), | |||
614 | m_pViewWin->GetPaintedPreviewDocRect().Top() ); | |||
615 | } | |||
616 | else | |||
617 | { | |||
618 | if ( pPagePreviewLay->DoesPreviewLayoutRowsFitIntoWindow() ) | |||
619 | { | |||
620 | nScrollAmount = pPagePreviewLay->GetWinPagesScrollAmount( 1 ); | |||
621 | if ( (m_pViewWin->SelectedPage() + nVisPages) <= mnPageCount ) | |||
622 | nNewSelectedPageNum = m_pViewWin->SelectedPage() + nVisPages; | |||
623 | else | |||
624 | nNewSelectedPageNum = mnPageCount; | |||
625 | } | |||
626 | else | |||
627 | nScrollAmount = std::min( m_pViewWin->GetOutputSize().Height(), | |||
628 | ( pPagePreviewLay->GetPreviewDocSize().Height() - | |||
629 | m_pViewWin->GetPaintedPreviewDocRect().Bottom() ) ); | |||
630 | } | |||
631 | m_pViewWin->Scroll( 0, nScrollAmount ); | |||
632 | if ( nNewSelectedPageNum != 0 ) | |||
633 | { | |||
634 | m_pViewWin->SetSelectedPage( nNewSelectedPageNum ); | |||
635 | } | |||
636 | ScrollViewSzChg(); | |||
637 | // additional invalidate page status. | |||
638 | static sal_uInt16 aInval[] = | |||
639 | { | |||
640 | FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), | |||
641 | FN_STAT_PAGE((20000 + 1180) + 1), 0 | |||
642 | }; | |||
643 | SfxBindings& rBindings = GetViewFrame()->GetBindings(); | |||
644 | rBindings.Invalidate( aInval ); | |||
645 | m_pViewWin->Invalidate(); | |||
646 | } | |||
647 | } | |||
648 | ||||
649 | if ( _pReq ) | |||
650 | _pReq->Done(); | |||
651 | } | |||
652 | ||||
653 | // Then all for the SwPagePreview | |||
654 | void SwPagePreview::Execute( SfxRequest &rReq ) | |||
655 | { | |||
656 | int eMvMode = SwPagePreviewWin::MV_DOC_END; | |||
657 | sal_uInt8 nRow = 1; | |||
658 | bool bRefresh = true; | |||
659 | ||||
660 | switch(rReq.GetSlot()) | |||
661 | { | |||
662 | case FN_REFRESH_VIEW((20000 + 200) + 1): | |||
663 | case FN_STAT_PAGE((20000 + 1180) + 1): | |||
664 | case FN_STAT_ZOOM((20000 + 1180) + 3): | |||
665 | break; | |||
666 | ||||
667 | case FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2): | |||
668 | { | |||
669 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
670 | if( pArgs && pArgs->Count() >= 2 ) | |||
671 | { | |||
672 | sal_uInt8 nCols = static_cast<sal_uInt8>(pArgs->Get(SID_ATTR_TABLE_COLUMNTypedWhichId<SfxUInt16Item>( 10000 + 218 )).GetValue()); | |||
673 | sal_uInt8 nRows = static_cast<sal_uInt8>(pArgs->Get(SID_ATTR_TABLE_ROWTypedWhichId<SfxUInt16Item>( 10000 + 219 )).GetValue()); | |||
674 | m_pViewWin->CalcWish( nRows, nCols ); | |||
675 | ||||
676 | } | |||
677 | else | |||
678 | { | |||
679 | SwPreviewZoomDlg aDlg(*m_pViewWin); | |||
680 | aDlg.execute(); | |||
681 | } | |||
682 | } | |||
683 | break; | |||
684 | case FN_SHOW_BOOKVIEW((20000 + 1250) + 5): | |||
685 | { | |||
686 | const SfxItemSet* pArgs = rReq.GetArgs(); | |||
687 | const SfxPoolItem* pItem; | |||
688 | bool bBookPreview = GetViewShell()->GetViewOptions()->IsPagePrevBookview(); | |||
689 | if( pArgs && SfxItemState::SET == pArgs->GetItemState( FN_SHOW_BOOKVIEW((20000 + 1250) + 5), false, &pItem ) ) | |||
690 | { | |||
691 | bBookPreview = static_cast< const SfxBoolItem* >( pItem )->GetValue(); | |||
692 | const_cast<SwViewOption*>(GetViewShell()->GetViewOptions())->SetPagePrevBookview( bBookPreview ); | |||
693 | // cast is not gentleman like, but it's common use in writer and in this case | |||
694 | } | |||
695 | if ( m_pViewWin->SetBookPreviewMode( bBookPreview ) ) | |||
696 | { | |||
697 | // book preview mode changed. Thus, adjust scrollbars and | |||
698 | // invalidate corresponding states. | |||
699 | ScrollViewSzChg(); | |||
700 | static sal_uInt16 aInval[] = | |||
701 | { | |||
702 | FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), | |||
703 | FN_STAT_PAGE((20000 + 1180) + 1), FN_SHOW_BOOKVIEW((20000 + 1250) + 5), 0 | |||
704 | }; | |||
705 | SfxBindings& rBindings = GetViewFrame()->GetBindings(); | |||
706 | rBindings.Invalidate( aInval ); | |||
707 | m_pViewWin->Invalidate(); | |||
708 | } | |||
709 | ||||
710 | } | |||
711 | break; | |||
712 | case FN_SHOW_TWO_PAGES((20000 + 1250) + 1): | |||
713 | m_pViewWin->CalcWish( nRow, 2 ); | |||
714 | break; | |||
715 | ||||
716 | case FN_SHOW_SINGLE_PAGE((20000 + 1250) + 6): | |||
717 | m_pViewWin->CalcWish( nRow, 1 ); | |||
718 | break; | |||
719 | ||||
720 | case FN_PREVIEW_ZOOM((20000 + 200) + 51): | |||
721 | case SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0): | |||
722 | { | |||
723 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
724 | const SfxPoolItem* pItem; | |||
725 | ScopedVclPtr<AbstractSvxZoomDialog> pDlg; | |||
726 | if(!pArgs) | |||
727 | { | |||
728 | SfxItemSet aCoreSet(GetPool(), svl::Items<SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0)>{}); | |||
729 | const SwViewOption* pVOpt = GetViewShell()->GetViewOptions(); | |||
730 | SvxZoomItem aZoom( pVOpt->GetZoomType(), pVOpt->GetZoom() ); | |||
731 | aZoom.SetValueSet( | |||
732 | SvxZoomEnableFlags::N50| | |||
733 | SvxZoomEnableFlags::N75| | |||
734 | SvxZoomEnableFlags::N100| | |||
735 | SvxZoomEnableFlags::N150| | |||
736 | SvxZoomEnableFlags::N200| | |||
737 | SvxZoomEnableFlags::WHOLEPAGE); | |||
738 | aCoreSet.Put( aZoom ); | |||
739 | ||||
740 | SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); | |||
741 | pDlg.disposeAndReset(pFact->CreateSvxZoomDialog(GetViewFrame()->GetWindow().GetFrameWeld(), aCoreSet)); | |||
742 | pDlg->SetLimits( MINZOOM20, MAXZOOM600 ); | |||
743 | ||||
744 | if( pDlg->Execute() != RET_CANCEL ) | |||
745 | pArgs = pDlg->GetOutputItemSet(); | |||
746 | } | |||
747 | if( pArgs ) | |||
748 | { | |||
749 | SvxZoomType eType = SvxZoomType::PERCENT; | |||
750 | sal_uInt16 nZoomFactor = USHRT_MAX(32767 *2 +1); | |||
751 | if(SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0), true, &pItem)) | |||
752 | { | |||
753 | eType = static_cast<const SvxZoomItem *>(pItem)->GetType(); | |||
754 | nZoomFactor = static_cast<const SvxZoomItem *>(pItem)->GetValue(); | |||
755 | } | |||
756 | else if(SfxItemState::SET == pArgs->GetItemState(FN_PREVIEW_ZOOM((20000 + 200) + 51), true, &pItem)) | |||
757 | nZoomFactor = static_cast<const SfxUInt16Item *>(pItem)->GetValue(); | |||
758 | if(USHRT_MAX(32767 *2 +1) != nZoomFactor) | |||
759 | SetZoom(eType, nZoomFactor); | |||
760 | } | |||
761 | } | |||
762 | break; | |||
763 | case SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) : | |||
764 | { | |||
765 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
766 | const SfxPoolItem* pItem; | |||
767 | ||||
768 | if ( pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_ZOOMSLIDER( 10000 + 1065 ), true, &pItem ) ) | |||
769 | { | |||
770 | const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue(); | |||
771 | SetZoom( SvxZoomType::PERCENT, nCurrentZoom ); | |||
772 | } | |||
773 | } | |||
774 | break; | |||
775 | case SID_ZOOM_IN(10000 + 98): | |||
776 | case SID_ZOOM_OUT(10000 + 97): | |||
777 | { | |||
778 | const SwViewOption* pVOpt = GetViewShell()->GetViewOptions(); | |||
779 | SetZoom(SvxZoomType::PERCENT, | |||
780 | lcl_GetNextZoomStep(pVOpt->GetZoom(), SID_ZOOM_IN(10000 + 98) == rReq.GetSlot())); | |||
781 | } | |||
782 | break; | |||
783 | case FN_CHAR_LEFT((20000 + 900) + 1 ): | |||
784 | case FN_CHAR_RIGHT((20000 + 900) + 2 ): | |||
785 | case FN_LINE_UP((20000 + 900) + 3 ): | |||
786 | case FN_LINE_DOWN((20000 + 900) + 4 ): | |||
787 | { | |||
788 | SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout(); | |||
789 | sal_uInt16 nNewSelectedPage; | |||
790 | sal_uInt16 nNewStartPage; | |||
791 | Point aNewStartPos; | |||
792 | sal_Int16 nHoriMove = 0; | |||
793 | sal_Int16 nVertMove = 0; | |||
794 | switch(rReq.GetSlot()) | |||
795 | { | |||
796 | case FN_CHAR_LEFT((20000 + 900) + 1 ): nHoriMove = -1; break; | |||
797 | case FN_CHAR_RIGHT((20000 + 900) + 2 ): nHoriMove = 1; break; | |||
798 | case FN_LINE_UP((20000 + 900) + 3 ): nVertMove = -1; break; | |||
799 | case FN_LINE_DOWN((20000 + 900) + 4 ): nVertMove = 1; break; | |||
800 | } | |||
801 | pPagePreviewLay->CalcStartValuesForSelectedPageMove( nHoriMove, nVertMove, | |||
802 | nNewSelectedPage, nNewStartPage, aNewStartPos ); | |||
803 | if ( m_pViewWin->SelectedPage() != nNewSelectedPage ) | |||
804 | { | |||
805 | if ( pPagePreviewLay->IsPageVisible( nNewSelectedPage ) ) | |||
806 | { | |||
807 | pPagePreviewLay->MarkNewSelectedPage( nNewSelectedPage ); | |||
808 | // adjust position at vertical scrollbar. | |||
809 | SetVScrollbarThumbPos( nNewSelectedPage ); | |||
810 | bRefresh = false; | |||
811 | } | |||
812 | else | |||
813 | { | |||
814 | m_pViewWin->SetSelectedPage( nNewSelectedPage ); | |||
815 | m_pViewWin->SetSttPage( nNewStartPage ); | |||
816 | bRefresh = ChgPage( SwPagePreviewWin::MV_SELPAGE ); | |||
817 | } | |||
818 | GetViewShell()->ShowPreviewSelection( nNewSelectedPage ); | |||
819 | // invalidate page status. | |||
820 | static sal_uInt16 aInval[] = | |||
821 | { | |||
822 | FN_STAT_PAGE((20000 + 1180) + 1), 0 | |||
823 | }; | |||
824 | SfxBindings& rBindings = GetViewFrame()->GetBindings(); | |||
825 | rBindings.Invalidate( aInval ); | |||
826 | rReq.Done(); | |||
827 | } | |||
828 | else | |||
829 | { | |||
830 | bRefresh = false; | |||
831 | } | |||
832 | break; | |||
833 | } | |||
834 | case FN_PAGEUP((20000 + 900) + 37): | |||
835 | case FN_PAGEDOWN((20000 + 900) + 38): | |||
836 | { | |||
837 | ExecPgUpAndPgDown( rReq.GetSlot() == FN_PAGEUP((20000 + 900) + 37), &rReq ); | |||
838 | break; | |||
839 | } | |||
840 | case SID_JUMP_TO_SPECIFIC_PAGE((20000 + 900) + 92): | |||
841 | { | |||
842 | const SfxItemSet *pArgs = rReq.GetArgs(); | |||
843 | if( pArgs && pArgs->Count()) | |||
844 | { | |||
845 | sal_uInt16 nPageNum = static_cast<const SfxUInt16Item &>(pArgs->Get(SID_JUMP_TO_SPECIFIC_PAGE((20000 + 900) + 92))).GetValue(); | |||
846 | ||||
847 | if( nPageNum > 0 && nPageNum <= mnPageCount ) | |||
848 | { | |||
849 | m_pViewWin->SetSttPage( nPageNum); | |||
850 | m_pViewWin->SetSelectedPage( nPageNum ); | |||
851 | ChgPage( SwPagePreviewWin::MV_SPECIFIC_PAGE, false ); | |||
852 | ScrollViewSzChg(); | |||
853 | } | |||
854 | } | |||
855 | } | |||
856 | break; | |||
857 | case FN_START_OF_LINE((20000 + 900) + 5 ): | |||
858 | case FN_START_OF_DOCUMENT((20000 + 900) + 7 ): | |||
859 | eMvMode = SwPagePreviewWin::MV_DOC_STT; | |||
860 | [[fallthrough]]; | |||
861 | case FN_END_OF_LINE((20000 + 900) + 6 ): | |||
862 | case FN_END_OF_DOCUMENT((20000 + 900) + 8): | |||
863 | m_pViewWin->SetSelectedPage(eMvMode == SwPagePreviewWin::MV_DOC_STT ? 1 : mnPageCount); | |||
864 | { | |||
865 | bool bRet = ChgPage( eMvMode ); | |||
866 | // return value for Basic | |||
867 | rReq.SetReturnValue(SfxBoolItem(rReq.GetSlot(), !bRet)); | |||
868 | ||||
869 | bRefresh = bRet; | |||
870 | rReq.Done(); | |||
871 | } | |||
872 | break; | |||
873 | ||||
874 | case FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3): | |||
875 | { | |||
876 | const SwPagePreviewPrtData* pPPVPD = m_pViewWin->GetViewShell()->GetDoc()->GetPreviewPrtData(); | |||
877 | // The thing with the orientation | |||
878 | if(pPPVPD) | |||
879 | { | |||
880 | SfxPrinter* pPrinter = GetPrinter( true ); | |||
881 | if((pPrinter->GetOrientation() == Orientation::Landscape) | |||
882 | != pPPVPD->GetLandscape()) | |||
883 | pPrinter->SetOrientation(pPPVPD->GetLandscape() ? Orientation::Landscape : Orientation::Portrait); | |||
884 | } | |||
885 | ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false ); | |||
886 | m_bNormalPrint = false; | |||
887 | rReq.SetSlot( SID_PRINTDOC(5000 + 504) ); | |||
888 | SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() ); | |||
889 | rReq.SetSlot( FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3) ); | |||
890 | return; | |||
891 | } | |||
892 | case SID_PRINTDOCDIRECT(5000 + 509): | |||
893 | case SID_PRINTDOC(5000 + 504): | |||
894 | ::SetAppPrintOptions( m_pViewWin->GetViewShell(), false ); | |||
895 | m_bNormalPrint = true; | |||
896 | SfxViewShell::ExecuteSlot( rReq, SfxViewShell::GetInterface() ); | |||
897 | return; | |||
898 | case FN_CLOSE_PAGEPREVIEW((20000 + 1250) + 4): | |||
899 | case SID_PRINTPREVIEW(5000 + 325): | |||
900 | // print preview is now always in the same frame as the tab view | |||
901 | // -> always switch this frame back to normal view | |||
902 | // (ScTabViewShell ctor reads stored view data) | |||
903 | GetViewFrame()->GetDispatcher()->Execute( SID_VIEWSHELL0(5000 + 630), SfxCallMode::ASYNCHRON ); | |||
904 | break; | |||
905 | case FN_INSERT_BREAK((20000 + 300) + 3): | |||
906 | { | |||
907 | sal_uInt16 nSelPage = m_pViewWin->SelectedPage(); | |||
908 | //if a dummy page is selected (e.g. a non-existing right/left page) | |||
909 | //the direct neighbor is used | |||
910 | if(GetViewShell()->IsDummyPage( nSelPage ) && GetViewShell()->IsDummyPage( --nSelPage )) | |||
911 | nSelPage +=2; | |||
912 | m_nNewPage = nSelPage; | |||
913 | SfxViewFrame *pTmpFrame = GetViewFrame(); | |||
914 | pTmpFrame->GetBindings().Execute( SID_VIEWSHELL0(5000 + 630), nullptr, | |||
915 | SfxCallMode::ASYNCHRON ); | |||
916 | } | |||
917 | break; | |||
918 | default: | |||
919 | OSL_ENSURE(false, "wrong dispatcher")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx" ":" "919" ": "), "%s", "wrong dispatcher"); } } while (false ); | |||
920 | return; | |||
921 | } | |||
922 | ||||
923 | if( bRefresh ) | |||
924 | m_pViewWin->Invalidate(); | |||
925 | } | |||
926 | ||||
927 | void SwPagePreview::GetState( SfxItemSet& rSet ) | |||
928 | { | |||
929 | SfxWhichIter aIter(rSet); | |||
930 | sal_uInt16 nWhich = aIter.FirstWhich(); | |||
931 | OSL_ENSURE(nWhich, "empty set")do { if (true && (!(nWhich))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx" ":" "931" ": "), "%s", "empty set"); } } while (false); | |||
932 | SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout(); | |||
933 | ||||
934 | while(nWhich) | |||
935 | { | |||
936 | switch(nWhich) | |||
937 | { | |||
938 | case SID_BROWSER_MODE(5000 + 1313): | |||
939 | case FN_PRINT_LAYOUT((20000 + 200) + 37): | |||
940 | rSet.DisableItem(nWhich); | |||
941 | break; | |||
942 | case FN_START_OF_DOCUMENT((20000 + 900) + 7 ): | |||
943 | { | |||
944 | if ( pPagePreviewLay->IsPageVisible( 1 ) ) | |||
945 | rSet.DisableItem(nWhich); | |||
946 | break; | |||
947 | } | |||
948 | case FN_END_OF_DOCUMENT((20000 + 900) + 8): | |||
949 | { | |||
950 | if ( pPagePreviewLay->IsPageVisible( mnPageCount ) ) | |||
951 | rSet.DisableItem(nWhich); | |||
952 | break; | |||
953 | } | |||
954 | case FN_PAGEUP((20000 + 900) + 37): | |||
955 | { | |||
956 | if( pPagePreviewLay->GetWinPagesScrollAmount( -1 ) == 0 ) | |||
957 | rSet.DisableItem(nWhich); | |||
958 | break; | |||
959 | } | |||
960 | case FN_PAGEDOWN((20000 + 900) + 38): | |||
961 | { | |||
962 | if( pPagePreviewLay->GetWinPagesScrollAmount( 1 ) == 0 ) | |||
963 | rSet.DisableItem(nWhich); | |||
964 | break; | |||
965 | } | |||
966 | ||||
967 | case FN_STAT_PAGE((20000 + 1180) + 1): | |||
968 | { | |||
969 | OUString aStr = m_sPageStr + m_pViewWin->GetStatusStr( mnPageCount ); | |||
970 | rSet.Put( SfxStringItem( nWhich, aStr) ); | |||
971 | } | |||
972 | break; | |||
973 | ||||
974 | case SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0): | |||
975 | case FN_STAT_ZOOM((20000 + 1180) + 3): | |||
976 | { | |||
977 | const SwViewOption* pVOpt = GetViewShell()->GetViewOptions(); | |||
978 | SvxZoomItem aZoom(pVOpt->GetZoomType(), pVOpt->GetZoom()); | |||
979 | aZoom.SetValueSet( | |||
980 | SvxZoomEnableFlags::N50| | |||
981 | SvxZoomEnableFlags::N75| | |||
982 | SvxZoomEnableFlags::N100| | |||
983 | SvxZoomEnableFlags::N150| | |||
984 | SvxZoomEnableFlags::N200); | |||
985 | rSet.Put( aZoom ); | |||
986 | } | |||
987 | break; | |||
988 | case SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) : | |||
989 | { | |||
990 | const SwViewOption* pVOpt = GetViewShell()->GetViewOptions(); | |||
991 | const sal_uInt16 nCurrentZoom = pVOpt->GetZoom(); | |||
992 | SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM20, MAXZOOM600 ); | |||
993 | aZoomSliderItem.AddSnappingPoint( 100 ); | |||
994 | rSet.Put( aZoomSliderItem ); | |||
995 | } | |||
996 | break; | |||
997 | case FN_PREVIEW_ZOOM((20000 + 200) + 51): | |||
998 | { | |||
999 | const SwViewOption* pVOpt = GetViewShell()->GetViewOptions(); | |||
1000 | rSet.Put(SfxUInt16Item(nWhich, pVOpt->GetZoom())); | |||
1001 | } | |||
1002 | break; | |||
1003 | case SID_ZOOM_IN(10000 + 98): | |||
1004 | case SID_ZOOM_OUT(10000 + 97): | |||
1005 | { | |||
1006 | const SwViewOption* pVOpt = GetViewShell()->GetViewOptions(); | |||
1007 | if((SID_ZOOM_OUT(10000 + 97) == nWhich && pVOpt->GetZoom() >= MAX_PREVIEW_ZOOM600)|| | |||
1008 | (SID_ZOOM_IN(10000 + 98) == nWhich && pVOpt->GetZoom() <= MIN_PREVIEW_ZOOM25)) | |||
1009 | { | |||
1010 | rSet.DisableItem(nWhich); | |||
1011 | } | |||
1012 | } | |||
1013 | break; | |||
1014 | case FN_SHOW_MULTIPLE_PAGES((20000 + 1250) + 2): | |||
1015 | // should never be disabled | |||
1016 | break; | |||
1017 | case FN_SHOW_BOOKVIEW((20000 + 1250) + 5): | |||
1018 | { | |||
1019 | bool b = GetViewShell()->GetViewOptions()->IsPagePrevBookview(); | |||
1020 | rSet.Put(SfxBoolItem(nWhich, b)); | |||
1021 | } | |||
1022 | break; | |||
1023 | ||||
1024 | case FN_SHOW_TWO_PAGES((20000 + 1250) + 1): | |||
1025 | if( 2 == m_pViewWin->GetCol() && 1 == m_pViewWin->GetRow() ) | |||
1026 | rSet.DisableItem( nWhich ); | |||
1027 | break; | |||
1028 | ||||
1029 | case FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3): | |||
1030 | // has the same status like the normal printing | |||
1031 | { | |||
1032 | const SfxPoolItem* pItem; | |||
1033 | SfxItemSet aSet( *rSet.GetPool(), svl::Items<SID_PRINTDOC(5000 + 504), SID_PRINTDOC(5000 + 504)>{} ); | |||
1034 | GetSlotState( SID_PRINTDOC(5000 + 504), SfxViewShell::GetInterface(), &aSet ); | |||
1035 | if( SfxItemState::DISABLED == aSet.GetItemState( SID_PRINTDOC(5000 + 504), | |||
1036 | false, &pItem )) | |||
1037 | rSet.DisableItem( nWhich ); | |||
1038 | else if( SfxItemState::SET == aSet.GetItemState( SID_PRINTDOC(5000 + 504), | |||
1039 | false, &pItem )) | |||
1040 | { | |||
1041 | const_cast<SfxPoolItem*>(pItem)->SetWhich( FN_PRINT_PAGEPREVIEW((20000 + 1250) + 3) ); | |||
1042 | rSet.Put( *pItem ); | |||
1043 | } | |||
1044 | } | |||
1045 | break; | |||
1046 | ||||
1047 | case SID_PRINTPREVIEW(5000 + 325): | |||
1048 | rSet.Put( SfxBoolItem( nWhich, true ) ); | |||
1049 | break; | |||
1050 | ||||
1051 | case SID_PRINTDOC(5000 + 504): | |||
1052 | case SID_PRINTDOCDIRECT(5000 + 509): | |||
1053 | GetSlotState( nWhich, SfxViewShell::GetInterface(), &rSet ); | |||
1054 | break; | |||
1055 | } | |||
1056 | nWhich = aIter.NextWhich(); | |||
1057 | } | |||
1058 | } | |||
1059 | ||||
1060 | void SwPagePreview::StateUndo(SfxItemSet& rSet) | |||
1061 | { | |||
1062 | SfxWhichIter aIter(rSet); | |||
1063 | sal_uInt16 nWhich = aIter.FirstWhich(); | |||
1064 | ||||
1065 | while (nWhich) | |||
1066 | { | |||
1067 | rSet.DisableItem(nWhich); | |||
1068 | nWhich = aIter.NextWhich(); | |||
1069 | } | |||
1070 | } | |||
1071 | ||||
1072 | void SwPagePreview::Init() | |||
1073 | { | |||
1074 | if ( GetViewShell()->HasDrawView() ) | |||
1075 | GetViewShell()->GetDrawView()->SetAnimationEnabled( false ); | |||
1076 | ||||
1077 | m_bNormalPrint = true; | |||
1078 | ||||
1079 | // Check and process the DocSize. The shell could not be found via | |||
1080 | // the handler, because the shell is unknown to the SFX management | |||
1081 | // within the CTOR phase. | |||
1082 | ||||
1083 | const SwViewOption * pPrefs = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetUsrPref(false); | |||
1084 | ||||
1085 | mbHScrollbarEnabled = pPrefs->IsViewHScrollBar(); | |||
1086 | mbVScrollbarEnabled = pPrefs->IsViewVScrollBar(); | |||
1087 | ||||
1088 | // Update the fields | |||
1089 | // ATTENTION: Do cast the EditShell up, to use the SS. | |||
1090 | // At the methods the current shell will be queried! | |||
1091 | SwEditShell* pESh = dynamic_cast<SwEditShell*>(GetViewShell()); | |||
1092 | bool bIsModified = pESh != nullptr && pESh->IsModified(); | |||
1093 | ||||
1094 | SwViewOption aOpt( *pPrefs ); | |||
1095 | aOpt.SetPagePreview(true); | |||
1096 | aOpt.SetTab( false ); | |||
1097 | aOpt.SetBlank( false ); | |||
1098 | aOpt.SetHardBlank( false ); | |||
1099 | aOpt.SetParagraph( false ); | |||
1100 | aOpt.SetLineBreak( false ); | |||
1101 | aOpt.SetPageBreak( false ); | |||
1102 | aOpt.SetColumnBreak( false ); | |||
1103 | aOpt.SetSoftHyph( false ); | |||
1104 | aOpt.SetFieldName( false ); | |||
1105 | aOpt.SetPostIts( false ); | |||
1106 | aOpt.SetShowBookmarks( false ); | |||
1107 | aOpt.SetShowHiddenChar( false ); | |||
1108 | aOpt.SetShowHiddenField( false ); | |||
1109 | aOpt.SetShowHiddenPara( false ); | |||
1110 | aOpt.SetViewHRuler( false ); | |||
1111 | aOpt.SetViewVRuler( false ); | |||
1112 | aOpt.SetGraphic( true ); | |||
1113 | aOpt.SetTable( true ); | |||
1114 | aOpt.SetSnap( false ); | |||
1115 | aOpt.SetGridVisible( false ); | |||
1116 | aOpt.SetOnlineSpell( false ); | |||
1117 | aOpt.SetHideWhitespaceMode( false ); | |||
1118 | ||||
1119 | GetViewShell()->ApplyViewOptions( aOpt ); | |||
1120 | GetViewShell()->ApplyAccessibilityOptions(SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetAccessibilityOptions()); | |||
1121 | ||||
1122 | // adjust view shell option to the same as for print | |||
1123 | SwPrintData const aPrintOptions = *SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetPrtOptions(false); | |||
1124 | GetViewShell()->AdjustOptionsForPagePreview( aPrintOptions ); | |||
1125 | ||||
1126 | GetViewShell()->CalcLayout(); | |||
1127 | DocSzChgd( GetViewShell()->GetDocSize() ); | |||
1128 | ||||
1129 | if( !bIsModified && pESh != nullptr ) | |||
1130 | pESh->ResetModified(); | |||
1131 | } | |||
1132 | ||||
1133 | SwPagePreview::SwPagePreview(SfxViewFrame *pViewFrame, SfxViewShell* pOldSh): | |||
1134 | SfxViewShell( pViewFrame, SWVIEWFLAGSSfxViewShellFlags::HAS_PRINTOPTIONS ), | |||
1135 | m_pViewWin( VclPtr<SwPagePreviewWin>::Create(&GetViewFrame()->GetWindow(), *this ) ), | |||
1136 | m_nNewPage(USHRT_MAX(32767 *2 +1)), | |||
1137 | m_sPageStr(SwResId(STR_PAGEreinterpret_cast<char const *>("STR_PAGE" "\004" u8"Page " ))), | |||
1138 | m_pHScrollbar(nullptr), | |||
1139 | m_pVScrollbar(nullptr), | |||
1140 | m_pScrollFill(VclPtr<ScrollBarBox>::Create( &pViewFrame->GetWindow(), WB_SIZEABLE )), | |||
1141 | mnPageCount( 0 ), | |||
1142 | mbResetFormDesignMode( false ), | |||
1143 | mbFormDesignModeToReset( false ) | |||
1144 | { | |||
1145 | SetName("PageView"); | |||
1146 | SetWindow( m_pViewWin ); | |||
1147 | CreateScrollbar( true ); | |||
1148 | CreateScrollbar( false ); | |||
1149 | ||||
1150 | //notify notebookbar change in context | |||
1151 | SfxShell::SetContextBroadcasterEnabled(true); | |||
1152 | SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview)); | |||
1153 | SfxShell::BroadcastContextForActivation(true); | |||
1154 | //removelisteners for notebookbar | |||
1155 | if (SfxViewFrame* pCurrent = SfxViewFrame::Current()) | |||
1156 | if (auto& pBar = pCurrent->GetWindow().GetSystemWindow()->GetNotebookBar()) | |||
1157 | pBar->ControlListenerForCurrentController(false); | |||
1158 | ||||
1159 | SfxObjectShell* pObjShell = pViewFrame->GetObjectShell(); | |||
1160 | if ( !pOldSh ) | |||
1161 | { | |||
1162 | // Exists already a view on the document? | |||
1163 | SfxViewFrame *pF = SfxViewFrame::GetFirst( pObjShell ); | |||
1164 | if ( pF == pViewFrame ) | |||
1165 | pF = SfxViewFrame::GetNext( *pF, pObjShell ); | |||
1166 | if ( pF ) | |||
1167 | pOldSh = pF->GetViewShell(); | |||
1168 | } | |||
1169 | ||||
1170 | SwViewShell *pVS, *pNew; | |||
1171 | ||||
1172 | if (SwPagePreview* pPagePreview = dynamic_cast<SwPagePreview*>(pOldSh)) | |||
1173 | pVS = pPagePreview->GetViewShell(); | |||
1174 | else | |||
1175 | { | |||
1176 | if (SwView* pView = dynamic_cast<SwView *>(pOldSh)) | |||
1177 | { | |||
1178 | pVS = pView->GetWrtShellPtr(); | |||
1179 | // save the current ViewData of the previous SwView | |||
1180 | pOldSh->WriteUserData( m_sSwViewData ); | |||
1181 | } | |||
1182 | else | |||
1183 | pVS = GetDocShell()->GetWrtShell(); | |||
1184 | if( pVS ) | |||
1185 | { | |||
1186 | // Set the current page as the first. | |||
1187 | sal_uInt16 nPhysPg, nVirtPg; | |||
1188 | static_cast<SwCursorShell*>(pVS)->GetPageNum( nPhysPg, nVirtPg, true, false ); | |||
1189 | if( 1 != m_pViewWin->GetCol() && 1 == nPhysPg ) | |||
1190 | --nPhysPg; | |||
1191 | m_pViewWin->SetSttPage( nPhysPg ); | |||
1192 | } | |||
1193 | } | |||
1194 | ||||
1195 | // for form shell remember design mode of draw view | |||
1196 | // of previous view shell | |||
1197 | if ( pVS && pVS->HasDrawView() ) | |||
1198 | { | |||
1199 | mbResetFormDesignMode = true; | |||
1200 | mbFormDesignModeToReset = pVS->GetDrawView()->IsDesignMode(); | |||
1201 | } | |||
1202 | ||||
1203 | if( pVS ) | |||
1204 | pNew = new SwViewShell( *pVS, m_pViewWin, nullptr, VSHELLFLAG_ISPREVIEW(long(0x1)) ); | |||
1205 | else | |||
1206 | pNew = new SwViewShell( | |||
1207 | *static_cast<SwDocShell*>(pViewFrame->GetObjectShell())->GetDoc(), | |||
1208 | m_pViewWin, nullptr, nullptr, VSHELLFLAG_ISPREVIEW(long(0x1)) ); | |||
1209 | ||||
1210 | m_pViewWin->SetViewShell( pNew ); | |||
1211 | pNew->SetSfxViewShell( this ); | |||
1212 | Init(); | |||
1213 | } | |||
1214 | ||||
1215 | SwPagePreview::~SwPagePreview() | |||
1216 | { | |||
1217 | SetWindow( nullptr ); | |||
1218 | SwViewShell* pVShell = m_pViewWin->GetViewShell(); | |||
1219 | pVShell->SetWin(nullptr); | |||
1220 | delete pVShell; | |||
1221 | ||||
1222 | m_pViewWin.disposeAndClear(); | |||
| ||||
1223 | if (SfxViewFrame* pCurrent = SfxViewFrame::Current()) | |||
1224 | if (auto& pBar = pCurrent->GetWindow().GetSystemWindow()->GetNotebookBar()) | |||
1225 | pBar->ControlListenerForCurrentController(true); // start listening now | |||
1226 | m_pScrollFill.disposeAndClear(); | |||
1227 | m_pHScrollbar.disposeAndClear(); | |||
1228 | m_pVScrollbar.disposeAndClear(); | |||
1229 | } | |||
1230 | ||||
1231 | SwDocShell* SwPagePreview::GetDocShell() | |||
1232 | { | |||
1233 | return dynamic_cast<SwDocShell*>( GetViewFrame()->GetObjectShell() ); | |||
1234 | } | |||
1235 | ||||
1236 | void SwPagePreview::CreateScrollbar( bool bHori ) | |||
1237 | { | |||
1238 | vcl::Window *pMDI = &GetViewFrame()->GetWindow(); | |||
1239 | VclPtr<SwScrollbar>& ppScrollbar = bHori ? m_pHScrollbar : m_pVScrollbar; | |||
1240 | ||||
1241 | assert(!ppScrollbar)(static_cast <bool> (!ppScrollbar) ? void (0) : __assert_fail ("!ppScrollbar", "/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx" , 1241, __extension__ __PRETTY_FUNCTION__)); //check beforehand! | |||
1242 | ||||
1243 | ppScrollbar = VclPtr<SwScrollbar>::Create( pMDI, bHori ); | |||
1244 | ||||
1245 | ScrollDocSzChg(); | |||
1246 | ppScrollbar->EnableDrag(); | |||
1247 | ppScrollbar->SetEndScrollHdl( LINK( this, SwPagePreview, EndScrollHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwPagePreview *>(this), &SwPagePreview::LinkStubEndScrollHdl)); | |||
1248 | ||||
1249 | ppScrollbar->SetScrollHdl( LINK( this, SwPagePreview, ScrollHdl )::tools::detail::makeLink( ::tools::detail::castTo<SwPagePreview *>(this), &SwPagePreview::LinkStubScrollHdl)); | |||
1250 | ||||
1251 | InvalidateBorder(); | |||
1252 | ppScrollbar->ExtendedShow(); | |||
1253 | } | |||
1254 | ||||
1255 | bool SwPagePreview::ChgPage( int eMvMode, bool bUpdateScrollbar ) | |||
1256 | { | |||
1257 | tools::Rectangle aPixVisArea( m_pViewWin->LogicToPixel( m_aVisArea ) ); | |||
1258 | bool bChg = m_pViewWin->MovePage( eMvMode ) || | |||
1259 | eMvMode == SwPagePreviewWin::MV_CALC || | |||
1260 | eMvMode == SwPagePreviewWin::MV_NEWWINSIZE; | |||
1261 | m_aVisArea = m_pViewWin->PixelToLogic( aPixVisArea ); | |||
1262 | ||||
1263 | if( bChg ) | |||
1264 | { | |||
1265 | // Update statusbar | |||
1266 | OUString aStr = m_sPageStr + m_pViewWin->GetStatusStr( mnPageCount ); | |||
1267 | SfxBindings& rBindings = GetViewFrame()->GetBindings(); | |||
1268 | ||||
1269 | if( bUpdateScrollbar ) | |||
1270 | { | |||
1271 | ScrollViewSzChg(); | |||
1272 | ||||
1273 | static sal_uInt16 aInval[] = | |||
1274 | { | |||
1275 | FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), | |||
1276 | FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), 0 | |||
1277 | }; | |||
1278 | rBindings.Invalidate( aInval ); | |||
1279 | } | |||
1280 | rBindings.SetState( SfxStringItem( FN_STAT_PAGE((20000 + 1180) + 1), aStr ) ); | |||
1281 | } | |||
1282 | return bChg; | |||
1283 | } | |||
1284 | ||||
1285 | // From here, everything was taken from the SwView. | |||
1286 | void SwPagePreview::CalcAndSetBorderPixel( SvBorder &rToFill ) | |||
1287 | { | |||
1288 | const StyleSettings &rSet = m_pViewWin->GetSettings().GetStyleSettings(); | |||
1289 | const long nTmp = rSet.GetScrollBarSize(); | |||
1290 | if ( m_pVScrollbar->IsVisible( true ) ) | |||
1291 | rToFill.Right() = nTmp; | |||
1292 | if ( m_pHScrollbar->IsVisible( true ) ) | |||
1293 | rToFill.Bottom() = nTmp; | |||
1294 | SetBorderPixel( rToFill ); | |||
1295 | } | |||
1296 | ||||
1297 | void SwPagePreview::InnerResizePixel( const Point &rOfst, const Size &rSize, bool ) | |||
1298 | { | |||
1299 | SvBorder aBorder; | |||
1300 | CalcAndSetBorderPixel( aBorder ); | |||
1301 | tools::Rectangle aRect( rOfst, rSize ); | |||
1302 | aRect += aBorder; | |||
1303 | ViewResizePixel( *m_pViewWin, aRect.TopLeft(), aRect.GetSize(), | |||
1304 | m_pViewWin->GetOutputSizePixel(), | |||
1305 | *m_pVScrollbar, *m_pHScrollbar, *m_pScrollFill ); | |||
1306 | ||||
1307 | // Never set EditWin ! | |||
1308 | // Never set VisArea ! | |||
1309 | } | |||
1310 | ||||
1311 | void SwPagePreview::OuterResizePixel( const Point &rOfst, const Size &rSize ) | |||
1312 | { | |||
1313 | SvBorder aBorder; | |||
1314 | CalcAndSetBorderPixel( aBorder ); | |||
1315 | ||||
1316 | // Never set EditWin ! | |||
1317 | ||||
1318 | Size aTmpSize( m_pViewWin->GetOutputSizePixel() ); | |||
1319 | Point aBottomRight( m_pViewWin->PixelToLogic( Point( aTmpSize.Width(), aTmpSize.Height() ) ) ); | |||
1320 | SetVisArea( tools::Rectangle( Point(), aBottomRight ) ); | |||
1321 | ||||
1322 | // Call of the DocSzChgd-Method of the scrollbars is necessary, | |||
1323 | // because from the maximum scroll range half the height of the | |||
1324 | // VisArea is always deducted. | |||
1325 | if ( m_pVScrollbar && !aTmpSize.IsEmpty() ) | |||
1326 | { | |||
1327 | ScrollDocSzChg(); | |||
1328 | } | |||
1329 | ||||
1330 | SvBorder aBorderNew; | |||
1331 | CalcAndSetBorderPixel( aBorderNew ); | |||
1332 | ViewResizePixel( *m_pViewWin, rOfst, rSize, m_pViewWin->GetOutputSizePixel(), | |||
1333 | *m_pVScrollbar, *m_pHScrollbar, *m_pScrollFill ); | |||
1334 | } | |||
1335 | ||||
1336 | void SwPagePreview::SetVisArea( const tools::Rectangle &rRect ) | |||
1337 | { | |||
1338 | const Point aTopLeft(AlignToPixel(rRect.TopLeft())); | |||
1339 | const Point aBottomRight(AlignToPixel(rRect.BottomRight())); | |||
1340 | tools::Rectangle aLR(aTopLeft,aBottomRight); | |||
1341 | ||||
1342 | if(aLR == m_aVisArea) | |||
1343 | return; | |||
1344 | // No negative position, no negative size | |||
1345 | ||||
1346 | if(aLR.Top() < 0) | |||
1347 | { | |||
1348 | aLR.AdjustBottom(std::abs(aLR.Top()) ); | |||
1349 | aLR.SetTop( 0 ); | |||
1350 | } | |||
1351 | ||||
1352 | if(aLR.Left() < 0) | |||
1353 | { | |||
1354 | aLR.AdjustRight(std::abs(aLR.Left()) ); | |||
1355 | aLR.SetLeft( 0 ); | |||
1356 | } | |||
1357 | if(aLR.Right() < 0) aLR.SetRight( 0 ); | |||
1358 | if(aLR.Bottom() < 0) aLR.SetBottom( 0 ); | |||
1359 | if(aLR == m_aVisArea || | |||
1360 | // Ignore empty rectangle | |||
1361 | ( 0 == aLR.Bottom() - aLR.Top() && 0 == aLR.Right() - aLR.Left() ) ) | |||
1362 | return; | |||
1363 | ||||
1364 | if( aLR.Left() > aLR.Right() || aLR.Top() > aLR.Bottom() ) | |||
1365 | return; | |||
1366 | ||||
1367 | // Before the data can be changed call an update if necessary. | |||
1368 | // Thereby ensured, that adjacent paints are correctly converted into | |||
1369 | // document coordinates. | |||
1370 | // As a precaution, we do this only when at the shell runs an action, | |||
1371 | // because then we do not really paint but the rectangles are just | |||
1372 | // bookmarked (in document coordinates). | |||
1373 | if( GetViewShell()->ActionPend() ) | |||
1374 | m_pViewWin->PaintImmediately(); | |||
1375 | ||||
1376 | // Set at View-Win the current size | |||
1377 | m_aVisArea = aLR; | |||
1378 | m_pViewWin->SetWinSize( aLR.GetSize() ); | |||
1379 | ChgPage( SwPagePreviewWin::MV_NEWWINSIZE ); | |||
1380 | ||||
1381 | m_pViewWin->Invalidate(); | |||
1382 | } | |||
1383 | ||||
1384 | IMPL_LINK( SwPagePreview, ScrollHdl, ScrollBar *, p, void )void SwPagePreview::LinkStubScrollHdl(void * instance, ScrollBar * data) { return static_cast<SwPagePreview *>(instance )->ScrollHdl(data); } void SwPagePreview::ScrollHdl(ScrollBar * p) | |||
1385 | { | |||
1386 | SwScrollbar* pScrollbar = static_cast<SwScrollbar*>(p); | |||
1387 | if(!GetViewShell()) | |||
1388 | return; | |||
1389 | if( !pScrollbar->IsHoriScroll() && | |||
1390 | pScrollbar->GetType() == ScrollType::Drag && | |||
1391 | Help::IsQuickHelpEnabled() && | |||
1392 | GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow()) | |||
1393 | { | |||
1394 | // Scroll how many pages?? | |||
1395 | OUString sStateStr(m_sPageStr); | |||
1396 | long nThmbPos = pScrollbar->GetThumbPos(); | |||
1397 | if( 1 == m_pViewWin->GetCol() || !nThmbPos ) | |||
1398 | ++nThmbPos; | |||
1399 | sStateStr += OUString::number( nThmbPos ); | |||
1400 | Point aPos = pScrollbar->GetParent()->OutputToScreenPixel( | |||
1401 | pScrollbar->GetPosPixel()); | |||
1402 | aPos.setY( pScrollbar->OutputToScreenPixel(pScrollbar->GetPointerPosPixel()).Y() ); | |||
1403 | tools::Rectangle aRect; | |||
1404 | aRect.SetLeft( aPos.X() -8 ); | |||
1405 | aRect.SetRight( aRect.Left() ); | |||
1406 | aRect.SetTop( aPos.Y() ); | |||
1407 | aRect.SetBottom( aRect.Top() ); | |||
1408 | ||||
1409 | Help::ShowQuickHelp(pScrollbar, aRect, sStateStr, | |||
1410 | QuickHelpFlags::Right|QuickHelpFlags::VCenter); | |||
1411 | ||||
1412 | } | |||
1413 | else | |||
1414 | EndScrollHdl( pScrollbar ); | |||
1415 | } | |||
1416 | ||||
1417 | IMPL_LINK( SwPagePreview, EndScrollHdl, ScrollBar *, p, void )void SwPagePreview::LinkStubEndScrollHdl(void * instance, ScrollBar * data) { return static_cast<SwPagePreview *>(instance )->EndScrollHdl(data); } void SwPagePreview::EndScrollHdl( ScrollBar * p) | |||
1418 | { | |||
1419 | SwScrollbar* pScrollbar = static_cast<SwScrollbar*>(p); | |||
1420 | if(!GetViewShell()) | |||
1421 | return; | |||
1422 | ||||
1423 | // boolean to avoid unnecessary invalidation of the window. | |||
1424 | bool bInvalidateWin = true; | |||
1425 | ||||
1426 | if( !pScrollbar->IsHoriScroll() ) // scroll vertically | |||
1427 | { | |||
1428 | if ( Help::IsQuickHelpEnabled() ) | |||
1429 | Help::ShowQuickHelp(pScrollbar, tools::Rectangle(), OUString()); | |||
1430 | if ( GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow() ) | |||
1431 | { | |||
1432 | // Scroll how many pages ?? | |||
1433 | const sal_uInt16 nThmbPos = static_cast<sal_uInt16>(pScrollbar->GetThumbPos()); | |||
1434 | // adjust to new preview functionality | |||
1435 | if( nThmbPos != m_pViewWin->SelectedPage() ) | |||
1436 | { | |||
1437 | // consider case that page <nThmbPos> | |||
1438 | // is already visible | |||
1439 | SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout(); | |||
1440 | if ( pPagePreviewLay->IsPageVisible( nThmbPos ) ) | |||
1441 | { | |||
1442 | pPagePreviewLay->MarkNewSelectedPage( nThmbPos ); | |||
1443 | // invalidation of window is unnecessary | |||
1444 | bInvalidateWin = false; | |||
1445 | } | |||
1446 | else | |||
1447 | { | |||
1448 | // consider whether layout columns | |||
1449 | // fit or not. | |||
1450 | if ( !pPagePreviewLay->DoesPreviewLayoutColsFitIntoWindow() ) | |||
1451 | { | |||
1452 | m_pViewWin->SetSttPage( nThmbPos ); | |||
1453 | m_pViewWin->SetSelectedPage( nThmbPos ); | |||
1454 | ChgPage( SwPagePreviewWin::MV_SCROLL, false ); | |||
1455 | // update scrollbars | |||
1456 | ScrollViewSzChg(); | |||
1457 | } | |||
1458 | else | |||
1459 | { | |||
1460 | // correct scroll amount | |||
1461 | const sal_Int16 nPageDiff = nThmbPos - m_pViewWin->SelectedPage(); | |||
1462 | const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol(); | |||
1463 | sal_Int16 nWinPagesToScroll = nPageDiff / nVisPages; | |||
1464 | if ( nPageDiff % nVisPages ) | |||
1465 | { | |||
1466 | // decrease/increase number of preview pages to scroll | |||
1467 | nPageDiff < 0 ? --nWinPagesToScroll : ++nWinPagesToScroll; | |||
1468 | } | |||
1469 | m_pViewWin->SetSelectedPage( nThmbPos ); | |||
1470 | m_pViewWin->Scroll( 0, pPagePreviewLay->GetWinPagesScrollAmount( nWinPagesToScroll ) ); | |||
1471 | } | |||
1472 | } | |||
1473 | // update accessibility | |||
1474 | GetViewShell()->ShowPreviewSelection( nThmbPos ); | |||
1475 | } | |||
1476 | else | |||
1477 | { | |||
1478 | // invalidation of window is unnecessary | |||
1479 | bInvalidateWin = false; | |||
1480 | } | |||
1481 | } | |||
1482 | else | |||
1483 | { | |||
1484 | long nThmbPos = pScrollbar->GetThumbPos(); | |||
1485 | m_pViewWin->Scroll(0, nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Top()); | |||
1486 | } | |||
1487 | } | |||
1488 | else | |||
1489 | { | |||
1490 | long nThmbPos = pScrollbar->GetThumbPos(); | |||
1491 | m_pViewWin->Scroll(nThmbPos - m_pViewWin->GetPaintedPreviewDocRect().Left(), 0); | |||
1492 | } | |||
1493 | // additional invalidate page status. | |||
1494 | static sal_uInt16 aInval[] = | |||
1495 | { | |||
1496 | FN_START_OF_DOCUMENT((20000 + 900) + 7 ), FN_END_OF_DOCUMENT((20000 + 900) + 8), FN_PAGEUP((20000 + 900) + 37), FN_PAGEDOWN((20000 + 900) + 38), | |||
1497 | FN_STAT_PAGE((20000 + 1180) + 1), 0 | |||
1498 | }; | |||
1499 | SfxBindings& rBindings = GetViewFrame()->GetBindings(); | |||
1500 | rBindings.Invalidate( aInval ); | |||
1501 | // control invalidation of window | |||
1502 | if ( bInvalidateWin ) | |||
1503 | { | |||
1504 | m_pViewWin->Invalidate(); | |||
1505 | } | |||
1506 | } | |||
1507 | ||||
1508 | Point SwPagePreview::AlignToPixel(const Point &rPt) const | |||
1509 | { | |||
1510 | return m_pViewWin->PixelToLogic( m_pViewWin->LogicToPixel( rPt ) ); | |||
1511 | } | |||
1512 | ||||
1513 | void SwPagePreview::DocSzChgd( const Size &rSz ) | |||
1514 | { | |||
1515 | if( m_aDocSize == rSz ) | |||
1516 | return; | |||
1517 | ||||
1518 | m_aDocSize = rSz; | |||
1519 | ||||
1520 | // #i96726# | |||
1521 | // Due to the multiple page layout it is needed to trigger recalculation | |||
1522 | // of the page preview layout, even if the count of pages is not changing. | |||
1523 | mnPageCount = GetViewShell()->GetNumPages(); | |||
1524 | ||||
1525 | if( m_aVisArea.GetWidth() ) | |||
1526 | { | |||
1527 | ChgPage( SwPagePreviewWin::MV_CALC ); | |||
1528 | ScrollDocSzChg(); | |||
1529 | ||||
1530 | m_pViewWin->Invalidate(); | |||
1531 | } | |||
1532 | } | |||
1533 | ||||
1534 | void SwPagePreview::ScrollViewSzChg() | |||
1535 | { | |||
1536 | if(!GetViewShell()) | |||
1537 | return ; | |||
1538 | ||||
1539 | bool bShowVScrollbar = false, bShowHScrollbar = false; | |||
1540 | ||||
1541 | if(m_pVScrollbar) | |||
1542 | { | |||
1543 | if(GetViewShell()->PagePreviewLayout()->DoesPreviewLayoutRowsFitIntoWindow()) | |||
1544 | { | |||
1545 | //vertical scrolling by row | |||
1546 | // adjust to new preview functionality | |||
1547 | const sal_uInt16 nVisPages = m_pViewWin->GetRow() * m_pViewWin->GetCol(); | |||
1548 | ||||
1549 | m_pVScrollbar->SetVisibleSize( nVisPages ); | |||
1550 | // set selected page as scroll bar position, | |||
1551 | // if it is visible. | |||
1552 | SwPagePreviewLayout* pPagePreviewLay = GetViewShell()->PagePreviewLayout(); | |||
1553 | if ( pPagePreviewLay->IsPageVisible( m_pViewWin->SelectedPage() ) ) | |||
1554 | { | |||
1555 | m_pVScrollbar->SetThumbPos( m_pViewWin->SelectedPage() ); | |||
1556 | } | |||
1557 | else | |||
1558 | { | |||
1559 | m_pVScrollbar->SetThumbPos( m_pViewWin->GetSttPage() ); | |||
1560 | } | |||
1561 | m_pVScrollbar->SetLineSize( m_pViewWin->GetCol() ); | |||
1562 | m_pVScrollbar->SetPageSize( nVisPages ); | |||
1563 | // calculate and set scrollbar range | |||
1564 | Range aScrollbarRange( 1, mnPageCount ); | |||
1565 | // increase range by one, because left-top-corner is left blank. | |||
1566 | ++aScrollbarRange.Max(); | |||
1567 | // increase range in order to access all pages | |||
1568 | aScrollbarRange.Max() += ( nVisPages - 1 ); | |||
1569 | m_pVScrollbar->SetRange( aScrollbarRange ); | |||
1570 | ||||
1571 | bShowVScrollbar = nVisPages < mnPageCount; | |||
1572 | } | |||
1573 | else //vertical scrolling by pixel | |||
1574 | { | |||
1575 | const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect(); | |||
1576 | const Size& rPreviewSize = | |||
1577 | GetViewShell()->PagePreviewLayout()->GetPreviewDocSize(); | |||
1578 | m_pVScrollbar->SetRangeMax(rPreviewSize.Height()) ; | |||
1579 | long nVisHeight = rDocRect.GetHeight(); | |||
1580 | m_pVScrollbar->SetVisibleSize( nVisHeight ); | |||
1581 | m_pVScrollbar->SetThumbPos( rDocRect.Top() ); | |||
1582 | m_pVScrollbar->SetLineSize( nVisHeight / 10 ); | |||
1583 | m_pVScrollbar->SetPageSize( nVisHeight / 2 ); | |||
1584 | ||||
1585 | bShowVScrollbar = true; | |||
1586 | } | |||
1587 | ||||
1588 | if (!mbVScrollbarEnabled) | |||
1589 | bShowVScrollbar = false; | |||
1590 | ||||
1591 | ShowVScrollbar(bShowVScrollbar); | |||
1592 | } | |||
1593 | if(m_pHScrollbar) | |||
1594 | { | |||
1595 | const tools::Rectangle& rDocRect = m_pViewWin->GetPaintedPreviewDocRect(); | |||
1596 | const Size& rPreviewSize = | |||
1597 | GetViewShell()->PagePreviewLayout()->GetPreviewDocSize(); | |||
1598 | Range aRange(0,0); | |||
1599 | ||||
1600 | if(rDocRect.GetWidth() < rPreviewSize.Width()) | |||
1601 | { | |||
1602 | bShowHScrollbar = true; | |||
1603 | ||||
1604 | long nVisWidth = rDocRect.GetWidth(); | |||
1605 | long nThumb = rDocRect.Left(); | |||
1606 | aRange = Range(0, rPreviewSize.Width()); | |||
1607 | ||||
1608 | m_pHScrollbar->SetRange( aRange ); | |||
1609 | m_pHScrollbar->SetVisibleSize( nVisWidth ); | |||
1610 | m_pHScrollbar->SetThumbPos( nThumb ); | |||
1611 | m_pHScrollbar->SetLineSize( nVisWidth / 10 ); | |||
1612 | m_pHScrollbar->SetPageSize( nVisWidth / 2 ); | |||
1613 | } | |||
1614 | ||||
1615 | if (!mbHScrollbarEnabled) | |||
1616 | bShowHScrollbar = false; | |||
1617 | ||||
1618 | ShowHScrollbar(bShowHScrollbar); | |||
1619 | } | |||
1620 | m_pScrollFill->Show(bShowVScrollbar && bShowHScrollbar); | |||
1621 | } | |||
1622 | ||||
1623 | void SwPagePreview::ScrollDocSzChg() | |||
1624 | { | |||
1625 | ScrollViewSzChg(); | |||
1626 | } | |||
1627 | ||||
1628 | // All about printing | |||
1629 | SfxPrinter* SwPagePreview::GetPrinter( bool bCreate ) | |||
1630 | { | |||
1631 | return m_pViewWin->GetViewShell()->getIDocumentDeviceAccess().getPrinter( bCreate ); | |||
1632 | } | |||
1633 | ||||
1634 | sal_uInt16 SwPagePreview::SetPrinter( SfxPrinter *pNew, SfxPrinterChangeFlags nDiffFlags ) | |||
1635 | { | |||
1636 | SwViewShell &rSh = *GetViewShell(); | |||
1637 | SfxPrinter* pOld = rSh.getIDocumentDeviceAccess().getPrinter( false ); | |||
1638 | if ( pOld && pOld->IsPrinting() ) | |||
1639 | return SFX_PRINTERROR_BUSY1; | |||
1640 | ||||
1641 | SwEditShell &rESh = static_cast<SwEditShell&>(rSh); //Buh... | |||
1642 | if( ( SfxPrinterChangeFlags::PRINTER | SfxPrinterChangeFlags::JOBSETUP ) & nDiffFlags ) | |||
1643 | { | |||
1644 | rSh.getIDocumentDeviceAccess().setPrinter( pNew, true, true ); | |||
1645 | if( nDiffFlags & SfxPrinterChangeFlags::PRINTER ) | |||
1646 | rESh.SetModified(); | |||
1647 | } | |||
1648 | if ( ( nDiffFlags & SfxPrinterChangeFlags::OPTIONS ) == SfxPrinterChangeFlags::OPTIONS ) | |||
1649 | ::SetPrinter( &rSh.getIDocumentDeviceAccess(), pNew, false ); | |||
1650 | ||||
1651 | const bool bChgOri = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_ORIENTATION); | |||
1652 | const bool bChgSize = bool(nDiffFlags & SfxPrinterChangeFlags::CHG_SIZE); | |||
1653 | if ( bChgOri || bChgSize ) | |||
1654 | { | |||
1655 | rESh.StartAllAction(); | |||
1656 | if ( bChgOri ) | |||
1657 | rSh.ChgAllPageOrientation( pNew->GetOrientation() ); | |||
1658 | if ( bChgSize ) | |||
1659 | { | |||
1660 | Size aSz( SvxPaperInfo::GetPaperSize( pNew ) ); | |||
1661 | rSh.ChgAllPageSize( aSz ); | |||
1662 | } | |||
1663 | if( !m_bNormalPrint ) | |||
1664 | m_pViewWin->CalcWish( m_pViewWin->GetRow(), m_pViewWin->GetCol() ); | |||
1665 | rESh.SetModified(); | |||
1666 | rESh.EndAllAction(); | |||
1667 | ||||
1668 | static sal_uInt16 aInval[] = | |||
1669 | { | |||
1670 | SID_ATTR_LONG_ULSPACE( 10000 + 284 ), SID_ATTR_LONG_LRSPACE( 10000 + 285 ), | |||
1671 | SID_RULER_BORDERSTypedWhichId<SvxRulerItem>( 10000 + 80 ), SID_RULER_PAGE_POSTypedWhichId<SvxRulerItem>( 10000 + 82 ), 0 | |||
1672 | }; | |||
1673 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1674 | { | |||
1675 | const sal_uInt16* pPtr = aInval + 1; | |||
1676 | do { | |||
1677 | OSL_ENSURE( *(pPtr - 1) < *pPtr, "wrong sorting!" )do { if (true && (!(*(pPtr - 1) < *pPtr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx" ":" "1677" ": "), "%s", "wrong sorting!"); } } while (false); | |||
1678 | } while( *++pPtr ); | |||
1679 | } | |||
1680 | #endif | |||
1681 | ||||
1682 | GetViewFrame()->GetBindings().Invalidate(aInval); | |||
1683 | } | |||
1684 | ||||
1685 | return 0; | |||
1686 | } | |||
1687 | ||||
1688 | bool SwPagePreview::HasPrintOptionsPage() const | |||
1689 | { | |||
1690 | return true; | |||
1691 | } | |||
1692 | ||||
1693 | std::unique_ptr<SfxTabPage> SwPagePreview::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController, | |||
1694 | const SfxItemSet &rOptions) | |||
1695 | { | |||
1696 | return ::CreatePrintOptionsPage(pPage, pController, rOptions, !m_bNormalPrint); | |||
1697 | } | |||
1698 | ||||
1699 | void SwPagePreviewWin::SetViewShell( SwViewShell* pShell ) | |||
1700 | { | |||
1701 | mpViewShell = pShell; | |||
1702 | if ( mpViewShell && mpViewShell->IsPreview() ) | |||
1703 | { | |||
1704 | mpPgPreviewLayout = mpViewShell->PagePreviewLayout(); | |||
1705 | } | |||
1706 | } | |||
1707 | ||||
1708 | void SwPagePreviewWin::RepaintCoreRect( const SwRect& rRect ) | |||
1709 | { | |||
1710 | // #i24183# | |||
1711 | if ( mpPgPreviewLayout->PreviewLayoutValid() ) | |||
1712 | { | |||
1713 | mpPgPreviewLayout->Repaint( tools::Rectangle( rRect.Pos(), rRect.SSize() ) ); | |||
1714 | } | |||
1715 | } | |||
1716 | ||||
1717 | /** method to adjust preview to a new zoom factor | |||
1718 | ||||
1719 | #i19975# also consider zoom type - adding parameter <_eZoomType> | |||
1720 | */ | |||
1721 | void SwPagePreviewWin::AdjustPreviewToNewZoom( const sal_uInt16 _nZoomFactor, | |||
1722 | const SvxZoomType _eZoomType ) | |||
1723 | { | |||
1724 | // #i19975# consider zoom type | |||
1725 | if ( _eZoomType == SvxZoomType::WHOLEPAGE ) | |||
1726 | { | |||
1727 | mnRow = 1; | |||
1728 | mnCol = 1; | |||
1729 | mpPgPreviewLayout->Init( mnCol, mnRow, maPxWinSize ); | |||
1730 | mpPgPreviewLayout->Prepare( mnSttPage, Point(0,0), maPxWinSize, | |||
1731 | mnSttPage, maPaintedPreviewDocRect ); | |||
1732 | SetSelectedPage( mnSttPage ); | |||
1733 | SetPagePreview(mnRow, mnCol); | |||
1734 | maScale = GetMapMode().GetScaleX(); | |||
1735 | } | |||
1736 | else if ( _nZoomFactor != 0 ) | |||
1737 | { | |||
1738 | // calculate new scaling and set mapping mode appropriately. | |||
1739 | Fraction aNewScale( _nZoomFactor, 100 ); | |||
1740 | MapMode aNewMapMode = GetMapMode(); | |||
1741 | aNewMapMode.SetScaleX( aNewScale ); | |||
1742 | aNewMapMode.SetScaleY( aNewScale ); | |||
1743 | SetMapMode( aNewMapMode ); | |||
1744 | ||||
1745 | // calculate new start position for preview paint | |||
1746 | Size aNewWinSize = PixelToLogic( maPxWinSize ); | |||
1747 | Point aNewPaintStartPos = | |||
1748 | mpPgPreviewLayout->GetPreviewStartPosForNewScale( aNewScale, maScale, aNewWinSize ); | |||
1749 | ||||
1750 | // remember new scaling and prepare preview paint | |||
1751 | // Note: paint of preview will be performed by a corresponding invalidate | |||
1752 | // due to property changes. | |||
1753 | maScale = aNewScale; | |||
1754 | mpPgPreviewLayout->Prepare( 0, aNewPaintStartPos, maPxWinSize, | |||
1755 | mnSttPage, maPaintedPreviewDocRect ); | |||
1756 | } | |||
1757 | ||||
1758 | } | |||
1759 | ||||
1760 | /** | |||
1761 | * pixel scrolling - horizontally always or vertically | |||
1762 | * when less than the desired number of rows fits into | |||
1763 | * the view | |||
1764 | */ | |||
1765 | void SwPagePreviewWin::Scroll(long nXMove, long nYMove, ScrollFlags /*nFlags*/) | |||
1766 | { | |||
1767 | maPaintedPreviewDocRect.Move(nXMove, nYMove); | |||
1768 | mpPgPreviewLayout->Prepare( 0, maPaintedPreviewDocRect.TopLeft(), | |||
1769 | maPxWinSize, mnSttPage, | |||
1770 | maPaintedPreviewDocRect ); | |||
1771 | ||||
1772 | } | |||
1773 | ||||
1774 | bool SwPagePreview::HandleWheelCommands( const CommandEvent& rCEvt ) | |||
1775 | { | |||
1776 | bool bOk = false; | |||
1777 | const CommandWheelData* pWData = rCEvt.GetWheelData(); | |||
1778 | if( pWData && CommandWheelMode::ZOOM == pWData->GetMode() ) | |||
1779 | { | |||
1780 | //only the Preference shouldn't control the Zoom, it is better to detect AT tools running. So the bridge can be used here | |||
1781 | if (!Application::GetSettings().GetMiscSettings().GetEnableATToolSupport()) | |||
1782 | { | |||
1783 | sal_uInt16 nFactor = GetViewShell()->GetViewOptions()->GetZoom(); | |||
1784 | const sal_uInt16 nOffset = 10; | |||
1785 | if( 0L > pWData->GetDelta() ) | |||
1786 | { | |||
1787 | nFactor -= nOffset; | |||
1788 | if(nFactor < MIN_PREVIEW_ZOOM25) | |||
1789 | nFactor = MIN_PREVIEW_ZOOM25; | |||
1790 | } | |||
1791 | else | |||
1792 | { | |||
1793 | nFactor += nOffset; | |||
1794 | if(nFactor > MAX_PREVIEW_ZOOM600) | |||
1795 | nFactor = MAX_PREVIEW_ZOOM600; | |||
1796 | } | |||
1797 | SetZoom(SvxZoomType::PERCENT, nFactor); | |||
1798 | } | |||
1799 | bOk = true; | |||
1800 | } | |||
1801 | else | |||
1802 | bOk = m_pViewWin->HandleScrollCommand( rCEvt, m_pHScrollbar, m_pVScrollbar ); | |||
1803 | return bOk; | |||
1804 | } | |||
1805 | ||||
1806 | uno::Reference< css::accessibility::XAccessible > | |||
1807 | SwPagePreviewWin::CreateAccessible() | |||
1808 | { | |||
1809 | SolarMutexGuard aGuard; // this should have happened already!!! | |||
1810 | ||||
1811 | OSL_ENSURE( GetViewShell() != nullptr, "We need a view shell" )do { if (true && (!(GetViewShell() != nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/uibase/uiview/pview.cxx" ":" "1811" ": "), "%s", "We need a view shell"); } } while ( false); | |||
1812 | css::uno::Reference< css::accessibility::XAccessible > xAcc = GetAccessible( false ); | |||
1813 | if (xAcc.is()) | |||
1814 | { | |||
1815 | return xAcc; | |||
1816 | } | |||
1817 | if (mpViewShell) | |||
1818 | { | |||
1819 | css::uno::Reference< css::accessibility::XAccessible > xAccPreview = mpViewShell->CreateAccessiblePreview(); | |||
1820 | SetAccessible(xAccPreview); | |||
1821 | } | |||
1822 | return GetAccessible( false ); | |||
1823 | } | |||
1824 | ||||
1825 | void SwPagePreview::ApplyAccessibilityOptions(SvtAccessibilityOptions const & rAccessibilityOptions) | |||
1826 | { | |||
1827 | GetViewShell()->ApplyAccessibilityOptions(rAccessibilityOptions); | |||
1828 | } | |||
1829 | ||||
1830 | void SwPagePreview::ShowHScrollbar(bool bShow) | |||
1831 | { | |||
1832 | m_pHScrollbar->Show(bShow); | |||
1833 | InvalidateBorder(); | |||
1834 | } | |||
1835 | ||||
1836 | void SwPagePreview::ShowVScrollbar(bool bShow) | |||
1837 | { | |||
1838 | m_pVScrollbar->Show(bShow); | |||
1839 | InvalidateBorder(); | |||
1840 | } | |||
1841 | ||||
1842 | void SwPagePreview::EnableHScrollbar(bool bEnable) | |||
1843 | { | |||
1844 | if (mbHScrollbarEnabled != bEnable) | |||
1845 | { | |||
1846 | mbHScrollbarEnabled = bEnable; | |||
1847 | ScrollViewSzChg(); | |||
1848 | } | |||
1849 | } | |||
1850 | ||||
1851 | void SwPagePreview::EnableVScrollbar(bool bEnable) | |||
1852 | { | |||
1853 | if (mbVScrollbarEnabled != bEnable) | |||
1854 | { | |||
1855 | mbVScrollbarEnabled = bEnable; | |||
1856 | ScrollViewSzChg(); | |||
1857 | } | |||
1858 | } | |||
1859 | ||||
1860 | void SwPagePreview::SetZoom(SvxZoomType eType, sal_uInt16 nFactor) | |||
1861 | { | |||
1862 | SwViewShell& rSh = *GetViewShell(); | |||
1863 | SwViewOption aOpt(*rSh.GetViewOptions()); | |||
1864 | // perform action only on changes of zoom or zoom type. | |||
1865 | if ( aOpt.GetZoom() != nFactor || | |||
1866 | aOpt.GetZoomType() != eType ) | |||
1867 | { | |||
1868 | aOpt.SetZoom(nFactor); | |||
1869 | aOpt.SetZoomType(eType); | |||
1870 | rSh.ApplyViewOptions( aOpt ); | |||
1871 | lcl_InvalidateZoomSlots(GetViewFrame()->GetBindings()); | |||
1872 | // #i19975# also consider zoom type | |||
1873 | m_pViewWin->AdjustPreviewToNewZoom( nFactor, eType ); | |||
1874 | ScrollViewSzChg(); | |||
1875 | } | |||
1876 | } | |||
1877 | ||||
1878 | /** adjust position of vertical scrollbar */ | |||
1879 | void SwPagePreview::SetVScrollbarThumbPos( const sal_uInt16 _nNewThumbPos ) | |||
1880 | { | |||
1881 | if ( m_pVScrollbar ) | |||
1882 | { | |||
1883 | m_pVScrollbar->SetThumbPos( _nNewThumbPos ); | |||
1884 | } | |||
1885 | } | |||
1886 | ||||
1887 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | |
20 | #ifndef INCLUDED_VCL_PTR_HXX |
21 | #define INCLUDED_VCL_PTR_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <rtl/ref.hxx> |
26 | |
27 | #include <utility> |
28 | #include <type_traits> |
29 | |
30 | #ifdef DBG_UTIL |
31 | #ifndef _WIN32 |
32 | #include <vcl/vclmain.hxx> |
33 | #endif |
34 | #endif |
35 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase( |
44 | int (*)[sizeof(T)]) |
45 | { return std::is_base_of<VclReferenceBase, T>::value; } |
46 | |
47 | } // namespace vcl::detail |
48 | |
49 | /** |
50 | * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses. |
51 | * |
52 | * For more details on the design please see vcl/README.lifecycle |
53 | * |
54 | * @param reference_type must be a subclass of vcl::Window |
55 | */ |
56 | template <class reference_type> |
57 | class VclPtr |
58 | { |
59 | static_assert( |
60 | vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>( |
61 | nullptr), |
62 | "template argument type must be derived from VclReferenceBase"); |
63 | |
64 | ::rtl::Reference<reference_type> m_rInnerRef; |
65 | |
66 | public: |
67 | /** Constructor... |
68 | */ |
69 | VclPtr() |
70 | : m_rInnerRef() |
71 | {} |
72 | |
73 | /** Constructor... |
74 | */ |
75 | VclPtr (reference_type * pBody) |
76 | : m_rInnerRef(pBody) |
77 | {} |
78 | |
79 | /** Constructor... that doesn't take a ref. |
80 | */ |
81 | VclPtr (reference_type * pBody, __sal_NoAcquire) |
82 | : m_rInnerRef(pBody, SAL_NO_ACQUIRE) |
83 | {} |
84 | |
85 | /** Up-casting conversion constructor: Copies interface reference. |
86 | |
87 | Does not work for up-casts to ambiguous bases. For the special case of |
88 | up-casting to Reference< XInterface >, see the corresponding conversion |
89 | operator. |
90 | |
91 | @param rRef another reference |
92 | */ |
93 | template< class derived_type > |
94 | VclPtr( |
95 | const VclPtr< derived_type > & rRef, |
96 | typename std::enable_if< |
97 | std::is_base_of<reference_type, derived_type>::value, int>::type |
98 | = 0 ) |
99 | : m_rInnerRef( static_cast<reference_type*>(rRef) ) |
100 | { |
101 | } |
102 | |
103 | #if defined(DBG_UTIL) && !defined(_WIN32) |
104 | virtual ~VclPtr() |
105 | { |
106 | assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain ::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 106, __extension__ __PRETTY_FUNCTION__)); |
107 | // We can be one of the intermediate counts, but if we are the last |
108 | // VclPtr keeping this object alive, then something forgot to call dispose(). |
109 | assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)) |
110 | && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)); |
111 | } |
112 | VclPtr(VclPtr const &) = default; |
113 | VclPtr(VclPtr &&) = default; |
114 | VclPtr & operator =(VclPtr const &) = default; |
115 | VclPtr & operator =(VclPtr &&) = default; |
116 | #endif |
117 | |
118 | /** |
119 | * A construction helper for VclPtr. Since VclPtr types are created |
120 | * with a reference-count of one - to help fit into the existing |
121 | * code-flow; this helps us to construct them easily. |
122 | * |
123 | * For more details on the design please see vcl/README.lifecycle |
124 | * |
125 | * @tparam reference_type must be a subclass of vcl::Window |
126 | */ |
127 | template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg) |
128 | { |
129 | return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ); |
130 | } |
131 | |
132 | /** Probably most common used: handle->someBodyOp(). |
133 | */ |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | /** Get the body. Can be used instead of operator->(). |
140 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
141 | are the same. |
142 | */ |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | /** Up-casting copy assignment operator. |
159 | |
160 | Does not work for up-casts to ambiguous bases. |
161 | |
162 | @param rRef another reference |
163 | */ |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | // hold it alive for the lifetime of this method |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-) |
205 | if (aTmp.get()) { |
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | /** Needed to place VclPtr's into STL collection. |
211 | */ |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; // class VclPtr |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) { |
261 | return !(p1 == p2); |
262 | } |
263 | |
264 | /** |
265 | * A construction helper for a temporary VclPtr. Since VclPtr types |
266 | * are created with a reference-count of one - to help fit into |
267 | * the existing code-flow; this helps us to construct them easily. |
268 | * see also VclPtr::Create and ScopedVclPtr |
269 | * |
270 | * For more details on the design please see vcl/README.lifecycle |
271 | * |
272 | * @param reference_type must be a subclass of vcl::Window |
273 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
278 | template<typename... Arg> VclPtrInstance(Arg &&... arg) |
279 | : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
280 | { |
281 | } |
282 | |
283 | /** |
284 | * Override and disallow this, to prevent people accidentally calling it and actually |
285 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
286 | */ |
287 | template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete; |
288 | }; |
289 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
294 | /** Constructor... |
295 | */ |
296 | ScopedVclPtr() |
297 | : VclPtr<reference_type>() |
298 | {} |
299 | |
300 | /** Constructor |
301 | */ |
302 | ScopedVclPtr (reference_type * pBody) |
303 | : VclPtr<reference_type>(pBody) |
304 | {} |
305 | |
306 | /** Copy constructor... |
307 | */ |
308 | ScopedVclPtr (const VclPtr<reference_type> & handle) |
309 | : VclPtr<reference_type>(handle) |
310 | {} |
311 | |
312 | /** |
313 | Assignment that releases the last reference. |
314 | */ |
315 | void disposeAndReset(reference_type *pBody) |
316 | { |
317 | if (pBody != this->get()) { |
318 | VclPtr<reference_type>::disposeAndClear(); |
319 | VclPtr<reference_type>::set(pBody); |
320 | } |
321 | } |
322 | |
323 | /** |
324 | Assignment that releases the last reference. |
325 | */ |
326 | ScopedVclPtr<reference_type>& operator = (reference_type * pBody) |
327 | { |
328 | disposeAndReset(pBody); |
329 | return *this; |
330 | } |
331 | |
332 | /** Up-casting conversion constructor: Copies interface reference. |
333 | |
334 | Does not work for up-casts to ambiguous bases. For the special case of |
335 | up-casting to Reference< XInterface >, see the corresponding conversion |
336 | operator. |
337 | |
338 | @param rRef another reference |
339 | */ |
340 | template< class derived_type > |
341 | ScopedVclPtr( |
342 | const VclPtr< derived_type > & rRef, |
343 | typename std::enable_if< |
344 | std::is_base_of<reference_type, derived_type>::value, int>::type |
345 | = 0 ) |
346 | : VclPtr<reference_type>( rRef ) |
347 | { |
348 | } |
349 | |
350 | /** Up-casting assignment operator. |
351 | |
352 | Does not work for up-casts to ambiguous bases. |
353 | |
354 | @param rRef another VclPtr |
355 | */ |
356 | template<typename derived_type> |
357 | typename std::enable_if< |
358 | std::is_base_of<reference_type, derived_type>::value, |
359 | ScopedVclPtr &>::type |
360 | operator =(VclPtr<derived_type> const & rRef) |
361 | { |
362 | disposeAndReset(rRef.get()); |
363 | return *this; |
364 | } |
365 | |
366 | /** |
367 | * Override and disallow this, to prevent people accidentally calling it and actually |
368 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
369 | */ |
370 | template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete; |
371 | |
372 | ~ScopedVclPtr() |
373 | { |
374 | VclPtr<reference_type>::disposeAndClear(); |
375 | assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get( ) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 375, __extension__ __PRETTY_FUNCTION__)); // make sure there are no lingering references |
376 | } |
377 | |
378 | private: |
379 | // Most likely we don't want this default copy-constructor. |
380 | ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete; |
381 | // And certainly we don't want a default assignment operator. |
382 | ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete; |
383 | // And disallow reset as that doesn't call disposeAndClear on the original reference |
384 | void reset() = delete; |
385 | void reset(reference_type *pBody) = delete; |
386 | |
387 | protected: |
388 | ScopedVclPtr (reference_type * pBody, __sal_NoAcquire) |
389 | : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE) |
390 | {} |
391 | }; |
392 | |
393 | /** |
394 | * A construction helper for ScopedVclPtr. Since VclPtr types are created |
395 | * with a reference-count of one - to help fit into the existing |
396 | * code-flow; this helps us to construct them easily. |
397 | * |
398 | * For more details on the design please see vcl/README.lifecycle |
399 | * |
400 | * @param reference_type must be a subclass of vcl::Window |
401 | */ |
402 | #if defined _MSC_VER |
403 | #pragma warning(push) |
404 | #pragma warning(disable: 4521) // " multiple copy constructors specified" |
405 | #endif |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
410 | template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg) |
411 | : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
412 | { |
413 | } |
414 | |
415 | /** |
416 | * Override and disallow this, to prevent people accidentally calling it and actually |
417 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
418 | */ |
419 | template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete; |
420 | |
421 | private: |
422 | // Prevent the above perfect forwarding ctor from hijacking (accidental) |
423 | // attempts at ScopedVclPtrInstance copy construction (where the hijacking |
424 | // would typically lead to somewhat obscure error messages); both non-const |
425 | // and const variants are needed here, as the ScopedVclPtr base class has a |
426 | // const--variant copy ctor, so the implicitly declared copy ctor for |
427 | // ScopedVclPtrInstance would also be the const variant, so non-const copy |
428 | // construction attempts would be hijacked by the perfect forwarding ctor; |
429 | // but if we only declared a non-const variant here, the const variant would |
430 | // no longer be implicitly declared (as there would already be an explicitly |
431 | // declared copy ctor), so const copy construction attempts would then be |
432 | // hijacked by the perfect forwarding ctor: |
433 | ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete; |
434 | ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete; |
435 | }; |
436 | #if defined _MSC_VER |
437 | #pragma warning(pop) |
438 | #endif |
439 | |
440 | #endif // INCLUDED_VCL_PTR_HXX |
441 | |
442 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||||
2 | /* | ||||||||
3 | * This file is part of the LibreOffice project. | ||||||||
4 | * | ||||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||||
8 | * | ||||||||
9 | * This file incorporates work covered by the following license notice: | ||||||||
10 | * | ||||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||||
13 | * with this work for additional information regarding copyright | ||||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||||
18 | */ | ||||||||
19 | |||||||||
20 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||
22 | |||||||||
23 | #include "sal/config.h" | ||||||||
24 | |||||||||
25 | #include <cassert> | ||||||||
26 | #include <cstddef> | ||||||||
27 | #include <functional> | ||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
29 | #include <type_traits> | ||||||||
30 | #endif | ||||||||
31 | |||||||||
32 | #include "sal/types.h" | ||||||||
33 | |||||||||
34 | namespace rtl | ||||||||
35 | { | ||||||||
36 | |||||||||
37 | /** Template reference class for reference type. | ||||||||
38 | */ | ||||||||
39 | template <class reference_type> | ||||||||
40 | class Reference | ||||||||
41 | { | ||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||
43 | */ | ||||||||
44 | reference_type * m_pBody; | ||||||||
45 | |||||||||
46 | |||||||||
47 | public: | ||||||||
48 | /** Constructor... | ||||||||
49 | */ | ||||||||
50 | Reference() | ||||||||
51 | : m_pBody (NULL__null) | ||||||||
52 | {} | ||||||||
53 | |||||||||
54 | |||||||||
55 | /** Constructor... | ||||||||
56 | */ | ||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||
58 | : m_pBody (pBody) | ||||||||
59 | { | ||||||||
60 | } | ||||||||
61 | |||||||||
62 | /** Constructor... | ||||||||
63 | */ | ||||||||
64 | Reference (reference_type * pBody) | ||||||||
65 | : m_pBody (pBody) | ||||||||
66 | { | ||||||||
67 | if (m_pBody) | ||||||||
68 | m_pBody->acquire(); | ||||||||
69 | } | ||||||||
70 | |||||||||
71 | /** Copy constructor... | ||||||||
72 | */ | ||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||
75 | { | ||||||||
76 | if (m_pBody) | ||||||||
77 | m_pBody->acquire(); | ||||||||
78 | } | ||||||||
79 | |||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
81 | /** Move constructor... | ||||||||
82 | */ | ||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||
85 | { | ||||||||
86 | handle.m_pBody = nullptr; | ||||||||
87 | } | ||||||||
88 | #endif | ||||||||
89 | |||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||
92 | |||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||
94 | |||||||||
95 | @param rRef another reference | ||||||||
96 | */ | ||||||||
97 | template< class derived_type > | ||||||||
98 | inline Reference( | ||||||||
99 | const Reference< derived_type > & rRef, | ||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||
101 | : m_pBody (rRef.get()) | ||||||||
102 | { | ||||||||
103 | if (m_pBody) | ||||||||
104 | m_pBody->acquire(); | ||||||||
105 | } | ||||||||
106 | #endif | ||||||||
107 | |||||||||
108 | /** Destructor... | ||||||||
109 | */ | ||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||
111 | { | ||||||||
112 | if (m_pBody) | ||||||||
113 | m_pBody->release(); | ||||||||
114 | } | ||||||||
115 | |||||||||
116 | /** Set... | ||||||||
117 | Similar to assignment. | ||||||||
118 | */ | ||||||||
119 | Reference<reference_type> & | ||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||
121 | { | ||||||||
122 | if (pBody) | ||||||||
123 | pBody->acquire(); | ||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||
125 | m_pBody = pBody; | ||||||||
126 | if (pOld) | ||||||||
127 | pOld->release(); | ||||||||
128 | return *this; | ||||||||
129 | } | ||||||||
130 | |||||||||
131 | /** Assignment. | ||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||
133 | bind it to the body represented by the handle. | ||||||||
134 | */ | ||||||||
135 | Reference<reference_type> & | ||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||
137 | { | ||||||||
138 | return set( handle.m_pBody ); | ||||||||
139 | } | ||||||||
140 | |||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||
142 | /** Assignment. | ||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||
144 | * bind it to the body represented by the handle, and | ||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||
146 | */ | ||||||||
147 | Reference<reference_type> & | ||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||
149 | { | ||||||||
150 | // self-movement guts ourself | ||||||||
151 | if (m_pBody) | ||||||||
152 | m_pBody->release(); | ||||||||
153 | m_pBody = handle.m_pBody; | ||||||||
154 | handle.m_pBody = nullptr; | ||||||||
155 | return *this; | ||||||||
156 | } | ||||||||
157 | #endif | ||||||||
158 | |||||||||
159 | /** Assignment... | ||||||||
160 | */ | ||||||||
161 | Reference<reference_type> & | ||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||
163 | { | ||||||||
164 | return set( pBody ); | ||||||||
165 | } | ||||||||
166 | |||||||||
167 | /** Unbind the body from this handle. | ||||||||
168 | Note that for a handle representing a large body, | ||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||
171 | since in the second case two large objects exist in memory | ||||||||
172 | (the old body and the new body). | ||||||||
173 | */ | ||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||
175 | { | ||||||||
176 | if (m_pBody
| ||||||||
177 | { | ||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||
179 | m_pBody = NULL__null; | ||||||||
180 | pOld->release(); | ||||||||
181 | } | ||||||||
182 | return *this; | ||||||||
183 | } | ||||||||
184 | |||||||||
185 | |||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||
188 | are the same. | ||||||||
189 | */ | ||||||||
190 | reference_type * SAL_CALL get() const | ||||||||
191 | { | ||||||||
192 | return m_pBody; | ||||||||
| |||||||||
193 | } | ||||||||
194 | |||||||||
195 | |||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||
197 | */ | ||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||
199 | { | ||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||
201 | return m_pBody; | ||||||||
202 | } | ||||||||
203 | |||||||||
204 | |||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||
206 | */ | ||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||
208 | { | ||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||
210 | return *m_pBody; | ||||||||
211 | } | ||||||||
212 | |||||||||
213 | |||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||
215 | */ | ||||||||
216 | bool SAL_CALL is() const | ||||||||
217 | { | ||||||||
218 | return (m_pBody != NULL__null); | ||||||||
219 | } | ||||||||
220 | |||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||
223 | */ | ||||||||
224 | explicit operator bool() const | ||||||||
225 | { | ||||||||
226 | return is(); | ||||||||
227 | } | ||||||||
228 | #endif | ||||||||
229 | |||||||||
230 | /** Returns True if this points to pBody. | ||||||||
231 | */ | ||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||
233 | { | ||||||||
234 | return (m_pBody == pBody); | ||||||||
235 | } | ||||||||
236 | |||||||||
237 | |||||||||
238 | /** Returns True if handle points to the same body. | ||||||||
239 | */ | ||||||||
240 | bool | ||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||
242 | { | ||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||
244 | } | ||||||||
245 | |||||||||
246 | |||||||||
247 | /** Needed to place References into STL collection. | ||||||||
248 | */ | ||||||||
249 | bool | ||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||
251 | { | ||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||
253 | } | ||||||||
254 | |||||||||
255 | |||||||||
256 | /** Needed to place References into STL collection. | ||||||||
257 | */ | ||||||||
258 | bool | ||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||
260 | { | ||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||
262 | } | ||||||||
263 | |||||||||
264 | |||||||||
265 | /** Needed to place References into STL collection. | ||||||||
266 | */ | ||||||||
267 | bool | ||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||
269 | { | ||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||
271 | } | ||||||||
272 | }; | ||||||||
273 | |||||||||
274 | } // namespace rtl | ||||||||
275 | |||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||
277 | namespace std | ||||||||
278 | { | ||||||||
279 | |||||||||
280 | /// @cond INTERNAL | ||||||||
281 | /** | ||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||
283 | |||||||||
284 | @since LibreOffice 6.3 | ||||||||
285 | */ | ||||||||
286 | template<typename T> | ||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||
288 | { | ||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||
290 | { return std::size_t(s.get()); } | ||||||||
291 | }; | ||||||||
292 | /// @endcond | ||||||||
293 | |||||||||
294 | } | ||||||||
295 | |||||||||
296 | #endif | ||||||||
297 | |||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||
299 | |||||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |