Line data Source code
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 <com/sun/star/accessibility/XAccessible.hpp>
21 : #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
22 : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
24 : #include <toolkit/helper/vclunohelper.hxx>
25 :
26 :
27 : #include "starmath.hrc"
28 :
29 : #include <vcl/menu.hxx>
30 : #include <editeng/editview.hxx>
31 : #include <editeng/editeng.hxx>
32 : #include <editeng/editstat.hxx>
33 : #include <editeng/eeitem.hxx>
34 : #include <sfx2/dispatch.hxx>
35 : #include <svl/intitem.hxx>
36 : #include <svl/itempool.hxx>
37 : #include <svl/stritem.hxx>
38 : #include <editeng/fhgtitem.hxx>
39 : #include <editeng/wghtitem.hxx>
40 : #include <editeng/lrspitem.hxx>
41 : #include <svl/itemset.hxx>
42 : #include <editeng/fontitem.hxx>
43 : #include <sfx2/viewfrm.hxx>
44 :
45 : #include "edit.hxx"
46 : #include "view.hxx"
47 : #include "document.hxx"
48 : #include "config.hxx"
49 : #include "accessibility.hxx"
50 :
51 : #define SCROLL_LINE 24
52 :
53 :
54 : using namespace com::sun::star::accessibility;
55 : using namespace com::sun::star;
56 : using namespace com::sun::star::uno;
57 :
58 : ////////////////////////////////////////
59 :
60 :
61 17 : void SmGetLeftSelectionPart(const ESelection &rSel,
62 : sal_Int32 &nPara, sal_uInt16 &nPos)
63 : // returns paragraph number and position of the selections left part
64 : {
65 : // compare start and end of selection and use the one that comes first
66 17 : if ( rSel.nStartPara < rSel.nEndPara
67 17 : || (rSel.nStartPara == rSel.nEndPara && rSel.nStartPos < rSel.nEndPos) )
68 0 : { nPara = rSel.nStartPara;
69 0 : nPos = rSel.nStartPos;
70 : }
71 : else
72 17 : { nPara = rSel.nEndPara;
73 17 : nPos = rSel.nEndPos;
74 : }
75 17 : }
76 :
77 69 : bool SmEditWindow::IsInlineEditEnabled()
78 : {
79 69 : SmViewShell *pView = GetView();
80 69 : return pView ? pView->IsInlineEditEnabled() : false;
81 : }
82 :
83 : ////////////////////////////////////////
84 :
85 25 : SmEditWindow::SmEditWindow( SmCmdBoxWindow &rMyCmdBoxWin ) :
86 : Window (&rMyCmdBoxWin),
87 : DropTargetHelper ( this ),
88 : pAccessible (0),
89 : rCmdBox (rMyCmdBoxWin),
90 : pEditView (0),
91 : pHScrollBar (0),
92 : pVScrollBar (0),
93 25 : pScrollBox (0)
94 : {
95 25 : SetHelpId(HID_SMA_COMMAND_WIN_EDIT);
96 25 : SetMapMode(MAP_PIXEL);
97 :
98 : // Even RTL languages don't use RTL for math
99 25 : rCmdBox.GetEditWindow()->EnableRTL( false );
100 :
101 25 : ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
102 :
103 : // compare DataChanged
104 25 : SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
105 :
106 25 : aModifyTimer.SetTimeoutHdl(LINK(this, SmEditWindow, ModifyTimerHdl));
107 25 : aModifyTimer.SetTimeout(500);
108 :
109 25 : if (!IsInlineEditEnabled())
110 : {
111 25 : aCursorMoveTimer.SetTimeoutHdl(LINK(this, SmEditWindow, CursorMoveTimerHdl));
112 25 : aCursorMoveTimer.SetTimeout(500);
113 : }
114 :
115 : // if not called explicitly the this edit window within the
116 : // command window will just show an empty gray panel.
117 25 : Show();
118 25 : }
119 :
120 :
121 54 : SmEditWindow::~SmEditWindow()
122 : {
123 25 : aModifyTimer.Stop();
124 :
125 25 : StartCursorMove();
126 :
127 : // clean up of classes used for accessibility
128 : // must be done before EditView (and thus EditEngine) is no longer
129 : // available for those classes.
130 25 : if (pAccessible)
131 2 : pAccessible->ClearWin(); // make Accessible defunctional
132 : // Note: memory for pAccessible will be freed when the reference
133 : // xAccessible is released.
134 :
135 25 : if (pEditView)
136 : {
137 25 : EditEngine *pEditEngine = pEditView->GetEditEngine();
138 25 : if (pEditEngine)
139 : {
140 25 : pEditEngine->SetStatusEventHdl( Link() );
141 25 : pEditEngine->RemoveView( pEditView );
142 : }
143 : }
144 25 : delete pEditView;
145 25 : delete pHScrollBar;
146 25 : delete pVScrollBar;
147 25 : delete pScrollBox;
148 29 : }
149 :
150 28 : void SmEditWindow::StartCursorMove()
151 : {
152 28 : if (!IsInlineEditEnabled())
153 28 : aCursorMoveTimer.Stop();
154 28 : }
155 :
156 0 : void SmEditWindow::InvalidateSlots()
157 : {
158 0 : SfxBindings& rBind = GetView()->GetViewFrame()->GetBindings();
159 0 : rBind.Invalidate(SID_COPY);
160 0 : rBind.Invalidate(SID_CUT);
161 0 : rBind.Invalidate(SID_DELETE);
162 0 : }
163 :
164 89 : SmViewShell * SmEditWindow::GetView()
165 : {
166 89 : return rCmdBox.GetView();
167 : }
168 :
169 :
170 28 : SmDocShell * SmEditWindow::GetDoc()
171 : {
172 28 : SmViewShell *pView = rCmdBox.GetView();
173 28 : return pView ? pView->GetDoc() : 0;
174 : }
175 :
176 :
177 211 : EditEngine * SmEditWindow::GetEditEngine()
178 : {
179 211 : EditEngine *pEditEng = 0;
180 211 : if (pEditView)
181 186 : pEditEng = pEditView->GetEditEngine();
182 : else
183 : {
184 25 : SmDocShell *pDoc = GetDoc();
185 25 : if (pDoc)
186 25 : pEditEng = &pDoc->GetEditEngine();
187 : }
188 211 : return pEditEng;
189 : }
190 :
191 :
192 0 : SfxItemPool * SmEditWindow::GetEditEngineItemPool()
193 : {
194 0 : SmDocShell *pDoc = GetDoc();
195 0 : return pDoc ? &pDoc->GetEditEngineItemPool() : 0;
196 : }
197 :
198 25 : void SmEditWindow::ApplyColorConfigValues( const svtools::ColorConfig &rColorCfg )
199 : {
200 : // Note: SetBackground still done in SmEditWindow::DataChanged
201 : #if OSL_DEBUG_LEVEL > 1
202 : // ColorData nVal = rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor;
203 : #endif
204 25 : SetTextColor( rColorCfg.GetColorValue(svtools::FONTCOLOR).nColor );
205 25 : Invalidate();
206 25 : }
207 :
208 0 : void SmEditWindow::DataChanged( const DataChangedEvent& )
209 : {
210 0 : const StyleSettings aSettings( GetSettings().GetStyleSettings() );
211 :
212 0 : ApplyColorConfigValues( SM_MOD()->GetColorConfig() );
213 0 : SetBackground( aSettings.GetWindowColor() );
214 :
215 : // edit fields in other Applications use this font instead of
216 : // the application font thus we use this one too
217 0 : SetPointFont( aSettings.GetFieldFont() /*aSettings.GetAppFont()*/ );
218 :
219 0 : EditEngine *pEditEngine = GetEditEngine();
220 0 : SfxItemPool *pEditEngineItemPool = GetEditEngineItemPool();
221 :
222 0 : if (pEditEngine && pEditEngineItemPool)
223 : {
224 : //!
225 : //! see also SmDocShell::GetEditEngine() !
226 : //!
227 :
228 0 : pEditEngine->SetDefTab(sal_uInt16(GetTextWidth(OUString("XXXX"))));
229 :
230 0 : SetEditEngineDefaultFonts(*pEditEngineItemPool);
231 :
232 : // forces new settings to be used
233 : // unfortunately this resets the whole edit engine
234 : // thus we need to save at least the text
235 0 : OUString aTxt( pEditEngine->GetText( LINEEND_LF ) );
236 0 : pEditEngine->Clear(); //incorrect font size
237 0 : pEditEngine->SetText( aTxt );
238 : }
239 :
240 0 : AdjustScrollBars();
241 0 : Resize();
242 0 : }
243 :
244 4 : IMPL_LINK( SmEditWindow, ModifyTimerHdl, Timer *, EMPTYARG /*pTimer*/ )
245 : {
246 2 : UpdateStatus();
247 2 : aModifyTimer.Stop();
248 2 : return 0;
249 : }
250 :
251 0 : IMPL_LINK(SmEditWindow, CursorMoveTimerHdl, Timer *, EMPTYARG /*pTimer*/)
252 : // every once in a while check cursor position (selection) of edit
253 : // window and if it has changed (try to) set the formula-cursor
254 : // according to that.
255 : {
256 0 : if (IsInlineEditEnabled())
257 0 : return 0;
258 :
259 0 : ESelection aNewSelection(GetSelection());
260 :
261 0 : if (!aNewSelection.IsEqual(aOldSelection))
262 : {
263 0 : SmViewShell *pView = rCmdBox.GetView();
264 0 : if (pView)
265 : {
266 : // get row and column to look for
267 : sal_Int32 nRow;
268 : sal_uInt16 nCol;
269 0 : SmGetLeftSelectionPart(aNewSelection, nRow, nCol);
270 0 : nRow++;
271 0 : nCol++;
272 0 : pView->GetGraphicWindow().SetCursorPos(static_cast<sal_uInt16>(nRow), nCol);
273 0 : aOldSelection = aNewSelection;
274 : }
275 : }
276 0 : aCursorMoveTimer.Stop();
277 :
278 0 : return 0;
279 : }
280 :
281 48 : void SmEditWindow::Resize()
282 : {
283 48 : if (!pEditView)
284 25 : CreateEditView();
285 :
286 48 : if (pEditView)
287 : {
288 48 : pEditView->SetOutputArea(AdjustScrollBars());
289 48 : pEditView->ShowCursor();
290 :
291 : OSL_ENSURE( pEditView->GetEditEngine(), "EditEngine missing" );
292 96 : const long nMaxVisAreaStart = pEditView->GetEditEngine()->GetTextHeight() -
293 96 : pEditView->GetOutputArea().GetHeight();
294 48 : if (pEditView->GetVisArea().Top() > nMaxVisAreaStart)
295 : {
296 19 : Rectangle aVisArea(pEditView->GetVisArea() );
297 19 : aVisArea.Top() = (nMaxVisAreaStart > 0 ) ? nMaxVisAreaStart : 0;
298 19 : aVisArea.SetSize(pEditView->GetOutputArea().GetSize());
299 19 : pEditView->SetVisArea(aVisArea);
300 19 : pEditView->ShowCursor();
301 : }
302 48 : InitScrollBars();
303 : }
304 48 : Invalidate();
305 48 : }
306 :
307 0 : void SmEditWindow::MouseButtonUp(const MouseEvent &rEvt)
308 : {
309 0 : if (pEditView)
310 0 : pEditView->MouseButtonUp(rEvt);
311 : else
312 0 : Window::MouseButtonUp (rEvt);
313 :
314 0 : if (!IsInlineEditEnabled())
315 0 : CursorMoveTimerHdl(&aCursorMoveTimer);
316 0 : InvalidateSlots();
317 0 : }
318 :
319 0 : void SmEditWindow::MouseButtonDown(const MouseEvent &rEvt)
320 : {
321 0 : if (pEditView)
322 0 : pEditView->MouseButtonDown(rEvt);
323 : else
324 0 : Window::MouseButtonDown (rEvt);
325 :
326 0 : GrabFocus();
327 0 : }
328 :
329 0 : void SmEditWindow::Command(const CommandEvent& rCEvt)
330 : {
331 0 : bool bForwardEvt = true;
332 0 : if (rCEvt.GetCommand() == COMMAND_CONTEXTMENU)
333 : {
334 0 : GetParent()->ToTop();
335 :
336 0 : Point aPoint = rCEvt.GetMousePosPixel();
337 0 : PopupMenu* pPopupMenu = new PopupMenu(SmResId(RID_COMMANDMENU));
338 :
339 : // added for replaceability of context menus
340 0 : Menu* pMenu = NULL;
341 0 : ::com::sun::star::ui::ContextMenuExecuteEvent aEvent;
342 0 : aEvent.SourceWindow = VCLUnoHelper::GetInterface( this );
343 0 : aEvent.ExecutePosition.X = aPoint.X();
344 0 : aEvent.ExecutePosition.Y = aPoint.Y();
345 0 : OUString sDummy;
346 0 : if ( GetView()->TryContextMenuInterception( *pPopupMenu, sDummy, pMenu, aEvent ) )
347 : {
348 0 : if ( pMenu )
349 : {
350 0 : delete pPopupMenu;
351 0 : pPopupMenu = (PopupMenu*) pMenu;
352 : }
353 : }
354 :
355 0 : pPopupMenu->SetSelectHdl(LINK(this, SmEditWindow, MenuSelectHdl));
356 :
357 0 : pPopupMenu->Execute( this, aPoint );
358 0 : delete pPopupMenu;
359 0 : bForwardEvt = false;
360 : }
361 0 : else if (rCEvt.GetCommand() == COMMAND_WHEEL)
362 0 : bForwardEvt = !HandleWheelCommands( rCEvt );
363 :
364 0 : if (bForwardEvt)
365 : {
366 0 : if (pEditView)
367 0 : pEditView->Command( rCEvt );
368 : else
369 0 : Window::Command (rCEvt);
370 : }
371 0 : }
372 :
373 :
374 0 : bool SmEditWindow::HandleWheelCommands( const CommandEvent &rCEvt )
375 : {
376 0 : bool bCommandHandled = false; // true if the CommandEvent needs not
377 : // to be passed on (because it has fully
378 : // been taken care of).
379 :
380 0 : const CommandWheelData* pWData = rCEvt.GetWheelData();
381 0 : if (pWData)
382 : {
383 0 : if (COMMAND_WHEEL_ZOOM == pWData->GetMode())
384 0 : bCommandHandled = true; // no zooming in Command window
385 : else
386 0 : bCommandHandled = HandleScrollCommand( rCEvt, pHScrollBar, pVScrollBar);
387 : }
388 :
389 0 : return bCommandHandled;
390 : }
391 :
392 :
393 0 : IMPL_LINK_INLINE_START( SmEditWindow, MenuSelectHdl, Menu *, pMenu )
394 : {
395 0 : SmViewShell *pViewSh = rCmdBox.GetView();
396 0 : if (pViewSh)
397 : pViewSh->GetViewFrame()->GetDispatcher()->Execute(
398 : SID_INSERTCOMMAND, SFX_CALLMODE_STANDARD,
399 0 : new SfxInt16Item(SID_INSERTCOMMAND, pMenu->GetCurItemId()), 0L);
400 0 : return 0;
401 : }
402 0 : IMPL_LINK_INLINE_END( SmEditWindow, MenuSelectHdl, Menu *, pMenu )
403 :
404 0 : void SmEditWindow::KeyInput(const KeyEvent& rKEvt)
405 : {
406 0 : if (rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE)
407 : {
408 0 : bool bCallBase = true;
409 0 : SfxViewShell* pViewShell = GetView();
410 0 : if ( pViewShell && pViewShell->ISA(SmViewShell) )
411 : {
412 : // Terminate possible InPlace mode
413 0 : bCallBase = !pViewShell->Escape();
414 : }
415 0 : if ( bCallBase )
416 0 : Window::KeyInput( rKEvt );
417 : }
418 : else
419 : {
420 0 : StartCursorMove();
421 :
422 0 : if (!pEditView)
423 0 : CreateEditView();
424 0 : if ( !pEditView->PostKeyEvent(rKEvt) )
425 : {
426 0 : SmViewShell *pView = GetView();
427 0 : if ( pView && !pView->KeyInput(rKEvt) )
428 : {
429 : // F1 (help) leads to the destruction of this
430 0 : Flush();
431 0 : if ( aModifyTimer.IsActive() )
432 0 : aModifyTimer.Stop();
433 0 : Window::KeyInput(rKEvt);
434 : }
435 : else
436 : {
437 : // SFX has maybe called a slot of the view and thus (because of a hack in SFX)
438 : // set the focus to the view
439 0 : SfxViewShell* pVShell = GetView();
440 0 : if ( pVShell && pVShell->ISA(SmViewShell) &&
441 0 : ((SmViewShell*)pVShell)->GetGraphicWindow().HasFocus() )
442 : {
443 0 : GrabFocus();
444 : }
445 : }
446 : }
447 : else
448 : {
449 : // have doc-shell modified only for formula input/change and not
450 : // cursor travelling and such things...
451 0 : SmDocShell *pDocShell = GetDoc();
452 0 : if (pDocShell)
453 0 : pDocShell->SetModified( GetEditEngine()->IsModified() );
454 :
455 0 : aModifyTimer.Start();
456 : }
457 :
458 : // get the current char of the key event
459 0 : sal_Unicode charCode = rKEvt.GetCharCode();
460 0 : OUString close;
461 :
462 0 : if (charCode == '{')
463 0 : close = " }";
464 0 : else if (charCode == '[')
465 0 : close = " ]";
466 0 : else if (charCode == '(')
467 0 : close = " )";
468 :
469 : // auto close the current character
470 0 : if (!close.isEmpty())
471 : {
472 0 : pEditView->InsertText(close);
473 : // position it at center of brackets
474 0 : ESelection aSelection = pEditView->GetSelection();
475 0 : aSelection.nStartPos = aSelection.nEndPos = aSelection.nEndPos - 2;
476 0 : pEditView->SetSelection(aSelection);
477 : }
478 :
479 0 : InvalidateSlots();
480 : }
481 0 : }
482 :
483 23 : void SmEditWindow::Paint(const Rectangle& rRect)
484 : {
485 23 : if (!pEditView)
486 0 : CreateEditView();
487 23 : pEditView->Paint(rRect);
488 23 : }
489 :
490 25 : void SmEditWindow::CreateEditView()
491 : {
492 25 : EditEngine *pEditEngine = GetEditEngine();
493 :
494 : //! pEditEngine and pEditView may be 0.
495 : //! For example when the program is used by the document-converter
496 25 : if (!pEditView && pEditEngine)
497 : {
498 25 : pEditView = new EditView( pEditEngine, this );
499 25 : pEditEngine->InsertView( pEditView );
500 :
501 25 : if (!pVScrollBar)
502 25 : pVScrollBar = new ScrollBar(this, WinBits(WB_VSCROLL));
503 25 : if (!pHScrollBar)
504 25 : pHScrollBar = new ScrollBar(this, WinBits(WB_HSCROLL));
505 25 : if (!pScrollBox)
506 25 : pScrollBox = new ScrollBarBox(this);
507 25 : pVScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
508 25 : pHScrollBar->SetScrollHdl(LINK(this, SmEditWindow, ScrollHdl));
509 25 : pVScrollBar->EnableDrag( true );
510 25 : pHScrollBar->EnableDrag( true );
511 :
512 25 : pEditView->SetOutputArea(AdjustScrollBars());
513 :
514 25 : ESelection eSelection;
515 :
516 25 : pEditView->SetSelection(eSelection);
517 25 : Update();
518 25 : pEditView->ShowCursor(true, true);
519 :
520 25 : pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
521 25 : SetPointer(pEditView->GetPointer());
522 :
523 25 : SetScrollBarRanges();
524 : }
525 25 : }
526 :
527 :
528 12 : IMPL_LINK( SmEditWindow, EditStatusHdl, EditStatus *, EMPTYARG /*pStat*/ )
529 : {
530 6 : if (!pEditView)
531 0 : return 1;
532 : else
533 : {
534 6 : Resize();
535 6 : return 0;
536 : }
537 : }
538 :
539 0 : IMPL_LINK_INLINE_START( SmEditWindow, ScrollHdl, ScrollBar *, EMPTYARG /*pScrollBar*/ )
540 : {
541 : OSL_ENSURE(pEditView, "EditView missing");
542 0 : if (pEditView)
543 : {
544 : pEditView->SetVisArea(Rectangle(Point(pHScrollBar->GetThumbPos(),
545 : pVScrollBar->GetThumbPos()),
546 0 : pEditView->GetVisArea().GetSize()));
547 0 : pEditView->Invalidate();
548 : }
549 0 : return 0;
550 : }
551 0 : IMPL_LINK_INLINE_END( SmEditWindow, ScrollHdl, ScrollBar *, pScrollBar )
552 :
553 73 : Rectangle SmEditWindow::AdjustScrollBars()
554 : {
555 73 : const Size aOut( GetOutputSizePixel() );
556 73 : Point aPoint;
557 73 : Rectangle aRect( aPoint, aOut );
558 :
559 73 : if (pVScrollBar && pHScrollBar && pScrollBox)
560 : {
561 73 : const long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
562 73 : Point aPt( aRect.TopRight() ); aPt.X() -= nTmp -1L;
563 73 : pVScrollBar->SetPosSizePixel( aPt, Size(nTmp, aOut.Height() - nTmp));
564 :
565 73 : aPt = aRect.BottomLeft(); aPt.Y() -= nTmp - 1L;
566 73 : pHScrollBar->SetPosSizePixel( aPt, Size(aOut.Width() - nTmp, nTmp));
567 :
568 73 : aPt.X() = pHScrollBar->GetSizePixel().Width();
569 73 : aPt.Y() = pVScrollBar->GetSizePixel().Height();
570 73 : pScrollBox->SetPosSizePixel(aPt, Size(nTmp, nTmp ));
571 :
572 73 : aRect.Right() = aPt.X() - 2;
573 73 : aRect.Bottom() = aPt.Y() - 2;
574 : }
575 73 : return aRect;
576 : }
577 :
578 73 : void SmEditWindow::SetScrollBarRanges()
579 : {
580 : // Extra method, not InitScrollBars, since it's also being used for EditEngine events
581 73 : EditEngine *pEditEngine = GetEditEngine();
582 73 : if (pVScrollBar && pHScrollBar && pEditEngine && pEditView)
583 : {
584 73 : long nTmp = pEditEngine->GetTextHeight();
585 73 : pVScrollBar->SetRange(Range(0, nTmp));
586 73 : pVScrollBar->SetThumbPos(pEditView->GetVisArea().Top());
587 :
588 73 : nTmp = pEditEngine->GetPaperSize().Width();
589 73 : pHScrollBar->SetRange(Range(0,nTmp));
590 73 : pHScrollBar->SetThumbPos(pEditView->GetVisArea().Left());
591 : }
592 73 : }
593 :
594 48 : void SmEditWindow::InitScrollBars()
595 : {
596 48 : if (pVScrollBar && pHScrollBar && pScrollBox && pEditView)
597 : {
598 48 : const Size aOut( pEditView->GetOutputArea().GetSize() );
599 48 : pVScrollBar->SetVisibleSize(aOut.Height());
600 48 : pVScrollBar->SetPageSize(aOut.Height() * 8 / 10);
601 48 : pVScrollBar->SetLineSize(aOut.Height() * 2 / 10);
602 :
603 48 : pHScrollBar->SetVisibleSize(aOut.Width());
604 48 : pHScrollBar->SetPageSize(aOut.Width() * 8 / 10);
605 48 : pHScrollBar->SetLineSize(SCROLL_LINE );
606 :
607 48 : SetScrollBarRanges();
608 :
609 48 : pVScrollBar->Show();
610 48 : pHScrollBar->Show();
611 48 : pScrollBox->Show();
612 : }
613 48 : }
614 :
615 :
616 9 : OUString SmEditWindow::GetText() const
617 : {
618 9 : String aText;
619 9 : EditEngine *pEditEngine = const_cast< SmEditWindow* >(this)->GetEditEngine();
620 : OSL_ENSURE( pEditEngine, "EditEngine missing" );
621 9 : if (pEditEngine)
622 9 : aText = pEditEngine->GetText( LINEEND_LF );
623 9 : return aText;
624 : }
625 :
626 :
627 4 : void SmEditWindow::SetText(const OUString& rText)
628 : {
629 4 : EditEngine *pEditEngine = GetEditEngine();
630 : OSL_ENSURE( pEditEngine, "EditEngine missing" );
631 4 : if (pEditEngine && !pEditEngine->IsModified())
632 : {
633 4 : if (!pEditView)
634 0 : CreateEditView();
635 :
636 4 : ESelection eSelection = pEditView->GetSelection();
637 :
638 4 : pEditEngine->SetText(rText);
639 4 : pEditEngine->ClearModifyFlag();
640 :
641 : // Restarting the timer here, prevents calling the handlers for other (currently inactive)
642 : // math tasks
643 4 : aModifyTimer.Start();
644 :
645 4 : pEditView->SetSelection(eSelection);
646 : }
647 4 : }
648 :
649 :
650 16 : void SmEditWindow::GetFocus()
651 : {
652 16 : Window::GetFocus();
653 :
654 16 : if (xAccessible.is())
655 : {
656 : // Note: will implicitly send the AccessibleStateType::FOCUSED event
657 0 : ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper();
658 0 : if (pHelper)
659 0 : pHelper->SetFocus(true);
660 : }
661 :
662 16 : if (!pEditView)
663 0 : CreateEditView();
664 16 : EditEngine *pEditEngine = GetEditEngine();
665 16 : if (pEditEngine)
666 16 : pEditEngine->SetStatusEventHdl( LINK(this, SmEditWindow, EditStatusHdl) );
667 :
668 : //Let SmViewShell know we got focus
669 16 : if(GetView() && IsInlineEditEnabled())
670 0 : GetView()->SetInsertIntoEditWindow(true);
671 16 : }
672 :
673 :
674 1 : void SmEditWindow::LoseFocus()
675 : {
676 1 : EditEngine *pEditEngine = GetEditEngine();
677 1 : if (pEditEngine)
678 1 : pEditEngine->SetStatusEventHdl( Link() );
679 :
680 1 : Window::LoseFocus();
681 :
682 1 : if (xAccessible.is())
683 : {
684 : // Note: will implicitly send the AccessibleStateType::FOCUSED event
685 0 : ::accessibility::AccessibleTextHelper *pHelper = pAccessible->GetTextHelper();
686 0 : if (pHelper)
687 0 : pHelper->SetFocus(false);
688 : }
689 1 : }
690 :
691 :
692 0 : bool SmEditWindow::IsAllSelected() const
693 : {
694 0 : bool bRes = false;
695 0 : EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine();
696 : OSL_ENSURE( pEditView, "NULL pointer" );
697 : OSL_ENSURE( pEditEngine, "NULL pointer" );
698 0 : if (pEditEngine && pEditView)
699 : {
700 0 : ESelection eSelection( pEditView->GetSelection() );
701 0 : sal_Int32 nParaCnt = pEditEngine->GetParagraphCount();
702 0 : if (!(nParaCnt - 1))
703 : {
704 0 : sal_Int32 nTextLen = pEditEngine->GetText( LINEEND_LF ).getLength();
705 0 : bRes = !eSelection.nStartPos && (eSelection.nEndPos == nTextLen - 1);
706 : }
707 : else
708 : {
709 0 : bRes = !eSelection.nStartPara && (eSelection.nEndPara == nParaCnt - 1);
710 : }
711 : }
712 0 : return bRes;
713 : }
714 :
715 0 : void SmEditWindow::SelectAll()
716 : {
717 : OSL_ENSURE( pEditView, "NULL pointer" );
718 0 : if (pEditView)
719 : {
720 : // ALL as last two parameters refers to the end of the text
721 0 : pEditView->SetSelection( ESelection( 0, 0, EE_PARA_ALL, EE_TEXTPOS_ALL ) );
722 : }
723 0 : }
724 :
725 0 : void SmEditWindow::InsertCommand(sal_uInt16 nCommand)
726 : {
727 : OSL_ENSURE( pEditView, "EditView missing" );
728 0 : if (pEditView)
729 : {
730 0 : ESelection aSelection = pEditView->GetSelection();
731 :
732 : OSL_ENSURE( pEditView, "NULL pointer" );
733 0 : OUString aText = SM_RESSTR(nCommand);
734 :
735 0 : OUString aCurrentFormula = pEditView->GetEditEngine()->GetText();
736 0 : sal_Int32 nStartIndex = 0;
737 0 : sal_Int32 nEndIndex = 0;
738 :
739 : // get the start position (when we get a multi line formula)
740 0 : for (sal_Int32 nParaPos = 0; nParaPos < aSelection.nStartPara; nParaPos++)
741 0 : nStartIndex = aCurrentFormula.indexOf("\n", nStartIndex) + 1;
742 :
743 0 : nStartIndex += aSelection.nStartPos;
744 :
745 : // get the end position (when we get a multi line formula)
746 0 : for (sal_Int32 nParaPos = 0; nParaPos < aSelection.nEndPara; nParaPos++)
747 0 : nEndIndex = aCurrentFormula.indexOf("\n", nEndIndex) + 1;
748 :
749 0 : nEndIndex += aSelection.nEndPos;
750 :
751 : // remove right space of current symbol if there already one
752 0 : if (nEndIndex < aCurrentFormula.getLength() &&
753 0 : aCurrentFormula[nEndIndex] == ' ')
754 0 : aText = aText.trim();
755 :
756 : // put an space before put a new command when necessary(if we're not in the begin of a line)
757 0 : if (aSelection.nStartPos > 0 && aCurrentFormula[nStartIndex - 1] != ' ')
758 0 : aText = " " + aText;
759 :
760 0 : pEditView->InsertText(aText);
761 :
762 : // Remember start of the selection and move the cursor there afterwards.
763 0 : aSelection.nEndPara = aSelection.nStartPara;
764 0 : if (HasMark(aText))
765 : {
766 0 : aSelection.nEndPos = aSelection.nStartPos;
767 0 : pEditView->SetSelection(aSelection);
768 0 : SelNextMark();
769 : }
770 : else
771 : { // set selection after inserted text
772 0 : aSelection.nEndPos = aSelection.nStartPos + aText.getLength();
773 0 : aSelection.nStartPos = aSelection.nEndPos;
774 0 : pEditView->SetSelection(aSelection);
775 : }
776 :
777 0 : aModifyTimer.Start();
778 0 : StartCursorMove();
779 0 : GrabFocus();
780 : }
781 0 : }
782 :
783 0 : void SmEditWindow::MarkError(const Point &rPos)
784 : {
785 : OSL_ENSURE( pEditView, "EditView missing" );
786 0 : if (pEditView)
787 : {
788 0 : const xub_StrLen nCol = sal::static_int_cast< xub_StrLen >(rPos.X());
789 0 : const sal_uInt16 nRow = sal::static_int_cast< sal_uInt16 >(rPos.Y() - 1);
790 :
791 0 : pEditView->SetSelection(ESelection(nRow, nCol - 1, nRow, nCol));
792 0 : GrabFocus();
793 : }
794 0 : }
795 :
796 : // Makes selection to next <?> symbol
797 3 : void SmEditWindow::SelNextMark()
798 : {
799 3 : EditEngine *pEditEngine = GetEditEngine();
800 : OSL_ENSURE( pEditView, "NULL pointer" );
801 : OSL_ENSURE( pEditEngine, "NULL pointer" );
802 3 : if (pEditEngine && pEditView)
803 : {
804 3 : ESelection eSelection = pEditView->GetSelection();
805 3 : sal_Int32 nPos = eSelection.nEndPos;
806 3 : sal_Int32 nCounts = pEditEngine->GetParagraphCount();
807 :
808 6 : while (eSelection.nEndPara < nCounts)
809 : {
810 3 : OUString aText = pEditEngine->GetText(eSelection.nEndPara);
811 3 : nPos = aText.indexOf("<?>", nPos);
812 3 : if (nPos != -1)
813 : {
814 : pEditView->SetSelection(ESelection(
815 3 : eSelection.nEndPara, nPos, eSelection.nEndPara, nPos + 3));
816 3 : break;
817 : }
818 :
819 0 : nPos = 0;
820 0 : eSelection.nEndPara++;
821 0 : }
822 : }
823 3 : }
824 :
825 1 : void SmEditWindow::SelPrevMark()
826 : {
827 1 : EditEngine *pEditEngine = GetEditEngine();
828 : OSL_ENSURE( pEditEngine, "NULL pointer" );
829 : OSL_ENSURE( pEditView, "NULL pointer" );
830 1 : if (pEditEngine && pEditView)
831 : {
832 1 : ESelection eSelection = pEditView->GetSelection();
833 1 : sal_Int32 nPos = -1;
834 1 : sal_Int32 nMax = eSelection.nStartPos;
835 1 : OUString aText(pEditEngine->GetText(eSelection.nStartPara));
836 2 : OUString aMark("<?>");
837 1 : sal_Int32 nCounts = pEditEngine->GetParagraphCount();
838 :
839 1 : do
840 : {
841 1 : sal_Int32 nMarkIndex = aText.indexOf(aMark);
842 3 : while ((nMarkIndex < nMax) && (nMarkIndex != -1))
843 : {
844 1 : nPos = nMarkIndex;
845 1 : nMarkIndex = aText.indexOf(aMark, nMarkIndex + 1);
846 : }
847 :
848 1 : if (nPos == -1)
849 : {
850 0 : eSelection.nStartPara--;
851 0 : aText = pEditEngine->GetText(eSelection.nStartPara);
852 0 : nMax = aText.getLength();
853 : }
854 : }
855 2 : while ((eSelection.nStartPara < nCounts) &&
856 : (nPos == -1));
857 :
858 1 : if (nPos != -1)
859 : {
860 : pEditView->SetSelection(ESelection(
861 1 : eSelection.nStartPara, nPos, eSelection.nStartPara, nPos + 3));
862 1 : }
863 : }
864 1 : }
865 :
866 0 : bool SmEditWindow::HasMark(const OUString& rText) const
867 : // returns true iff 'rText' contains a mark
868 : {
869 0 : return rText.indexOf("<?>") != -1;
870 : }
871 :
872 0 : void SmEditWindow::MouseMove(const MouseEvent &rEvt)
873 : {
874 0 : if (pEditView)
875 0 : pEditView->MouseMove(rEvt);
876 0 : }
877 :
878 0 : sal_Int8 SmEditWindow::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
879 : {
880 0 : return pEditView ? /*pEditView->QueryDrop( rEvt )*/DND_ACTION_NONE: DND_ACTION_NONE;
881 : }
882 :
883 0 : sal_Int8 SmEditWindow::ExecuteDrop( const ExecuteDropEvent& /*rEvt*/ )
884 : {
885 0 : return pEditView ? /*pEditView->Drop( rEvt )*/DND_ACTION_NONE : DND_ACTION_NONE;
886 : }
887 :
888 17 : ESelection SmEditWindow::GetSelection() const
889 : {
890 : // pointer may be 0 when reloading a document and the old view
891 : // was already destroyed
892 : //(OSL_ENSURE( pEditView, "NULL pointer" );
893 17 : ESelection eSel;
894 17 : if (pEditView)
895 17 : eSel = pEditView->GetSelection();
896 17 : return eSel;
897 : }
898 :
899 0 : void SmEditWindow::SetSelection(const ESelection &rSel)
900 : {
901 : OSL_ENSURE( pEditView, "NULL pointer" );
902 0 : if (pEditView)
903 0 : pEditView->SetSelection(rSel);
904 0 : InvalidateSlots();
905 0 : }
906 :
907 13 : bool SmEditWindow::IsEmpty() const
908 : {
909 13 : EditEngine *pEditEngine = ((SmEditWindow *) this)->GetEditEngine();
910 13 : bool bEmpty = ( pEditEngine ? pEditEngine->GetTextLen() == 0 : false);
911 13 : return bEmpty;
912 : }
913 :
914 26 : bool SmEditWindow::IsSelected() const
915 : {
916 26 : return pEditView ? pEditView->HasSelection() : false;
917 : }
918 :
919 :
920 5 : void SmEditWindow::UpdateStatus( bool bSetDocModified )
921 : {
922 5 : SmModule *pMod = SM_MOD();
923 5 : if (pMod && pMod->GetConfig()->IsAutoRedraw())
924 5 : Flush();
925 5 : if ( bSetDocModified )
926 3 : GetDoc()->SetModified(true);
927 5 : }
928 :
929 0 : void SmEditWindow::Cut()
930 : {
931 : OSL_ENSURE( pEditView, "EditView missing" );
932 0 : if (pEditView)
933 : {
934 0 : pEditView->Cut();
935 0 : UpdateStatus(true);
936 : }
937 0 : }
938 :
939 0 : void SmEditWindow::Copy()
940 : {
941 : OSL_ENSURE( pEditView, "EditView missing" );
942 0 : if (pEditView)
943 0 : pEditView->Copy();
944 0 : }
945 :
946 0 : void SmEditWindow::Paste()
947 : {
948 : OSL_ENSURE( pEditView, "EditView missing" );
949 0 : if (pEditView)
950 : {
951 0 : pEditView->Paste();
952 0 : UpdateStatus(true);
953 : }
954 0 : }
955 :
956 3 : void SmEditWindow::Delete()
957 : {
958 : OSL_ENSURE( pEditView, "EditView missing" );
959 3 : if (pEditView)
960 : {
961 3 : pEditView->DeleteSelected();
962 3 : UpdateStatus(true);
963 : }
964 3 : }
965 :
966 3 : void SmEditWindow::InsertText(const OUString& rText)
967 : {
968 : OSL_ENSURE( pEditView, "EditView missing" );
969 3 : if (pEditView)
970 : {
971 3 : pEditView->InsertText(rText);
972 3 : aModifyTimer.Start();
973 3 : StartCursorMove();
974 : }
975 3 : }
976 :
977 8 : void SmEditWindow::Flush()
978 : {
979 8 : EditEngine *pEditEngine = GetEditEngine();
980 8 : if (pEditEngine && pEditEngine->IsModified())
981 : {
982 4 : pEditEngine->ClearModifyFlag();
983 4 : SmViewShell *pViewSh = rCmdBox.GetView();
984 4 : if (pViewSh)
985 : {
986 : pViewSh->GetViewFrame()->GetDispatcher()->Execute(
987 : SID_TEXT, SFX_CALLMODE_STANDARD,
988 4 : new SfxStringItem(SID_TEXT, GetText()), 0L);
989 : }
990 : }
991 8 : if (aCursorMoveTimer.IsActive())
992 : {
993 0 : aCursorMoveTimer.Stop();
994 0 : CursorMoveTimerHdl(&aCursorMoveTimer);
995 : }
996 8 : }
997 :
998 :
999 0 : void SmEditWindow::DeleteEditView( SmViewShell & /*rView*/ )
1000 : {
1001 0 : if (pEditView)
1002 : {
1003 0 : EditEngine *pEditEngine = pEditView->GetEditEngine();
1004 0 : if (pEditEngine)
1005 : {
1006 0 : pEditEngine->SetStatusEventHdl( Link() );
1007 0 : pEditEngine->RemoveView( pEditView );
1008 : }
1009 0 : delete pEditView;
1010 0 : pEditView = 0;
1011 : }
1012 0 : }
1013 :
1014 :
1015 2 : uno::Reference< XAccessible > SmEditWindow::CreateAccessible()
1016 : {
1017 2 : if (!pAccessible)
1018 : {
1019 2 : pAccessible = new SmEditAccessible( this );
1020 2 : xAccessible = pAccessible;
1021 2 : pAccessible->Init();
1022 : }
1023 2 : return xAccessible;
1024 21 : }
1025 :
1026 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|