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