/src/libreoffice/editeng/source/outliner/outlvw.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <memory> |
21 | | #include <com/sun/star/i18n/WordType.hpp> |
22 | | |
23 | | #include <svl/itempool.hxx> |
24 | | #include <editeng/editeng.hxx> |
25 | | #include <editeng/editview.hxx> |
26 | | #include <editeng/editdata.hxx> |
27 | | #include <editeng/StripPortionsHelper.hxx> |
28 | | |
29 | | #include <svl/style.hxx> |
30 | | #include <svl/languageoptions.hxx> |
31 | | #include <i18nlangtag/languagetag.hxx> |
32 | | |
33 | | #include <editeng/outliner.hxx> |
34 | | #include <outleeng.hxx> |
35 | | #include "paralist.hxx" |
36 | | #include "outlundo.hxx" |
37 | | #include <editeng/outlobj.hxx> |
38 | | #include <editeng/flditem.hxx> |
39 | | #include <editeng/eeitem.hxx> |
40 | | #include <editeng/numitem.hxx> |
41 | | #include <vcl/window.hxx> |
42 | | #include <vcl/event.hxx> |
43 | | #include <vcl/ptrstyle.hxx> |
44 | | #include <svl/itemset.hxx> |
45 | | #include <svl/eitem.hxx> |
46 | | #include <editeng/editstat.hxx> |
47 | | #include <sal/log.hxx> |
48 | | #include <osl/diagnose.h> |
49 | | #include <tools/debug.hxx> |
50 | | |
51 | | using namespace ::com::sun::star; |
52 | | |
53 | | OutlinerView::OutlinerView(Outliner& rOut, vcl::Window* pWin) |
54 | 0 | : rOwner(rOut) |
55 | 0 | , pEditView(new EditView(rOut.getOutlinerEditEng(), pWin)) |
56 | 0 | { |
57 | 0 | } |
58 | | |
59 | | OutlinerView::~OutlinerView() |
60 | 0 | { |
61 | 0 | } |
62 | | |
63 | | void OutlinerView::DrawText_ToEditView( const tools::Rectangle& rRect, OutputDevice* pTargetDevice ) |
64 | 0 | { |
65 | | // For the first Paint/KeyInput/Drop an empty Outliner is turned into |
66 | | // an Outliner with exactly one paragraph. |
67 | 0 | if( rOwner.bFirstParaIsEmpty ) |
68 | 0 | rOwner.Insert( OUString() ); |
69 | | |
70 | | // use TextHierarchyBreakupOutliner to get all text embedded to the |
71 | | // TextHierarchy.*Primitive2D groupings for better processing, plus |
72 | | // the correct paragraph countings |
73 | 0 | TextHierarchyBreakupOutliner aHelper(rOwner); |
74 | | |
75 | | // hand that Helper over to DrawText_ToEditView at the EditEngine |
76 | | // for usage |
77 | 0 | pEditView->DrawText_ToEditView( aHelper, rRect, pTargetDevice ); |
78 | 0 | } |
79 | | |
80 | | bool OutlinerView::PostKeyEvent( const KeyEvent& rKEvt, vcl::Window const * pFrameWin ) |
81 | 0 | { |
82 | | // For the first Paint/KeyInput/Drop an empty Outliner is turned into |
83 | | // an Outliner with exactly one paragraph. |
84 | 0 | if( rOwner.bFirstParaIsEmpty ) |
85 | 0 | rOwner.Insert( OUString() ); |
86 | |
|
87 | 0 | bool bKeyProcessed = false; |
88 | 0 | ESelection aSel( pEditView->GetSelection() ); |
89 | 0 | bool bSelection = aSel.HasRange(); |
90 | 0 | vcl::KeyCode aKeyCode = rKEvt.GetKeyCode(); |
91 | 0 | KeyFuncType eFunc = aKeyCode.GetFunction(); |
92 | 0 | sal_uInt16 nCode = aKeyCode.GetCode(); |
93 | 0 | bool bReadOnly = IsReadOnly(); |
94 | |
|
95 | 0 | if( bSelection && ( nCode != KEY_TAB ) && EditEngine::DoesKeyChangeText( rKEvt ) ) |
96 | 0 | { |
97 | 0 | if ( ImpCalcSelectedPages( false ) && !rOwner.ImpCanDeleteSelectedPages( this ) ) |
98 | 0 | return true; |
99 | 0 | } |
100 | | |
101 | 0 | if ( eFunc != KeyFuncType::DONTKNOW ) |
102 | 0 | { |
103 | 0 | switch ( eFunc ) |
104 | 0 | { |
105 | 0 | case KeyFuncType::CUT: |
106 | 0 | { |
107 | 0 | if ( !bReadOnly ) |
108 | 0 | { |
109 | 0 | Cut(); |
110 | 0 | bKeyProcessed = true; |
111 | 0 | } |
112 | 0 | } |
113 | 0 | break; |
114 | 0 | case KeyFuncType::COPY: |
115 | 0 | { |
116 | 0 | Copy(); |
117 | 0 | bKeyProcessed = true; |
118 | 0 | } |
119 | 0 | break; |
120 | 0 | case KeyFuncType::PASTE: |
121 | 0 | { |
122 | 0 | if ( !bReadOnly ) |
123 | 0 | { |
124 | 0 | PasteSpecial(); |
125 | 0 | bKeyProcessed = true; |
126 | 0 | } |
127 | 0 | } |
128 | 0 | break; |
129 | 0 | case KeyFuncType::DELETE: |
130 | 0 | { |
131 | 0 | if( !bReadOnly && !bSelection && ( rOwner.GetOutlinerMode() != OutlinerMode::TextObject ) ) |
132 | 0 | { |
133 | 0 | if (aSel.end.nIndex == rOwner.pEditEngine->GetTextLen(aSel.end.nPara)) |
134 | 0 | { |
135 | 0 | Paragraph* pNext = rOwner.pParaList->GetParagraph(aSel.end.nPara + 1); |
136 | 0 | if( pNext && pNext->HasFlag(ParaFlag::ISPAGE) ) |
137 | 0 | { |
138 | 0 | if (!rOwner.ImpCanDeleteSelectedPages(this, aSel.end.nPara, 1)) |
139 | 0 | return false; |
140 | 0 | } |
141 | 0 | } |
142 | 0 | } |
143 | 0 | } |
144 | 0 | break; |
145 | 0 | default: // is then possibly edited below. |
146 | 0 | eFunc = KeyFuncType::DONTKNOW; |
147 | 0 | } |
148 | 0 | } |
149 | 0 | if ( eFunc == KeyFuncType::DONTKNOW ) |
150 | 0 | { |
151 | 0 | switch ( nCode ) |
152 | 0 | { |
153 | 0 | case KEY_TAB: |
154 | 0 | { |
155 | 0 | if ( !bReadOnly && !aKeyCode.IsMod1() && !aKeyCode.IsMod2() ) |
156 | 0 | { |
157 | 0 | if ( ( rOwner.GetOutlinerMode() != OutlinerMode::TextObject ) && |
158 | 0 | ( rOwner.GetOutlinerMode() != OutlinerMode::TitleObject ) && |
159 | 0 | ( bSelection || !aSel.start.nIndex ) ) |
160 | 0 | { |
161 | 0 | Indent( aKeyCode.IsShift() ? -1 : +1 ); |
162 | 0 | bKeyProcessed = true; |
163 | 0 | } |
164 | 0 | else if ( ( rOwner.GetOutlinerMode() == OutlinerMode::TextObject ) && |
165 | 0 | !bSelection && !aSel.end.nIndex && rOwner.ImplHasNumberFormat( aSel.end.nPara ) ) |
166 | 0 | { |
167 | 0 | Indent( aKeyCode.IsShift() ? -1 : +1 ); |
168 | 0 | bKeyProcessed = true; |
169 | 0 | } |
170 | 0 | } |
171 | 0 | } |
172 | 0 | break; |
173 | 0 | case KEY_BACKSPACE: |
174 | 0 | { |
175 | 0 | if (!bReadOnly && !bSelection && aSel.end.nPara && !aSel.end.nIndex) |
176 | 0 | { |
177 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph(aSel.end.nPara); |
178 | 0 | Paragraph* pPrev = rOwner.pParaList->GetParagraph(aSel.end.nPara - 1); |
179 | 0 | if( !pPrev->IsVisible() ) |
180 | 0 | return true; |
181 | 0 | if( !pPara->GetDepth() ) |
182 | 0 | { |
183 | 0 | if (!rOwner.ImpCanDeleteSelectedPages(this, aSel.end.nPara, 1)) |
184 | 0 | return true; |
185 | 0 | } |
186 | 0 | } |
187 | 0 | } |
188 | 0 | break; |
189 | 0 | case KEY_RETURN: |
190 | 0 | { |
191 | 0 | if ( !bReadOnly ) |
192 | 0 | { |
193 | | // Special treatment: hard return at the end of a paragraph, |
194 | | // which has collapsed subparagraphs. |
195 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph(aSel.end.nPara); |
196 | |
|
197 | 0 | if( !aKeyCode.IsShift() ) |
198 | 0 | { |
199 | | // Don't let insert empty paragraph with numbering. Instead end numbering. |
200 | 0 | if (pPara->GetDepth() > -1 && |
201 | 0 | rOwner.pEditEngine->GetTextLen( aSel.end.nPara ) == 0) |
202 | 0 | { |
203 | 0 | ToggleBullets(); |
204 | 0 | return true; |
205 | 0 | } |
206 | | // ImpGetCursor again??? |
207 | 0 | if( !bSelection && |
208 | 0 | aSel.end.nIndex == rOwner.pEditEngine->GetTextLen( aSel.end.nPara ) ) |
209 | 0 | { |
210 | 0 | sal_Int32 nChildren = rOwner.pParaList->GetChildCount(pPara); |
211 | 0 | if( nChildren && !rOwner.pParaList->HasVisibleChildren(pPara)) |
212 | 0 | { |
213 | 0 | rOwner.UndoActionStart( OLUNDO_INSERT ); |
214 | 0 | sal_Int32 nTemp = aSel.end.nPara; |
215 | 0 | nTemp += nChildren; |
216 | 0 | nTemp++; // insert above next Non-Child |
217 | 0 | SAL_WARN_IF( nTemp < 0, "editeng", "OutlinerView::PostKeyEvent - overflow"); |
218 | 0 | if (nTemp >= 0) |
219 | 0 | { |
220 | 0 | rOwner.Insert( OUString(),nTemp,pPara->GetDepth()); |
221 | | // Position the cursor |
222 | 0 | ESelection aTmpSel(nTemp, 0); |
223 | 0 | pEditView->SetSelection( aTmpSel ); |
224 | 0 | } |
225 | 0 | pEditView->ShowCursor(); |
226 | 0 | rOwner.UndoActionEnd(); |
227 | 0 | bKeyProcessed = true; |
228 | 0 | } |
229 | 0 | } |
230 | 0 | } |
231 | 0 | if( !bKeyProcessed && !bSelection && |
232 | 0 | !aKeyCode.IsShift() && aKeyCode.IsMod1() && |
233 | 0 | ( aSel.end.nIndex == rOwner.pEditEngine->GetTextLen(aSel.end.nPara) ) ) |
234 | 0 | { |
235 | 0 | rOwner.UndoActionStart( OLUNDO_INSERT ); |
236 | 0 | sal_Int32 nTemp = aSel.end.nPara; |
237 | 0 | nTemp++; |
238 | 0 | rOwner.Insert( OUString(), nTemp, pPara->GetDepth()+1 ); |
239 | | |
240 | | // Position the cursor |
241 | 0 | ESelection aTmpSel(nTemp, 0); |
242 | 0 | pEditView->SetSelection( aTmpSel ); |
243 | 0 | pEditView->ShowCursor(); |
244 | 0 | rOwner.UndoActionEnd(); |
245 | 0 | bKeyProcessed = true; |
246 | 0 | } |
247 | 0 | } |
248 | 0 | } |
249 | 0 | break; |
250 | 0 | } |
251 | 0 | } |
252 | | |
253 | 0 | return bKeyProcessed || pEditView->PostKeyEvent( rKEvt, pFrameWin ); |
254 | 0 | } |
255 | | |
256 | | sal_Int32 OutlinerView::ImpCheckMousePos(const Point& rPosPix, MouseTarget& reTarget) |
257 | 0 | { |
258 | 0 | sal_Int32 nPara = EE_PARA_MAX; |
259 | |
|
260 | 0 | Point aMousePosWin = pEditView->GetOutputDevice().PixelToLogic( rPosPix ); |
261 | 0 | if( !pEditView->GetOutputArea().Contains( aMousePosWin ) ) |
262 | 0 | { |
263 | 0 | reTarget = MouseTarget::Outside; |
264 | 0 | } |
265 | 0 | else |
266 | 0 | { |
267 | 0 | reTarget = MouseTarget::Text; |
268 | |
|
269 | 0 | Point aPaperPos( aMousePosWin ); |
270 | 0 | tools::Rectangle aOutArea = pEditView->GetOutputArea(); |
271 | 0 | tools::Rectangle aVisArea = pEditView->GetVisArea(); |
272 | 0 | aPaperPos.AdjustX( -(aOutArea.Left()) ); |
273 | 0 | aPaperPos.AdjustX(aVisArea.Left() ); |
274 | 0 | aPaperPos.AdjustY( -(aOutArea.Top()) ); |
275 | 0 | aPaperPos.AdjustY(aVisArea.Top() ); |
276 | |
|
277 | 0 | bool bBullet; |
278 | 0 | if ( rOwner.IsTextPos( aPaperPos, 0, &bBullet ) ) |
279 | 0 | { |
280 | 0 | Point aDocPos = rOwner.GetDocPos( aPaperPos ); |
281 | 0 | nPara = rOwner.pEditEngine->FindParagraph( aDocPos.Y() ); |
282 | |
|
283 | 0 | if ( bBullet ) |
284 | 0 | { |
285 | 0 | reTarget = MouseTarget::Bullet; |
286 | 0 | } |
287 | 0 | else |
288 | 0 | { |
289 | | // Check for hyperlink |
290 | 0 | const SvxFieldItem* pFieldItem = pEditView->GetField( aMousePosWin ); |
291 | 0 | if ( pFieldItem && pFieldItem->GetField() && dynamic_cast< const SvxURLField* >(pFieldItem->GetField()) != nullptr ) |
292 | 0 | reTarget = MouseTarget::Hypertext; |
293 | 0 | } |
294 | 0 | } |
295 | 0 | } |
296 | 0 | return nPara; |
297 | 0 | } |
298 | | |
299 | | bool OutlinerView::MouseMove( const MouseEvent& rMEvt ) |
300 | 0 | { |
301 | 0 | if( ( rOwner.GetOutlinerMode() == OutlinerMode::TextObject ) || pEditView->getEditEngine().IsInSelectionMode()) |
302 | 0 | return pEditView->MouseMove( rMEvt ); |
303 | | |
304 | 0 | Point aMousePosWin( pEditView->GetOutputDevice().PixelToLogic( rMEvt.GetPosPixel() ) ); |
305 | 0 | if( !pEditView->GetOutputArea().Contains( aMousePosWin ) ) |
306 | 0 | return false; |
307 | | |
308 | 0 | PointerStyle aPointer = GetPointer( rMEvt.GetPosPixel() ); |
309 | 0 | pEditView->GetWindow()->SetPointer( aPointer ); |
310 | 0 | return pEditView->MouseMove( rMEvt ); |
311 | 0 | } |
312 | | |
313 | | |
314 | | bool OutlinerView::MouseButtonDown( const MouseEvent& rMEvt ) |
315 | 0 | { |
316 | 0 | if ( ( rOwner.GetOutlinerMode() == OutlinerMode::TextObject ) || pEditView->getEditEngine().IsInSelectionMode() ) |
317 | 0 | return pEditView->MouseButtonDown( rMEvt ); |
318 | | |
319 | 0 | Point aMousePosWin( pEditView->GetOutputDevice().PixelToLogic( rMEvt.GetPosPixel() ) ); |
320 | 0 | if( !pEditView->GetOutputArea().Contains( aMousePosWin ) ) |
321 | 0 | return false; |
322 | | |
323 | 0 | PointerStyle aPointer = GetPointer( rMEvt.GetPosPixel() ); |
324 | 0 | pEditView->GetWindow()->SetPointer( aPointer ); |
325 | |
|
326 | 0 | MouseTarget eTarget; |
327 | 0 | sal_Int32 nPara = ImpCheckMousePos( rMEvt.GetPosPixel(), eTarget ); |
328 | 0 | if ( eTarget == MouseTarget::Bullet ) |
329 | 0 | { |
330 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
331 | 0 | bool bHasChildren = (pPara && rOwner.pParaList->HasChildren(pPara)); |
332 | 0 | if( rMEvt.GetClicks() == 1 ) |
333 | 0 | { |
334 | 0 | sal_Int32 nEndPara = nPara; |
335 | 0 | if ( bHasChildren && rOwner.pParaList->HasVisibleChildren(pPara) ) |
336 | 0 | nEndPara += rOwner.pParaList->GetChildCount( pPara ); |
337 | | // The selection is inverted, so that EditEngine does not scroll |
338 | 0 | ESelection aSel(nEndPara, EE_TEXTPOS_MAX, nPara, 0); |
339 | 0 | pEditView->SetSelection( aSel ); |
340 | 0 | } |
341 | 0 | else if( rMEvt.GetClicks() == 2 && bHasChildren ) |
342 | 0 | ImpToggleExpand( pPara ); |
343 | |
|
344 | 0 | return true; |
345 | 0 | } |
346 | | |
347 | | // special case for outliner view in impress, check if double click hits the page icon for toggle |
348 | 0 | if( (nPara == EE_PARA_MAX) && (rOwner.GetOutlinerMode() == OutlinerMode::OutlineView) && (eTarget == MouseTarget::Text) && (rMEvt.GetClicks() == 2) ) |
349 | 0 | { |
350 | 0 | ESelection aSel( pEditView->GetSelection() ); |
351 | 0 | nPara = aSel.start.nPara; |
352 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
353 | 0 | if( (pPara && rOwner.pParaList->HasChildren(pPara)) && pPara->HasFlag(ParaFlag::ISPAGE) ) |
354 | 0 | { |
355 | 0 | ImpToggleExpand( pPara ); |
356 | 0 | } |
357 | 0 | } |
358 | 0 | return pEditView->MouseButtonDown( rMEvt ); |
359 | 0 | } |
360 | | |
361 | | |
362 | | bool OutlinerView::MouseButtonUp( const MouseEvent& rMEvt ) |
363 | 0 | { |
364 | 0 | if ( ( rOwner.GetOutlinerMode() == OutlinerMode::TextObject ) || pEditView->getEditEngine().IsInSelectionMode() ) |
365 | 0 | return pEditView->MouseButtonUp( rMEvt ); |
366 | | |
367 | 0 | Point aMousePosWin( pEditView->GetOutputDevice().PixelToLogic( rMEvt.GetPosPixel() ) ); |
368 | 0 | if( !pEditView->GetOutputArea().Contains( aMousePosWin ) ) |
369 | 0 | return false; |
370 | | |
371 | 0 | PointerStyle aPointer = GetPointer( rMEvt.GetPosPixel() ); |
372 | 0 | pEditView->GetWindow()->SetPointer( aPointer ); |
373 | |
|
374 | 0 | return pEditView->MouseButtonUp( rMEvt ); |
375 | 0 | } |
376 | | |
377 | | void OutlinerView::ReleaseMouse() |
378 | 0 | { |
379 | 0 | pEditView->ReleaseMouse(); |
380 | 0 | } |
381 | | |
382 | | void OutlinerView::ImpToggleExpand( Paragraph const * pPara ) |
383 | 0 | { |
384 | 0 | sal_Int32 nPara = rOwner.pParaList->GetAbsPos( pPara ); |
385 | 0 | pEditView->SetSelection(ESelection(nPara, 0)); |
386 | 0 | ImplExpandOrCollaps( nPara, nPara, !rOwner.pParaList->HasVisibleChildren( pPara ) ); |
387 | 0 | pEditView->ShowCursor(); |
388 | 0 | } |
389 | | |
390 | | void OutlinerView::Select( Paragraph const * pParagraph, bool bSelect ) |
391 | 0 | { |
392 | 0 | sal_Int32 nPara = rOwner.pParaList->GetAbsPos( pParagraph ); |
393 | 0 | sal_Int32 nEnd = 0; |
394 | 0 | if ( bSelect ) |
395 | 0 | nEnd = SAL_MAX_INT32; |
396 | |
|
397 | 0 | ESelection aSel( nPara, 0, nPara, nEnd ); |
398 | 0 | pEditView->SetSelection( aSel ); |
399 | 0 | } |
400 | | |
401 | | void OutlinerView::SetDepth(sal_Int32 nParagraph, sal_Int16 nDepth) |
402 | 0 | { |
403 | 0 | Paragraph* pParagraph = rOwner.GetParagraph(nParagraph); |
404 | 0 | rOwner.SetDepth(pParagraph, nDepth); |
405 | 0 | } |
406 | | |
407 | | sal_Int16 OutlinerView::GetDepth() const |
408 | 0 | { |
409 | 0 | ESelection aESelection = GetSelection(); |
410 | 0 | aESelection.Adjust(); |
411 | 0 | sal_Int16 nDepth = rOwner.GetDepth(aESelection.start.nPara); |
412 | 0 | for (sal_Int32 nPara = aESelection.start.nPara + 1; nPara <= aESelection.end.nPara; ++nPara) |
413 | 0 | { |
414 | 0 | if (nDepth != rOwner.GetDepth(nPara)) |
415 | 0 | return -2; |
416 | 0 | } |
417 | 0 | return nDepth; |
418 | 0 | } |
419 | | |
420 | | void OutlinerView::SetAttribs( const SfxItemSet& rAttrs ) |
421 | 0 | { |
422 | 0 | bool bUpdate = rOwner.pEditEngine->SetUpdateLayout( false ); |
423 | |
|
424 | 0 | if( !rOwner.IsInUndo() && rOwner.IsUndoEnabled() ) |
425 | 0 | rOwner.UndoActionStart( OLUNDO_ATTR ); |
426 | |
|
427 | 0 | ParaRange aSel = ImpGetSelectedParagraphs( false ); |
428 | |
|
429 | 0 | pEditView->SetAttribs( rAttrs ); |
430 | | |
431 | | // Update Bullet text |
432 | 0 | for( sal_Int32 nPara= aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) |
433 | 0 | { |
434 | 0 | rOwner.ImplCheckNumBulletItem( nPara ); |
435 | 0 | rOwner.ImplCalcBulletText( nPara, false, false ); |
436 | |
|
437 | 0 | if( !rOwner.IsInUndo() && rOwner.IsUndoEnabled() ) |
438 | 0 | rOwner.InsertUndo( std::make_unique<OutlinerUndoCheckPara>( &rOwner, nPara ) ); |
439 | 0 | } |
440 | |
|
441 | 0 | if( !rOwner.IsInUndo() && rOwner.IsUndoEnabled() ) |
442 | 0 | rOwner.UndoActionEnd(); |
443 | |
|
444 | 0 | pEditView->SetEditEngineUpdateLayout( bUpdate ); |
445 | 0 | } |
446 | | |
447 | | ParaRange OutlinerView::ImpGetSelectedParagraphs( bool bIncludeHiddenChildren ) |
448 | 0 | { |
449 | 0 | ESelection aSel = pEditView->GetSelection(); |
450 | 0 | ParaRange aParas(aSel.start.nPara, aSel.end.nPara); |
451 | 0 | aParas.Adjust(); |
452 | | |
453 | | // Record the invisible Children of the last Parents in the selection |
454 | 0 | if ( bIncludeHiddenChildren ) |
455 | 0 | { |
456 | 0 | Paragraph* pLast = rOwner.pParaList->GetParagraph( aParas.nEndPara ); |
457 | 0 | if ( rOwner.pParaList->HasHiddenChildren( pLast ) ) |
458 | 0 | aParas.nEndPara = aParas.nEndPara + rOwner.pParaList->GetChildCount( pLast ); |
459 | 0 | } |
460 | 0 | return aParas; |
461 | 0 | } |
462 | | |
463 | | // TODO: Name should be changed! |
464 | | void OutlinerView::AdjustDepth( short nDX ) |
465 | 0 | { |
466 | 0 | Indent( nDX ); |
467 | 0 | } |
468 | | |
469 | | void OutlinerView::Indent( short nDiff ) |
470 | 0 | { |
471 | 0 | if( !nDiff || ( ( nDiff > 0 ) && ImpCalcSelectedPages( true ) && !rOwner.ImpCanIndentSelectedPages( this ) ) ) |
472 | 0 | return; |
473 | | |
474 | 0 | const bool bOutlinerView = bool(rOwner.pEditEngine->GetControlWord() & EEControlBits::OUTLINER); |
475 | 0 | bool bUpdate = rOwner.pEditEngine->SetUpdateLayout( false ); |
476 | |
|
477 | 0 | bool bUndo = !rOwner.IsInUndo() && rOwner.IsUndoEnabled(); |
478 | |
|
479 | 0 | if( bUndo ) |
480 | 0 | rOwner.UndoActionStart( OLUNDO_DEPTH ); |
481 | |
|
482 | 0 | sal_Int16 nMinDepth = -1; // Optimization: avoid recalculate too many paragraphs if not really needed. |
483 | |
|
484 | 0 | ParaRange aSel = ImpGetSelectedParagraphs( true ); |
485 | 0 | for ( sal_Int32 nPara = aSel.nStartPara; nPara <= aSel.nEndPara; nPara++ ) |
486 | 0 | { |
487 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
488 | |
|
489 | 0 | sal_Int16 nOldDepth = pPara->GetDepth(); |
490 | 0 | sal_Int16 nNewDepth = nOldDepth + nDiff; |
491 | |
|
492 | 0 | if( bOutlinerView && nPara ) |
493 | 0 | { |
494 | 0 | const bool bPage = pPara->HasFlag(ParaFlag::ISPAGE); |
495 | 0 | if( (bPage && (nDiff == +1)) || (!bPage && (nDiff == -1) && (nOldDepth <= 0)) ) |
496 | 0 | { |
497 | | // Notify App |
498 | 0 | rOwner.nDepthChangedHdlPrevDepth = nOldDepth; |
499 | 0 | ParaFlag nPrevFlags = pPara->nFlags; |
500 | |
|
501 | 0 | if( bPage ) |
502 | 0 | pPara->RemoveFlag( ParaFlag::ISPAGE ); |
503 | 0 | else |
504 | 0 | pPara->SetFlag( ParaFlag::ISPAGE ); |
505 | |
|
506 | 0 | rOwner.DepthChangedHdl(pPara, nPrevFlags); |
507 | 0 | rOwner.pEditEngine->QuickMarkInvalid(ESelection(nPara, 0)); |
508 | |
|
509 | 0 | if( bUndo ) |
510 | 0 | rOwner.InsertUndo( std::make_unique<OutlinerUndoChangeParaFlags>( &rOwner, nPara, nPrevFlags, pPara->nFlags ) ); |
511 | |
|
512 | 0 | continue; |
513 | 0 | } |
514 | 0 | } |
515 | | |
516 | | // do not switch off numeration with tab |
517 | 0 | if( (nOldDepth == 0) && (nNewDepth == -1) ) |
518 | 0 | continue; |
519 | | |
520 | | // do not indent if there is no numeration enabled |
521 | 0 | if( nOldDepth == -1 ) |
522 | 0 | continue; |
523 | | |
524 | 0 | if ( nNewDepth < Outliner::gnMinDepth ) |
525 | 0 | nNewDepth = Outliner::gnMinDepth; |
526 | 0 | if ( nNewDepth > rOwner.nMaxDepth ) |
527 | 0 | nNewDepth = rOwner.nMaxDepth; |
528 | |
|
529 | 0 | if( nOldDepth < nMinDepth ) |
530 | 0 | nMinDepth = nOldDepth; |
531 | 0 | if( nNewDepth < nMinDepth ) |
532 | 0 | nMinDepth = nNewDepth; |
533 | |
|
534 | 0 | if( nOldDepth != nNewDepth ) |
535 | 0 | { |
536 | 0 | if ( ( nPara == aSel.nStartPara ) && aSel.nStartPara && ( rOwner.GetOutlinerMode() != OutlinerMode::TextObject )) |
537 | 0 | { |
538 | | // Special case: the predecessor of an indented paragraph is |
539 | | // invisible and is now on the same level as the visible |
540 | | // paragraph. In this case, the next visible paragraph is |
541 | | // searched for and fluffed. |
542 | | #ifdef DBG_UTIL |
543 | | Paragraph* _pPara = rOwner.pParaList->GetParagraph( aSel.nStartPara ); |
544 | | DBG_ASSERT(_pPara->IsVisible(),"Selected Paragraph invisible ?!"); |
545 | | #endif |
546 | 0 | Paragraph* pPrev= rOwner.pParaList->GetParagraph( aSel.nStartPara-1 ); |
547 | |
|
548 | 0 | if( !pPrev->IsVisible() && ( pPrev->GetDepth() == nNewDepth ) ) |
549 | 0 | { |
550 | | // Predecessor is collapsed and is on the same level |
551 | | // => find next visible paragraph and expand it |
552 | 0 | pPrev = rOwner.pParaList->GetParent( pPrev ); |
553 | 0 | while( !pPrev->IsVisible() ) |
554 | 0 | pPrev = rOwner.pParaList->GetParent( pPrev ); |
555 | |
|
556 | 0 | rOwner.Expand( pPrev ); |
557 | 0 | rOwner.InvalidateBullet(rOwner.pParaList->GetAbsPos(pPrev)); |
558 | 0 | } |
559 | 0 | } |
560 | |
|
561 | 0 | rOwner.nDepthChangedHdlPrevDepth = nOldDepth; |
562 | 0 | ParaFlag nPrevFlags = pPara->nFlags; |
563 | |
|
564 | 0 | rOwner.ImplInitDepth( nPara, nNewDepth, true ); |
565 | 0 | rOwner.ImplCalcBulletText( nPara, false, false ); |
566 | |
|
567 | 0 | if ( rOwner.GetOutlinerMode() == OutlinerMode::OutlineObject ) |
568 | 0 | rOwner.ImplSetLevelDependentStyleSheet( nPara ); |
569 | | |
570 | | // Notify App |
571 | 0 | rOwner.DepthChangedHdl(pPara, nPrevFlags); |
572 | 0 | } |
573 | 0 | else |
574 | 0 | { |
575 | | // Needs at least a repaint... |
576 | 0 | rOwner.pEditEngine->QuickMarkInvalid(ESelection(nPara, 0)); |
577 | 0 | } |
578 | 0 | } |
579 | |
|
580 | 0 | sal_Int32 nParas = rOwner.pParaList->GetParagraphCount(); |
581 | 0 | for ( sal_Int32 n = aSel.nEndPara+1; n < nParas; n++ ) |
582 | 0 | { |
583 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( n ); |
584 | 0 | if ( pPara->GetDepth() < nMinDepth ) |
585 | 0 | break; |
586 | 0 | rOwner.ImplCalcBulletText( n, false, false ); |
587 | 0 | } |
588 | |
|
589 | 0 | if ( bUpdate ) |
590 | 0 | { |
591 | 0 | pEditView->SetEditEngineUpdateLayout( true ); |
592 | 0 | pEditView->ShowCursor(); |
593 | 0 | } |
594 | |
|
595 | 0 | if( bUndo ) |
596 | 0 | rOwner.UndoActionEnd(); |
597 | 0 | } |
598 | | |
599 | | void OutlinerView::AdjustHeight( tools::Long nDY ) |
600 | 0 | { |
601 | 0 | pEditView->MoveParagraphs( nDY ); |
602 | 0 | } |
603 | | |
604 | | tools::Rectangle OutlinerView::GetVisArea() const |
605 | 0 | { |
606 | 0 | return pEditView->GetVisArea(); |
607 | 0 | } |
608 | | |
609 | | void OutlinerView::Expand() |
610 | 0 | { |
611 | 0 | ParaRange aParas = ImpGetSelectedParagraphs( false ); |
612 | 0 | ImplExpandOrCollaps( aParas.nStartPara, aParas.nEndPara, true ); |
613 | 0 | } |
614 | | |
615 | | |
616 | | void OutlinerView::Collapse() |
617 | 0 | { |
618 | 0 | ParaRange aParas = ImpGetSelectedParagraphs( false ); |
619 | 0 | ImplExpandOrCollaps( aParas.nStartPara, aParas.nEndPara, false ); |
620 | 0 | } |
621 | | |
622 | | |
623 | | void OutlinerView::ExpandAll() |
624 | 0 | { |
625 | 0 | ImplExpandOrCollaps( 0, rOwner.pParaList->GetParagraphCount()-1, true ); |
626 | 0 | } |
627 | | |
628 | | |
629 | | void OutlinerView::CollapseAll() |
630 | 0 | { |
631 | 0 | ImplExpandOrCollaps( 0, rOwner.pParaList->GetParagraphCount()-1, false ); |
632 | 0 | } |
633 | | |
634 | | void OutlinerView::ImplExpandOrCollaps( sal_Int32 nStartPara, sal_Int32 nEndPara, bool bExpand ) |
635 | 0 | { |
636 | 0 | bool bUpdate = rOwner.SetUpdateLayout( false ); |
637 | |
|
638 | 0 | bool bUndo = !rOwner.IsInUndo() && rOwner.IsUndoEnabled(); |
639 | 0 | if( bUndo ) |
640 | 0 | rOwner.UndoActionStart( bExpand ? OLUNDO_EXPAND : OLUNDO_COLLAPSE ); |
641 | |
|
642 | 0 | for ( sal_Int32 nPara = nStartPara; nPara <= nEndPara; nPara++ ) |
643 | 0 | { |
644 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
645 | 0 | bool bDone = bExpand ? rOwner.Expand( pPara ) : rOwner.Collapse( pPara ); |
646 | 0 | if( bDone ) |
647 | 0 | { |
648 | | // The line under the paragraph should disappear ... |
649 | 0 | rOwner.pEditEngine->QuickMarkToBeRepainted( nPara ); |
650 | 0 | } |
651 | 0 | } |
652 | |
|
653 | 0 | if( bUndo ) |
654 | 0 | rOwner.UndoActionEnd(); |
655 | |
|
656 | 0 | if ( bUpdate ) |
657 | 0 | { |
658 | 0 | rOwner.SetUpdateLayout( true ); |
659 | 0 | pEditView->ShowCursor(); |
660 | 0 | } |
661 | 0 | } |
662 | | |
663 | | void OutlinerView::InsertText( const OutlinerParaObject& rParaObj ) |
664 | 0 | { |
665 | | // Like Paste, only EditView::Insert, instead of EditView::Paste. |
666 | | // Actually not quite true that possible indentations must be corrected, |
667 | | // but that comes later by a universal import. The indentation level is |
668 | | // then determined right in the Inserted method. |
669 | | // Possible structure: |
670 | | // pImportInfo with DestPara, DestPos, nFormat, pParaObj... |
671 | | // Possibly problematic: |
672 | | // EditEngine, RTF => Splitting the area, later join together. |
673 | |
|
674 | 0 | if ( ImpCalcSelectedPages( false ) && !rOwner.ImpCanDeleteSelectedPages( this ) ) |
675 | 0 | return; |
676 | | |
677 | 0 | rOwner.UndoActionStart( OLUNDO_INSERT ); |
678 | |
|
679 | 0 | const bool bPrevUpdateLayout = rOwner.pEditEngine->SetUpdateLayout( false ); |
680 | 0 | sal_Int32 nStart, nParaCount; |
681 | 0 | nParaCount = rOwner.pEditEngine->GetParagraphCount(); |
682 | 0 | sal_uInt16 nSize = ImpInitPaste( nStart ); |
683 | 0 | pEditView->InsertText( rParaObj.GetTextObject() ); |
684 | 0 | ImpPasted( nStart, nParaCount, nSize); |
685 | 0 | pEditView->SetEditEngineUpdateLayout( bPrevUpdateLayout ); |
686 | |
|
687 | 0 | rOwner.UndoActionEnd(); |
688 | |
|
689 | 0 | pEditView->ShowCursor(); |
690 | 0 | } |
691 | | |
692 | | |
693 | | void OutlinerView::Cut() |
694 | 0 | { |
695 | 0 | if ( !ImpCalcSelectedPages( false ) || rOwner.ImpCanDeleteSelectedPages( this ) ) { |
696 | 0 | pEditView->Cut(); |
697 | | // Chaining handling |
698 | 0 | aEndCutPasteLink.Call(nullptr); |
699 | 0 | } |
700 | 0 | } |
701 | | |
702 | | void OutlinerView::PasteSpecial(SotClipboardFormatId format) |
703 | 0 | { |
704 | 0 | Paste( true, format ); |
705 | 0 | } |
706 | | |
707 | | void OutlinerView::Paste( bool bUseSpecial, SotClipboardFormatId format) |
708 | 0 | { |
709 | 0 | if ( ImpCalcSelectedPages( false ) && !rOwner.ImpCanDeleteSelectedPages( this ) ) |
710 | 0 | return; |
711 | | |
712 | 0 | rOwner.UndoActionStart( OLUNDO_INSERT ); |
713 | |
|
714 | 0 | const bool bPrevUpdateLayout = rOwner.pEditEngine->SetUpdateLayout( false ); |
715 | 0 | rOwner.bPasting = true; |
716 | |
|
717 | 0 | if ( bUseSpecial ) |
718 | 0 | pEditView->PasteSpecial(format); |
719 | 0 | else |
720 | 0 | pEditView->Paste(); |
721 | |
|
722 | 0 | if ( rOwner.GetOutlinerMode() == OutlinerMode::OutlineObject ) |
723 | 0 | { |
724 | 0 | const sal_Int32 nParaCount = rOwner.pEditEngine->GetParagraphCount(); |
725 | |
|
726 | 0 | for( sal_Int32 nPara = 0; nPara < nParaCount; nPara++ ) |
727 | 0 | rOwner.ImplSetLevelDependentStyleSheet( nPara ); |
728 | 0 | } |
729 | |
|
730 | 0 | pEditView->SetEditEngineUpdateLayout( bPrevUpdateLayout ); |
731 | 0 | rOwner.UndoActionEnd(); |
732 | 0 | pEditView->ShowCursor(); |
733 | | |
734 | | // Chaining handling |
735 | | // NOTE: We need to do this last because it pEditView may be deleted if a switch of box occurs |
736 | 0 | aEndCutPasteLink.Call(nullptr); |
737 | 0 | } |
738 | | |
739 | | void OutlinerView::CreateSelectionList (std::vector<Paragraph*> &aSelList) |
740 | 0 | { |
741 | 0 | ParaRange aParas = ImpGetSelectedParagraphs( true ); |
742 | |
|
743 | 0 | for ( sal_Int32 nPara = aParas.nStartPara; nPara <= aParas.nEndPara; nPara++ ) |
744 | 0 | { |
745 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
746 | 0 | aSelList.push_back(pPara); |
747 | 0 | } |
748 | 0 | } |
749 | | |
750 | | void OutlinerView::SetStyleSheet(const OUString& rStyleName) |
751 | 0 | { |
752 | 0 | ParaRange aParas = ImpGetSelectedParagraphs(false); |
753 | |
|
754 | 0 | auto pStyle = rOwner.GetStyleSheetPool()->Find(rStyleName, SfxStyleFamily::Para); |
755 | 0 | if (!pStyle) |
756 | 0 | return; |
757 | | |
758 | 0 | for (sal_Int32 nPara = aParas.nStartPara; nPara <= aParas.nEndPara; nPara++) |
759 | 0 | rOwner.SetStyleSheet(nPara, static_cast<SfxStyleSheet*>(pStyle)); |
760 | 0 | } |
761 | | |
762 | | const SfxStyleSheet* OutlinerView::GetStyleSheet() const |
763 | 0 | { |
764 | 0 | return pEditView->GetStyleSheet(); |
765 | 0 | } |
766 | | |
767 | | SfxStyleSheet* OutlinerView::GetStyleSheet() |
768 | 0 | { |
769 | 0 | return pEditView->GetStyleSheet(); |
770 | 0 | } |
771 | | |
772 | | PointerStyle OutlinerView::GetPointer( const Point& rPosPixel ) |
773 | 0 | { |
774 | 0 | MouseTarget eTarget; |
775 | 0 | ImpCheckMousePos( rPosPixel, eTarget ); |
776 | |
|
777 | 0 | PointerStyle ePointerStyle = PointerStyle::Arrow; |
778 | 0 | if ( eTarget == MouseTarget::Text ) |
779 | 0 | { |
780 | 0 | ePointerStyle = GetOutliner().IsVertical() ? PointerStyle::TextVertical : PointerStyle::Text; |
781 | 0 | } |
782 | 0 | else if ( eTarget == MouseTarget::Hypertext ) |
783 | 0 | { |
784 | 0 | ePointerStyle = PointerStyle::RefHand; |
785 | 0 | } |
786 | 0 | else if ( eTarget == MouseTarget::Bullet ) |
787 | 0 | { |
788 | 0 | ePointerStyle = PointerStyle::Move; |
789 | 0 | } |
790 | |
|
791 | 0 | return ePointerStyle; |
792 | 0 | } |
793 | | |
794 | | |
795 | | sal_Int32 OutlinerView::ImpInitPaste( sal_Int32& rStart ) |
796 | 0 | { |
797 | 0 | rOwner.bPasting = true; |
798 | 0 | ESelection aSelection( pEditView->GetSelection() ); |
799 | 0 | aSelection.Adjust(); |
800 | 0 | rStart = aSelection.start.nPara; |
801 | 0 | sal_Int32 nSize = aSelection.end.nPara - aSelection.start.nPara + 1; |
802 | 0 | return nSize; |
803 | 0 | } |
804 | | |
805 | | |
806 | | void OutlinerView::ImpPasted( sal_Int32 nStart, sal_Int32 nPrevParaCount, sal_Int32 nSize) |
807 | 0 | { |
808 | 0 | rOwner.bPasting = false; |
809 | 0 | sal_Int32 nCurParaCount = rOwner.pEditEngine->GetParagraphCount(); |
810 | 0 | if( nCurParaCount < nPrevParaCount ) |
811 | 0 | nSize = nSize - ( nPrevParaCount - nCurParaCount ); |
812 | 0 | else |
813 | 0 | nSize = nSize + ( nCurParaCount - nPrevParaCount ); |
814 | 0 | rOwner.ImpTextPasted( nStart, nSize ); |
815 | 0 | } |
816 | | |
817 | | bool OutlinerView::Command(const CommandEvent& rCEvt) |
818 | 0 | { |
819 | 0 | return pEditView->Command(rCEvt); |
820 | 0 | } |
821 | | |
822 | | void OutlinerView::SelectRange( sal_Int32 nFirst, sal_Int32 nCount ) |
823 | 0 | { |
824 | 0 | ESelection aSel(nFirst, 0, nFirst + nCount, EE_TEXTPOS_MAX); |
825 | 0 | pEditView->SetSelection( aSel ); |
826 | 0 | } |
827 | | |
828 | | |
829 | | sal_Int32 OutlinerView::ImpCalcSelectedPages( bool bIncludeFirstSelected ) |
830 | 0 | { |
831 | 0 | ESelection aSel( pEditView->GetSelection() ); |
832 | 0 | aSel.Adjust(); |
833 | |
|
834 | 0 | sal_Int32 nPages = 0; |
835 | 0 | sal_Int32 nFirstPage = EE_PARA_MAX; |
836 | 0 | sal_Int32 nStartPara = aSel.start.nPara; |
837 | 0 | if ( !bIncludeFirstSelected ) |
838 | 0 | nStartPara++; // All paragraphs after StartPara will be deleted |
839 | 0 | for (sal_Int32 nPara = nStartPara; nPara <= aSel.end.nPara; nPara++) |
840 | 0 | { |
841 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
842 | 0 | assert(pPara && "ImpCalcSelectedPages: invalid Selection?"); |
843 | 0 | if( pPara->HasFlag(ParaFlag::ISPAGE) ) |
844 | 0 | { |
845 | 0 | nPages++; |
846 | 0 | if (nFirstPage == EE_PARA_MAX) |
847 | 0 | nFirstPage = nPara; |
848 | 0 | } |
849 | 0 | } |
850 | |
|
851 | 0 | if( nPages ) |
852 | 0 | { |
853 | 0 | rOwner.nDepthChangedHdlPrevDepth = nPages; |
854 | 0 | rOwner.mnFirstSelPage = nFirstPage; |
855 | 0 | } |
856 | |
|
857 | 0 | return nPages; |
858 | 0 | } |
859 | | |
860 | | |
861 | | void OutlinerView::ToggleBullets() |
862 | 0 | { |
863 | 0 | rOwner.UndoActionStart( OLUNDO_DEPTH ); |
864 | |
|
865 | 0 | ESelection aSel( pEditView->GetSelection() ); |
866 | 0 | aSel.Adjust(); |
867 | |
|
868 | 0 | const bool bUpdate = rOwner.pEditEngine->SetUpdateLayout( false ); |
869 | |
|
870 | 0 | sal_Int16 nNewDepth = -2; |
871 | 0 | const SvxNumRule* pDefaultBulletNumRule = nullptr; |
872 | |
|
873 | 0 | for (sal_Int32 nPara = aSel.start.nPara; nPara <= aSel.end.nPara; nPara++) |
874 | 0 | { |
875 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
876 | 0 | DBG_ASSERT(pPara, "OutlinerView::ToggleBullets(), illegal selection?"); |
877 | |
|
878 | 0 | if( pPara ) |
879 | 0 | { |
880 | 0 | if( nNewDepth == -2 ) |
881 | 0 | { |
882 | 0 | nNewDepth = (rOwner.GetDepth(nPara) == -1) ? 0 : -1; |
883 | 0 | if ( nNewDepth == 0 ) |
884 | 0 | { |
885 | | // determine default numbering rule for bullets |
886 | 0 | const ESelection aSelection(nPara, 0); |
887 | 0 | const SfxItemSet aTmpSet(rOwner.pEditEngine->GetAttribs(aSelection)); |
888 | 0 | const SfxPoolItem& rPoolItem = aTmpSet.GetPool()->GetUserOrPoolDefaultItem( EE_PARA_NUMBULLET ); |
889 | 0 | const SvxNumBulletItem* pNumBulletItem = dynamic_cast< const SvxNumBulletItem* >(&rPoolItem); |
890 | 0 | pDefaultBulletNumRule = pNumBulletItem ? &pNumBulletItem->GetNumRule() : nullptr; |
891 | 0 | } |
892 | 0 | } |
893 | |
|
894 | 0 | rOwner.SetDepth( pPara, nNewDepth ); |
895 | |
|
896 | 0 | if( nNewDepth == -1 ) |
897 | 0 | { |
898 | 0 | const SfxItemSet& rAttrs = rOwner.GetParaAttribs( nPara ); |
899 | 0 | if ( rAttrs.GetItemState( EE_PARA_BULLETSTATE ) == SfxItemState::SET ) |
900 | 0 | { |
901 | 0 | SfxItemSet aAttrs(rAttrs); |
902 | 0 | aAttrs.ClearItem( EE_PARA_BULLETSTATE ); |
903 | 0 | rOwner.SetParaAttribs( nPara, aAttrs ); |
904 | 0 | } |
905 | 0 | } |
906 | 0 | else |
907 | 0 | { |
908 | 0 | if ( pDefaultBulletNumRule ) |
909 | 0 | { |
910 | 0 | const SvxNumberFormat* pFmt = rOwner.GetNumberFormat( nPara ); |
911 | 0 | if ( !pFmt |
912 | 0 | || ( pFmt->GetNumberingType() != SVX_NUM_BITMAP |
913 | 0 | && pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL ) ) |
914 | 0 | { |
915 | 0 | SfxItemSet aAttrs( rOwner.GetParaAttribs( nPara ) ); |
916 | 0 | SvxNumRule aNewNumRule( *pDefaultBulletNumRule ); |
917 | 0 | aAttrs.Put( SvxNumBulletItem( std::move(aNewNumRule), EE_PARA_NUMBULLET ) ); |
918 | 0 | rOwner.SetParaAttribs( nPara, aAttrs ); |
919 | 0 | } |
920 | 0 | } |
921 | 0 | } |
922 | 0 | } |
923 | 0 | } |
924 | |
|
925 | 0 | const sal_Int32 nParaCount = rOwner.pParaList->GetParagraphCount(); |
926 | 0 | rOwner.ImplCheckParagraphs(aSel.start.nPara, nParaCount); |
927 | |
|
928 | 0 | sal_Int32 nEndPara = (nParaCount > 0) ? nParaCount-1 : nParaCount; |
929 | 0 | rOwner.pEditEngine->QuickMarkInvalid(ESelection(aSel.start.nPara, 0, nEndPara, 0)); |
930 | |
|
931 | 0 | rOwner.pEditEngine->SetUpdateLayout( bUpdate ); |
932 | |
|
933 | 0 | rOwner.UndoActionEnd(); |
934 | 0 | } |
935 | | |
936 | | bool OutlinerView::IsBulletOrNumbering(bool& bBullets, bool& bNumbering) |
937 | 0 | { |
938 | | //TODO: returns true if the same list is active in the selection, |
939 | | // sets bBullets/bNumbering if the related list type is found |
940 | 0 | bool bBulletFound = false; |
941 | 0 | bool bNumberingFound = false; |
942 | |
|
943 | 0 | ESelection aSel( pEditView->GetSelection() ); |
944 | 0 | aSel.Adjust(); |
945 | 0 | for (sal_Int32 nPara = aSel.start.nPara; nPara <= aSel.end.nPara; nPara++) |
946 | 0 | { |
947 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
948 | 0 | DBG_ASSERT(pPara, "OutlinerView::IsBulletOrNumbering(), illegal selection?"); |
949 | |
|
950 | 0 | if( pPara ) |
951 | 0 | { |
952 | 0 | if (rOwner.GetDepth(nPara) < 0) |
953 | 0 | return false; |
954 | 0 | const SvxNumberFormat* pFmt = rOwner.GetNumberFormat(nPara); |
955 | 0 | if (pFmt) |
956 | 0 | { |
957 | 0 | sal_Int16 nNumType = pFmt->GetNumberingType(); |
958 | 0 | if (nNumType != SVX_NUM_BITMAP && nNumType != SVX_NUM_CHAR_SPECIAL) |
959 | 0 | bNumberingFound = true; |
960 | 0 | else |
961 | 0 | bBulletFound = true; |
962 | 0 | } |
963 | 0 | } |
964 | 0 | } |
965 | 0 | if (bNumberingFound) |
966 | 0 | { |
967 | 0 | if (bBulletFound) |
968 | 0 | return false; |
969 | 0 | bNumbering = true; |
970 | 0 | } |
971 | 0 | else |
972 | 0 | bBullets = true; |
973 | 0 | return true; |
974 | 0 | } |
975 | | |
976 | | void OutlinerView::ToggleBulletsNumbering( |
977 | | const bool bToggle, |
978 | | const bool bHandleBullets, |
979 | | const SvxNumRule* pNumRule ) |
980 | 0 | { |
981 | 0 | ESelection aSel( pEditView->GetSelection() ); |
982 | 0 | aSel.Adjust(); |
983 | |
|
984 | 0 | bool bToggleOn = true; |
985 | 0 | if ( bToggle ) |
986 | 0 | { |
987 | 0 | bToggleOn = false; |
988 | 0 | const sal_Int16 nBulletNumberingStatus( rOwner.GetBulletsNumberingStatus( aSel.start.nPara, aSel.end.nPara ) ); |
989 | 0 | if ( nBulletNumberingStatus != 0 && bHandleBullets ) |
990 | 0 | { |
991 | | // not all paragraphs have bullets and method called to toggle bullets --> bullets on |
992 | 0 | bToggleOn = true; |
993 | 0 | } |
994 | 0 | else if ( nBulletNumberingStatus != 1 && !bHandleBullets ) |
995 | 0 | { |
996 | | // not all paragraphs have numbering and method called to toggle numberings --> numberings on |
997 | 0 | bToggleOn = true; |
998 | 0 | } |
999 | 0 | } |
1000 | 0 | if ( bToggleOn ) |
1001 | 0 | { |
1002 | | // apply bullets/numbering for selected paragraphs |
1003 | 0 | ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle, true ); |
1004 | 0 | } |
1005 | 0 | else |
1006 | 0 | { |
1007 | | // switch off bullets/numbering for selected paragraphs |
1008 | 0 | SwitchOffBulletsNumbering( true ); |
1009 | 0 | } |
1010 | 0 | } |
1011 | | |
1012 | | void OutlinerView::EnsureNumberingIsOn() |
1013 | 0 | { |
1014 | 0 | rOwner.UndoActionStart(OLUNDO_DEPTH); |
1015 | |
|
1016 | 0 | ESelection aSel(pEditView->GetSelection()); |
1017 | 0 | aSel.Adjust(); |
1018 | |
|
1019 | 0 | const bool bUpdate = rOwner.pEditEngine->IsUpdateLayout(); |
1020 | 0 | rOwner.pEditEngine->SetUpdateLayout(false); |
1021 | |
|
1022 | 0 | for (sal_Int32 nPara = aSel.start.nPara; nPara <= aSel.end.nPara; nPara++) |
1023 | 0 | { |
1024 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph(nPara); |
1025 | 0 | DBG_ASSERT(pPara, "OutlinerView::EnableBullets(), illegal selection?"); |
1026 | |
|
1027 | 0 | if (pPara && rOwner.GetDepth(nPara) == -1) |
1028 | 0 | rOwner.SetDepth(pPara, 0); |
1029 | 0 | } |
1030 | |
|
1031 | 0 | sal_Int32 nParaCount = rOwner.pParaList->GetParagraphCount(); |
1032 | 0 | rOwner.ImplCheckParagraphs(aSel.start.nPara, nParaCount); |
1033 | |
|
1034 | 0 | const sal_Int32 nEndPara = (nParaCount > 0) ? nParaCount-1 : nParaCount; |
1035 | 0 | rOwner.pEditEngine->QuickMarkInvalid(ESelection(aSel.start.nPara, 0, nEndPara, 0)); |
1036 | |
|
1037 | 0 | rOwner.pEditEngine->SetUpdateLayout(bUpdate); |
1038 | |
|
1039 | 0 | rOwner.UndoActionEnd(); |
1040 | 0 | } |
1041 | | |
1042 | | void OutlinerView::ApplyBulletsNumbering( |
1043 | | const bool bHandleBullets, |
1044 | | const SvxNumRule* pNewNumRule, |
1045 | | const bool bCheckCurrentNumRuleBeforeApplyingNewNumRule, |
1046 | | const bool bAtSelection ) |
1047 | 0 | { |
1048 | 0 | if (!rOwner.pEditEngine || !rOwner.pParaList) |
1049 | 0 | return; |
1050 | | |
1051 | 0 | rOwner.UndoActionStart(OLUNDO_DEPTH); |
1052 | 0 | const bool bUpdate = rOwner.pEditEngine->SetUpdateLayout(false); |
1053 | |
|
1054 | 0 | sal_Int32 nStartPara = 0; |
1055 | 0 | sal_Int32 nEndPara = 0; |
1056 | 0 | if ( bAtSelection ) |
1057 | 0 | { |
1058 | 0 | ESelection aSel( pEditView->GetSelection() ); |
1059 | 0 | aSel.Adjust(); |
1060 | 0 | nStartPara = aSel.start.nPara; |
1061 | 0 | nEndPara = aSel.end.nPara; |
1062 | 0 | } |
1063 | 0 | else |
1064 | 0 | { |
1065 | 0 | nStartPara = 0; |
1066 | 0 | nEndPara = rOwner.pParaList->GetParagraphCount() - 1; |
1067 | 0 | } |
1068 | |
|
1069 | 0 | for (sal_Int32 nPara = nStartPara; nPara <= nEndPara; ++nPara) |
1070 | 0 | { |
1071 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph(nPara); |
1072 | 0 | DBG_ASSERT(pPara, "OutlinerView::ApplyBulletsNumbering(..), illegal selection?"); |
1073 | |
|
1074 | 0 | if (pPara) |
1075 | 0 | { |
1076 | 0 | const sal_Int16 nDepth = rOwner.GetDepth(nPara); |
1077 | 0 | if ( nDepth == -1 ) |
1078 | 0 | { |
1079 | 0 | rOwner.SetDepth( pPara, 0 ); |
1080 | 0 | } |
1081 | |
|
1082 | 0 | const SfxItemSet& rAttrs = rOwner.GetParaAttribs(nPara); |
1083 | 0 | SfxItemSet aAttrs(rAttrs); |
1084 | 0 | aAttrs.Put(SfxBoolItem(EE_PARA_BULLETSTATE, true)); |
1085 | | |
1086 | | // apply new numbering rule |
1087 | 0 | if ( pNewNumRule ) |
1088 | 0 | { |
1089 | 0 | bool bApplyNumRule = false; |
1090 | 0 | if ( !bCheckCurrentNumRuleBeforeApplyingNewNumRule ) |
1091 | 0 | { |
1092 | 0 | bApplyNumRule = true; |
1093 | 0 | } |
1094 | 0 | else |
1095 | 0 | { |
1096 | 0 | const SvxNumberFormat* pFmt = rOwner.GetNumberFormat(nPara); |
1097 | 0 | if (!pFmt) |
1098 | 0 | { |
1099 | 0 | bApplyNumRule = true; |
1100 | 0 | } |
1101 | 0 | else |
1102 | 0 | { |
1103 | 0 | sal_Int16 nNumType = pFmt->GetNumberingType(); |
1104 | 0 | if ( bHandleBullets |
1105 | 0 | && nNumType != SVX_NUM_BITMAP && nNumType != SVX_NUM_CHAR_SPECIAL) |
1106 | 0 | { |
1107 | | // Set to Normal bullet, old bullet type is Numbering bullet. |
1108 | 0 | bApplyNumRule = true; |
1109 | 0 | } |
1110 | 0 | else if ( !bHandleBullets |
1111 | 0 | && (nNumType == SVX_NUM_BITMAP || nNumType == SVX_NUM_CHAR_SPECIAL)) |
1112 | 0 | { |
1113 | | // Set to Numbering bullet, old bullet type is Normal bullet. |
1114 | 0 | bApplyNumRule = true; |
1115 | 0 | } |
1116 | 0 | } |
1117 | 0 | } |
1118 | |
|
1119 | 0 | if ( bApplyNumRule ) |
1120 | 0 | { |
1121 | 0 | SvxNumRule aNewRule(*pNewNumRule); |
1122 | | |
1123 | | // Get old bullet space. |
1124 | 0 | { |
1125 | 0 | const SvxNumBulletItem* pNumBulletItem = rAttrs.GetItemIfSet(EE_PARA_NUMBULLET, false); |
1126 | 0 | if (pNumBulletItem) |
1127 | 0 | { |
1128 | | // Use default value when has not contain bullet item. |
1129 | 0 | ESelection aSelection(nPara, 0); |
1130 | 0 | SfxItemSet aTmpSet(rOwner.pEditEngine->GetAttribs(aSelection)); |
1131 | 0 | pNumBulletItem = aTmpSet.GetItem(EE_PARA_NUMBULLET); |
1132 | 0 | } |
1133 | |
|
1134 | 0 | if (pNumBulletItem) |
1135 | 0 | { |
1136 | 0 | const sal_uInt16 nLevelCnt = std::min(pNumBulletItem->GetNumRule().GetLevelCount(), aNewRule.GetLevelCount()); |
1137 | 0 | for ( sal_uInt16 nLevel = 0; nLevel < nLevelCnt; ++nLevel ) |
1138 | 0 | { |
1139 | 0 | const SvxNumberFormat* pOldFmt = pNumBulletItem->GetNumRule().Get(nLevel); |
1140 | 0 | const SvxNumberFormat* pNewFmt = aNewRule.Get(nLevel); |
1141 | 0 | if (pOldFmt && pNewFmt && (pOldFmt->GetFirstLineOffset() != pNewFmt->GetFirstLineOffset() || pOldFmt->GetAbsLSpace() != pNewFmt->GetAbsLSpace())) |
1142 | 0 | { |
1143 | 0 | SvxNumberFormat aNewFmtClone(*pNewFmt); |
1144 | 0 | aNewFmtClone.SetFirstLineOffset(pOldFmt->GetFirstLineOffset()); |
1145 | 0 | aNewFmtClone.SetAbsLSpace(pOldFmt->GetAbsLSpace()); |
1146 | 0 | aNewRule.SetLevel(nLevel, &aNewFmtClone); |
1147 | 0 | } |
1148 | 0 | } |
1149 | 0 | } |
1150 | 0 | } |
1151 | |
|
1152 | 0 | aAttrs.Put(SvxNumBulletItem(std::move(aNewRule), EE_PARA_NUMBULLET)); |
1153 | 0 | } |
1154 | 0 | } |
1155 | 0 | rOwner.SetParaAttribs(nPara, aAttrs); |
1156 | 0 | } |
1157 | 0 | } |
1158 | |
|
1159 | 0 | const sal_uInt16 nParaCount = static_cast<sal_uInt16>(rOwner.pParaList->GetParagraphCount()); |
1160 | 0 | rOwner.ImplCheckParagraphs( nStartPara, nParaCount ); |
1161 | 0 | rOwner.pEditEngine->QuickMarkInvalid( ESelection( nStartPara, 0, nParaCount, 0 ) ); |
1162 | |
|
1163 | 0 | rOwner.pEditEngine->SetUpdateLayout( bUpdate ); |
1164 | |
|
1165 | 0 | rOwner.UndoActionEnd(); |
1166 | 0 | } |
1167 | | |
1168 | | |
1169 | | void OutlinerView::SwitchOffBulletsNumbering( |
1170 | | const bool bAtSelection ) |
1171 | 0 | { |
1172 | 0 | sal_Int32 nStartPara = 0; |
1173 | 0 | sal_Int32 nEndPara = 0; |
1174 | 0 | if ( bAtSelection ) |
1175 | 0 | { |
1176 | 0 | ESelection aSel( pEditView->GetSelection() ); |
1177 | 0 | aSel.Adjust(); |
1178 | 0 | nStartPara = aSel.start.nPara; |
1179 | 0 | nEndPara = aSel.end.nPara; |
1180 | 0 | } |
1181 | 0 | else |
1182 | 0 | { |
1183 | 0 | nStartPara = 0; |
1184 | 0 | nEndPara = rOwner.pParaList->GetParagraphCount() - 1; |
1185 | 0 | } |
1186 | |
|
1187 | 0 | rOwner.UndoActionStart( OLUNDO_DEPTH ); |
1188 | 0 | const bool bUpdate = rOwner.pEditEngine->SetUpdateLayout( false ); |
1189 | |
|
1190 | 0 | for ( sal_Int32 nPara = nStartPara; nPara <= nEndPara; ++nPara ) |
1191 | 0 | { |
1192 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
1193 | 0 | DBG_ASSERT(pPara, "OutlinerView::SwitchOffBulletsNumbering(...), illegal paragraph index?"); |
1194 | |
|
1195 | 0 | if( pPara ) |
1196 | 0 | { |
1197 | 0 | rOwner.SetDepth( pPara, -1 ); |
1198 | |
|
1199 | 0 | const SfxItemSet& rAttrs = rOwner.GetParaAttribs( nPara ); |
1200 | 0 | if (rAttrs.GetItemState( EE_PARA_BULLETSTATE ) == SfxItemState::SET) |
1201 | 0 | { |
1202 | 0 | SfxItemSet aAttrs(rAttrs); |
1203 | 0 | aAttrs.ClearItem( EE_PARA_BULLETSTATE ); |
1204 | |
|
1205 | 0 | if (rOwner.GetOutlinerMode() == OutlinerMode::OutlineObject) |
1206 | 0 | { |
1207 | | // Outliner shape: also clear the SvxNumRule, so a next "switch on" will again |
1208 | | // work with styles from the master page. |
1209 | 0 | aAttrs.ClearItem(EE_PARA_NUMBULLET); |
1210 | 0 | } |
1211 | |
|
1212 | 0 | rOwner.SetParaAttribs( nPara, aAttrs ); |
1213 | 0 | } |
1214 | 0 | } |
1215 | 0 | } |
1216 | |
|
1217 | 0 | const sal_uInt16 nParaCount = static_cast<sal_uInt16>(rOwner.pParaList->GetParagraphCount()); |
1218 | 0 | rOwner.ImplCheckParagraphs( nStartPara, nParaCount ); |
1219 | 0 | rOwner.pEditEngine->QuickMarkInvalid( ESelection( nStartPara, 0, nParaCount, 0 ) ); |
1220 | |
|
1221 | 0 | rOwner.pEditEngine->SetUpdateLayout( bUpdate ); |
1222 | 0 | rOwner.UndoActionEnd(); |
1223 | 0 | } |
1224 | | |
1225 | | |
1226 | | void OutlinerView::RemoveAttribsKeepLanguages( bool bRemoveParaAttribs ) |
1227 | 0 | { |
1228 | 0 | RemoveAttribs( bRemoveParaAttribs, true /*keep language attribs*/ ); |
1229 | 0 | } |
1230 | | |
1231 | | void OutlinerView::RemoveAttribs( bool bRemoveParaAttribs, bool bKeepLanguages ) |
1232 | 0 | { |
1233 | 0 | bool bUpdate = rOwner.SetUpdateLayout( false ); |
1234 | 0 | rOwner.UndoActionStart( OLUNDO_ATTR ); |
1235 | 0 | if (bKeepLanguages) |
1236 | 0 | pEditView->RemoveAttribsKeepLanguages( bRemoveParaAttribs ); |
1237 | 0 | else |
1238 | 0 | pEditView->RemoveAttribs( bRemoveParaAttribs ); |
1239 | 0 | if ( bRemoveParaAttribs ) |
1240 | 0 | { |
1241 | | // Loop through all paragraphs and set indentation and level |
1242 | 0 | ESelection aSel = pEditView->GetSelection(); |
1243 | 0 | aSel.Adjust(); |
1244 | 0 | for (sal_Int32 nPara = aSel.start.nPara; nPara <= aSel.end.nPara; nPara++) |
1245 | 0 | { |
1246 | 0 | Paragraph* pPara = rOwner.pParaList->GetParagraph( nPara ); |
1247 | 0 | rOwner.ImplInitDepth( nPara, pPara->GetDepth(), false ); |
1248 | 0 | } |
1249 | 0 | } |
1250 | 0 | rOwner.UndoActionEnd(); |
1251 | 0 | rOwner.SetUpdateLayout( bUpdate ); |
1252 | 0 | } |
1253 | | |
1254 | | |
1255 | | // ====================== Simple pass-through ======================= |
1256 | | |
1257 | | |
1258 | | void OutlinerView::InsertText( const OUString& rNew, bool bSelect ) |
1259 | 0 | { |
1260 | 0 | if( rOwner.bFirstParaIsEmpty ) |
1261 | 0 | rOwner.Insert( OUString() ); |
1262 | 0 | pEditView->InsertText( rNew, bSelect ); |
1263 | 0 | } |
1264 | | |
1265 | | void OutlinerView::SetVisArea( const tools::Rectangle& rRect ) |
1266 | 0 | { |
1267 | 0 | pEditView->SetVisArea( rRect ); |
1268 | 0 | } |
1269 | | |
1270 | | |
1271 | | void OutlinerView::SetSelection( const ESelection& rSel ) |
1272 | 0 | { |
1273 | 0 | pEditView->SetSelection( rSel ); |
1274 | 0 | } |
1275 | | |
1276 | | void OutlinerView::GetSelectionRectangles(std::vector<tools::Rectangle>& rLogicRects) const |
1277 | 0 | { |
1278 | 0 | pEditView->GetSelectionRectangles(rLogicRects); |
1279 | 0 | } |
1280 | | |
1281 | | void OutlinerView::SetReadOnly( bool bReadOnly ) |
1282 | 0 | { |
1283 | 0 | pEditView->SetReadOnly( bReadOnly ); |
1284 | 0 | } |
1285 | | |
1286 | | bool OutlinerView::IsReadOnly() const |
1287 | 0 | { |
1288 | 0 | return pEditView->IsReadOnly(); |
1289 | 0 | } |
1290 | | |
1291 | | bool OutlinerView::HasSelection() const |
1292 | 0 | { |
1293 | 0 | return pEditView->HasSelection(); |
1294 | 0 | } |
1295 | | |
1296 | | void OutlinerView::ShowCursor( bool bGotoCursor, bool bActivate ) |
1297 | 0 | { |
1298 | 0 | pEditView->ShowCursor( bGotoCursor, /*bForceVisCursor=*/true, bActivate ); |
1299 | 0 | } |
1300 | | |
1301 | | void OutlinerView::HideCursor(bool bDeactivate) |
1302 | 0 | { |
1303 | 0 | pEditView->HideCursor(bDeactivate); |
1304 | 0 | } |
1305 | | |
1306 | 0 | bool OutlinerView::IsCursorVisible() const { return pEditView->IsCursorVisible(); } |
1307 | | |
1308 | | void OutlinerView::SetWindow( vcl::Window* pWin ) |
1309 | 0 | { |
1310 | 0 | pEditView->SetWindow( pWin ); |
1311 | 0 | } |
1312 | | |
1313 | | vcl::Window* OutlinerView::GetWindow() const |
1314 | 0 | { |
1315 | 0 | return pEditView->GetWindow(); |
1316 | 0 | } |
1317 | | |
1318 | | void OutlinerView::SetOutputArea( const tools::Rectangle& rRect ) |
1319 | 0 | { |
1320 | 0 | pEditView->SetOutputArea( rRect ); |
1321 | 0 | } |
1322 | | |
1323 | | tools::Rectangle const & OutlinerView::GetOutputArea() const |
1324 | 0 | { |
1325 | 0 | return pEditView->GetOutputArea(); |
1326 | 0 | } |
1327 | | |
1328 | | OUString OutlinerView::GetSelected() const |
1329 | 0 | { |
1330 | 0 | return pEditView->GetSelected(); |
1331 | 0 | } |
1332 | | |
1333 | | void OutlinerView::StartSpeller(weld::Widget* pDialogParent) |
1334 | 0 | { |
1335 | 0 | pEditView->StartSpeller(pDialogParent); |
1336 | 0 | } |
1337 | | |
1338 | | EESpellState OutlinerView::StartThesaurus(weld::Widget* pDialogParent) |
1339 | 0 | { |
1340 | 0 | return pEditView->StartThesaurus(pDialogParent); |
1341 | 0 | } |
1342 | | |
1343 | | void OutlinerView::StartTextConversion(weld::Widget* pDialogParent, |
1344 | | LanguageType nSrcLang, LanguageType nDestLang, const vcl::Font *pDestFont, |
1345 | | sal_Int32 nOptions, bool bIsInteractive, bool bMultipleDoc ) |
1346 | 0 | { |
1347 | 0 | if ( |
1348 | 0 | (LANGUAGE_KOREAN == nSrcLang && LANGUAGE_KOREAN == nDestLang) || |
1349 | 0 | (LANGUAGE_CHINESE_SIMPLIFIED == nSrcLang && LANGUAGE_CHINESE_TRADITIONAL == nDestLang) || |
1350 | 0 | (LANGUAGE_CHINESE_TRADITIONAL == nSrcLang && LANGUAGE_CHINESE_SIMPLIFIED == nDestLang) |
1351 | 0 | ) |
1352 | 0 | { |
1353 | 0 | pEditView->StartTextConversion(pDialogParent, nSrcLang, nDestLang, pDestFont, nOptions, bIsInteractive, bMultipleDoc); |
1354 | 0 | } |
1355 | 0 | else |
1356 | 0 | { |
1357 | 0 | OSL_FAIL( "unexpected language" ); |
1358 | 0 | } |
1359 | 0 | } |
1360 | | |
1361 | | |
1362 | | sal_Int32 OutlinerView::StartSearchAndReplace( const SvxSearchItem& rSearchItem ) |
1363 | 0 | { |
1364 | 0 | return pEditView->StartSearchAndReplace( rSearchItem ); |
1365 | 0 | } |
1366 | | |
1367 | | void OutlinerView::TransliterateText( TransliterationFlags nTransliterationMode ) |
1368 | 0 | { |
1369 | 0 | pEditView->TransliterateText( nTransliterationMode ); |
1370 | 0 | } |
1371 | | |
1372 | | ESelection OutlinerView::GetSelection() const |
1373 | 0 | { |
1374 | 0 | return pEditView->GetSelection(); |
1375 | 0 | } |
1376 | | |
1377 | | |
1378 | | void OutlinerView::Scroll( tools::Long nHorzScroll, tools::Long nVertScroll ) |
1379 | 0 | { |
1380 | 0 | pEditView->Scroll( nHorzScroll, nVertScroll ); |
1381 | 0 | } |
1382 | | |
1383 | | void OutlinerView::SetControlWord( EVControlBits nWord ) |
1384 | 0 | { |
1385 | 0 | pEditView->SetControlWord( nWord ); |
1386 | 0 | } |
1387 | | |
1388 | | EVControlBits OutlinerView::GetControlWord() const |
1389 | 0 | { |
1390 | 0 | return pEditView->GetControlWord(); |
1391 | 0 | } |
1392 | | |
1393 | | void OutlinerView::SetAnchorMode( EEAnchorMode eMode ) |
1394 | 0 | { |
1395 | 0 | pEditView->SetAnchorMode( eMode ); |
1396 | 0 | } |
1397 | | |
1398 | | EEAnchorMode OutlinerView::GetAnchorMode() const |
1399 | 0 | { |
1400 | 0 | return pEditView->GetAnchorMode(); |
1401 | 0 | } |
1402 | | |
1403 | | void OutlinerView::Copy() |
1404 | 0 | { |
1405 | 0 | pEditView->Copy(); |
1406 | 0 | } |
1407 | | |
1408 | | void OutlinerView::InsertField( const SvxFieldItem& rFld ) |
1409 | 0 | { |
1410 | 0 | pEditView->InsertField( rFld ); |
1411 | 0 | } |
1412 | | |
1413 | | const SvxFieldItem* OutlinerView::GetFieldUnderMousePointer() const |
1414 | 0 | { |
1415 | 0 | return pEditView->GetFieldUnderMousePointer(); |
1416 | 0 | } |
1417 | | |
1418 | | const SvxFieldItem* OutlinerView::GetFieldAtSelection(bool bAlsoCheckBeforeCursor) const |
1419 | 0 | { |
1420 | 0 | return pEditView->GetFieldAtSelection(bAlsoCheckBeforeCursor); |
1421 | 0 | } |
1422 | | |
1423 | | void OutlinerView::SelectFieldAtCursor() |
1424 | 0 | { |
1425 | 0 | pEditView->SelectFieldAtCursor(); |
1426 | 0 | } |
1427 | | |
1428 | | void OutlinerView::SetInvalidateMore( sal_uInt16 nPixel ) |
1429 | 0 | { |
1430 | 0 | pEditView->SetInvalidateMore( nPixel ); |
1431 | 0 | } |
1432 | | |
1433 | | |
1434 | | sal_uInt16 OutlinerView::GetInvalidateMore() const |
1435 | 0 | { |
1436 | 0 | return pEditView->GetInvalidateMore(); |
1437 | 0 | } |
1438 | | |
1439 | | |
1440 | | bool OutlinerView::IsCursorAtWrongSpelledWord() |
1441 | 0 | { |
1442 | 0 | return pEditView->IsCursorAtWrongSpelledWord(); |
1443 | 0 | } |
1444 | | |
1445 | | |
1446 | | bool OutlinerView::IsWrongSpelledWordAtPos( const Point& rPosPixel ) |
1447 | 0 | { |
1448 | 0 | return pEditView->IsWrongSpelledWordAtPos( rPosPixel, /*bMarkIfWrong*/false ); |
1449 | 0 | } |
1450 | | |
1451 | | bool OutlinerView::ExecuteSpellPopup(const Point& rPosPixel, const Link<SpellCallbackInfo&,void>& rStartDlg) |
1452 | 0 | { |
1453 | 0 | return pEditView->ExecuteSpellPopup(rPosPixel, rStartDlg); |
1454 | 0 | } |
1455 | | |
1456 | | void OutlinerView::Read( SvStream& rInput, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs ) |
1457 | 0 | { |
1458 | 0 | sal_Int32 nOldParaCount = pEditView->getEditEngine().GetParagraphCount(); |
1459 | 0 | ESelection aOldSel = pEditView->GetSelection(); |
1460 | 0 | aOldSel.Adjust(); |
1461 | |
|
1462 | 0 | pEditView->Read( rInput, eFormat, pHTTPHeaderAttrs ); |
1463 | |
|
1464 | 0 | tools::Long nParaDiff = pEditView->getEditEngine().GetParagraphCount() - nOldParaCount; |
1465 | 0 | sal_Int32 nChangesStart = aOldSel.start.nPara; |
1466 | 0 | sal_Int32 nChangesEnd = nChangesStart + nParaDiff + (aOldSel.end.nPara-aOldSel.start.nPara); |
1467 | |
|
1468 | 0 | for ( sal_Int32 n = nChangesStart; n <= nChangesEnd; n++ ) |
1469 | 0 | { |
1470 | 0 | if ( rOwner.GetOutlinerMode() == OutlinerMode::OutlineObject ) |
1471 | 0 | rOwner.ImplSetLevelDependentStyleSheet( n ); |
1472 | 0 | } |
1473 | |
|
1474 | 0 | rOwner.ImpFilterIndents( nChangesStart, nChangesEnd ); |
1475 | 0 | } |
1476 | | |
1477 | | void OutlinerView::SetBackgroundColor( const Color& rColor ) |
1478 | 0 | { |
1479 | 0 | pEditView->SetBackgroundColor( rColor ); |
1480 | 0 | } |
1481 | | |
1482 | | void OutlinerView::RegisterViewShell(OutlinerViewShell* pViewShell) |
1483 | 0 | { |
1484 | 0 | pEditView->RegisterViewShell(pViewShell); |
1485 | 0 | } |
1486 | | |
1487 | | Color const & OutlinerView::GetBackgroundColor() const |
1488 | 0 | { |
1489 | 0 | return pEditView->GetBackgroundColor(); |
1490 | 0 | } |
1491 | | |
1492 | | SfxItemSet OutlinerView::GetAttribs() |
1493 | 0 | { |
1494 | 0 | return pEditView->GetAttribs(); |
1495 | 0 | } |
1496 | | |
1497 | | SvtScriptType OutlinerView::GetSelectedScriptType() const |
1498 | 0 | { |
1499 | 0 | return pEditView->GetSelectedScriptType(); |
1500 | 0 | } |
1501 | | |
1502 | | OUString OutlinerView::GetSurroundingText() const |
1503 | 0 | { |
1504 | 0 | return pEditView->GetSurroundingText(); |
1505 | 0 | } |
1506 | | |
1507 | | Selection OutlinerView::GetSurroundingTextSelection() const |
1508 | 0 | { |
1509 | 0 | return pEditView->GetSurroundingTextSelection(); |
1510 | 0 | } |
1511 | | |
1512 | | bool OutlinerView::DeleteSurroundingText(const Selection& rSelection) |
1513 | 0 | { |
1514 | 0 | return pEditView->DeleteSurroundingText(rSelection); |
1515 | 0 | } |
1516 | | |
1517 | | // ===== some code for thesaurus sub menu within context menu |
1518 | | |
1519 | | namespace { |
1520 | | |
1521 | | bool isSingleScriptType( SvtScriptType nScriptType ) |
1522 | 0 | { |
1523 | 0 | sal_uInt8 nScriptCount = 0; |
1524 | |
|
1525 | 0 | if (nScriptType & SvtScriptType::LATIN) |
1526 | 0 | ++nScriptCount; |
1527 | 0 | if (nScriptType & SvtScriptType::ASIAN) |
1528 | 0 | ++nScriptCount; |
1529 | 0 | if (nScriptType & SvtScriptType::COMPLEX) |
1530 | 0 | ++nScriptCount; |
1531 | |
|
1532 | 0 | return nScriptCount == 1; |
1533 | 0 | } |
1534 | | |
1535 | | } |
1536 | | |
1537 | | // returns: true if a word for thesaurus look-up was found at the current cursor position. |
1538 | | // The status string will be word + iso language string (e.g. "light#en-US") |
1539 | | bool GetStatusValueForThesaurusFromContext( |
1540 | | OUString &rStatusVal, |
1541 | | LanguageType &rLang, |
1542 | | const EditView &rEditView ) |
1543 | 0 | { |
1544 | | // get text and locale for thesaurus look up |
1545 | 0 | OUString aText; |
1546 | 0 | EditEngine& rEditEngine = rEditView.getEditEngine(); |
1547 | 0 | ESelection aTextSel( rEditView.GetSelection() ); |
1548 | 0 | if (!aTextSel.HasRange()) |
1549 | 0 | aTextSel = rEditEngine.GetWord( aTextSel, i18n::WordType::DICTIONARY_WORD ); |
1550 | 0 | aText = rEditEngine.GetText( aTextSel ); |
1551 | 0 | aTextSel.Adjust(); |
1552 | |
|
1553 | 0 | if (!isSingleScriptType(rEditEngine.GetScriptType(aTextSel))) |
1554 | 0 | return false; |
1555 | | |
1556 | 0 | LanguageType nLang = rEditEngine.GetLanguage(aTextSel.start.nPara, aTextSel.start.nIndex).nLang; |
1557 | 0 | OUString aLangText( LanguageTag::convertToBcp47( nLang ) ); |
1558 | | |
1559 | | // set word and locale to look up as status value |
1560 | 0 | rStatusVal = aText + "#" + aLangText; |
1561 | 0 | rLang = nLang; |
1562 | |
|
1563 | 0 | return aText.getLength() > 0; |
1564 | 0 | } |
1565 | | |
1566 | | |
1567 | | void ReplaceTextWithSynonym( EditView &rEditView, const OUString &rSynonmText ) |
1568 | 0 | { |
1569 | | // get selection to use |
1570 | 0 | ESelection aCurSel( rEditView.GetSelection() ); |
1571 | 0 | if (!rEditView.HasSelection()) |
1572 | 0 | { |
1573 | | // select the same word that was used in GetStatusValueForThesaurusFromContext by calling GetWord. |
1574 | | // (In the end both functions will call ImpEditEngine::SelectWord) |
1575 | 0 | rEditView.SelectCurrentWord( i18n::WordType::DICTIONARY_WORD ); |
1576 | 0 | aCurSel = rEditView.GetSelection(); |
1577 | 0 | } |
1578 | | |
1579 | | // replace word ... |
1580 | 0 | rEditView.InsertText( rSynonmText ); |
1581 | 0 | rEditView.ShowCursor( true, false ); |
1582 | 0 | } |
1583 | | |
1584 | | |
1585 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |