1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26
27
28 #include <memory>
29
30 #include "unoiface.hxx"
31
32 #include <tools/rc.h>
33
34 #include <vcl/decoview.hxx>
35 #include <vcl/svapp.hxx>
36
37 #include <svtools/svmedit.hxx>
38 #include <svtools/xtextedt.hxx>
39 #include <svl/brdcst.hxx>
40 #include <svl/undo.hxx>
41 #include <svtools/textwindowpeer.hxx>
42 #include <svl/lstner.hxx>
43 #include <svl/smplhint.hxx>
44
45
46 // IDs erstmal aus VCL geklaut, muss mal richtig delivert werden...
47 #define SV_MENU_EDIT_UNDO 1
48 #define SV_MENU_EDIT_CUT 2
49 #define SV_MENU_EDIT_COPY 3
50 #define SV_MENU_EDIT_PASTE 4
51 #define SV_MENU_EDIT_DELETE 5
52 #define SV_MENU_EDIT_SELECTALL 6
53 #define SV_MENU_EDIT_INSERTSYMBOL 7
54 #include <vcl/scrbar.hxx>
55
56 namespace css = ::com::sun::star;
57
58 class TextWindow : public Window
59 {
60 private:
61 ExtTextEngine* mpExtTextEngine;
62 ExtTextView* mpExtTextView;
63
64 sal_Bool mbInMBDown;
65 sal_Bool mbFocusSelectionHide;
66 sal_Bool mbIgnoreTab;
67 sal_Bool mbActivePopup;
68 sal_Bool mbSelectOnTab;
69
70 public:
71 TextWindow( Window* pParent );
72 ~TextWindow();
73
GetTextEngine() const74 ExtTextEngine* GetTextEngine() const { return mpExtTextEngine; }
GetTextView() const75 ExtTextView* GetTextView() const { return mpExtTextView; }
76
77 virtual void MouseMove( const MouseEvent& rMEvt );
78 virtual void MouseButtonDown( const MouseEvent& rMEvt );
79 virtual void MouseButtonUp( const MouseEvent& rMEvt );
80 virtual void KeyInput( const KeyEvent& rKEvent );
81
82 virtual void Command( const CommandEvent& rCEvt );
83
84 virtual void Paint( const Rectangle& rRect );
85 virtual void Resize();
86
87 virtual void GetFocus();
88 virtual void LoseFocus();
89
IsAutoFocusHide() const90 sal_Bool IsAutoFocusHide() const { return mbFocusSelectionHide; }
SetAutoFocusHide(sal_Bool bAutoHide)91 void SetAutoFocusHide( sal_Bool bAutoHide ) { mbFocusSelectionHide = bAutoHide; }
92
IsIgnoreTab() const93 sal_Bool IsIgnoreTab() const { return mbIgnoreTab; }
SetIgnoreTab(sal_Bool bIgnore)94 void SetIgnoreTab( sal_Bool bIgnore ) { mbIgnoreTab = bIgnore; }
95
DisableSelectionOnFocus()96 void DisableSelectionOnFocus() {mbSelectOnTab = sal_False;}
97
98 virtual
99 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >
100 GetComponentInterface(sal_Bool bCreate = sal_True);
101 };
102
103
104 class ImpSvMEdit : public SfxListener
105 {
106 private:
107 MultiLineEdit* pSvMultiLineEdit;
108
109 TextWindow* mpTextWindow;
110 ScrollBar* mpHScrollBar;
111 ScrollBar* mpVScrollBar;
112 ScrollBarBox* mpScrollBox;
113
114 Point maTextWindowOffset;
115 xub_StrLen mnTextWidth;
116 mutable Selection maSelection;
117
118 protected:
119 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
120 void ImpUpdateSrollBarVis( WinBits nWinStyle );
121 void ImpInitScrollBars();
122 void ImpSetScrollBarRanges();
123 void ImpSetHScrollBarThumbPos();
124 DECL_LINK( ScrollHdl, ScrollBar* );
125
126 public:
127 ImpSvMEdit( MultiLineEdit* pSvMultiLineEdit, WinBits nWinStyle );
128 ~ImpSvMEdit();
129
130 void SetModified( sal_Bool bMod );
131 sal_Bool IsModified() const;
132
133 void SetReadOnly( sal_Bool bRdOnly );
134 sal_Bool IsReadOnly() const;
135
136 void SetMaxTextLen( xub_StrLen nLen );
137 xub_StrLen GetMaxTextLen() const;
138
139 void SetInsertMode( sal_Bool bInsert );
140 sal_Bool IsInsertMode() const;
141
142 void InsertText( const String& rStr );
143 String GetSelected() const;
144 String GetSelected( LineEnd aSeparator ) const;
145
146 void SetSelection( const Selection& rSelection );
147 const Selection& GetSelection() const;
148
149 void Cut();
150 void Copy();
151 void Paste();
152
153 void SetText( const String& rStr );
154 String GetText() const;
155 String GetText( LineEnd aSeparator ) const;
156 String GetTextLines() const;
157 String GetTextLines( LineEnd aSeparator ) const;
158
159 void Resize();
160 void GetFocus();
161
162 sal_Bool HandleCommand( const CommandEvent& rCEvt );
163
164 void Enable( sal_Bool bEnable );
165
166 Size CalcMinimumSize() const;
167 Size CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const;
168 void GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const;
169
170 void SetAlign( WinBits nWinStyle );
171
172 void InitFromStyle( WinBits nWinStyle );
173
GetTextWindow()174 TextWindow* GetTextWindow() { return mpTextWindow; }
GetHScrollBar()175 ScrollBar* GetHScrollBar() { return mpHScrollBar; }
GetVScrollBar()176 ScrollBar* GetVScrollBar() { return mpVScrollBar; }
177
178 void SetTextWindowOffset( const Point& rOffset );
179 };
180
ImpSvMEdit(MultiLineEdit * pEdt,WinBits nWinStyle)181 ImpSvMEdit::ImpSvMEdit( MultiLineEdit* pEdt, WinBits nWinStyle )
182 :mpHScrollBar(NULL)
183 ,mpVScrollBar(NULL)
184 ,mpScrollBox(NULL)
185 {
186 pSvMultiLineEdit = pEdt;
187 mnTextWidth = 0;
188 mpTextWindow = new TextWindow( pEdt );
189 mpTextWindow->Show();
190 InitFromStyle( nWinStyle );
191 StartListening( *mpTextWindow->GetTextEngine() );
192 }
193
ImpUpdateSrollBarVis(WinBits nWinStyle)194 void ImpSvMEdit::ImpUpdateSrollBarVis( WinBits nWinStyle )
195 {
196 const sal_Bool bHaveVScroll = (NULL != mpVScrollBar);
197 const sal_Bool bHaveHScroll = (NULL != mpHScrollBar);
198 const sal_Bool bHaveScrollBox = (NULL != mpScrollBox);
199
200 sal_Bool bNeedVScroll = ( nWinStyle & WB_VSCROLL ) == WB_VSCROLL;
201 const sal_Bool bNeedHScroll = ( nWinStyle & WB_HSCROLL ) == WB_HSCROLL;
202
203 const sal_Bool bAutoVScroll = ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL;
204 if ( !bNeedVScroll && bAutoVScroll )
205 {
206 TextEngine& rEngine( *mpTextWindow->GetTextEngine() );
207 sal_uLong nOverallTextHeight(0);
208 for ( sal_uLong i=0; i<rEngine.GetParagraphCount(); ++i )
209 nOverallTextHeight += rEngine.GetTextHeight( i );
210 if ( nOverallTextHeight > (sal_uLong)mpTextWindow->GetOutputSizePixel().Height() )
211 bNeedVScroll = true;
212 }
213
214 const sal_Bool bNeedScrollBox = bNeedVScroll && bNeedHScroll;
215
216 sal_Bool bScrollbarsChanged = false;
217 if ( bHaveVScroll != bNeedVScroll )
218 {
219 delete mpVScrollBar;
220 mpVScrollBar = bNeedVScroll ? new ScrollBar( pSvMultiLineEdit, WB_VSCROLL|WB_DRAG ) : NULL;
221
222 if ( bNeedVScroll )
223 {
224 mpVScrollBar->Show();
225 mpVScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
226 }
227
228 bScrollbarsChanged = sal_True;
229 }
230
231 if ( bHaveHScroll != bNeedHScroll )
232 {
233 delete mpHScrollBar;
234 mpHScrollBar = bNeedHScroll ? new ScrollBar( pSvMultiLineEdit, WB_HSCROLL|WB_DRAG ) : NULL;
235
236 if ( bNeedHScroll )
237 {
238 mpHScrollBar->Show();
239 mpHScrollBar->SetScrollHdl( LINK( this, ImpSvMEdit, ScrollHdl ) );
240 }
241
242 bScrollbarsChanged = sal_True;
243 }
244
245 if ( bHaveScrollBox != bNeedScrollBox )
246 {
247 delete mpScrollBox;
248 mpScrollBox = bNeedScrollBox ? new ScrollBarBox( pSvMultiLineEdit, WB_SIZEABLE ) : NULL;
249
250 if ( bNeedScrollBox )
251 mpScrollBox->Show();
252 }
253
254 if ( bScrollbarsChanged )
255 {
256 ImpInitScrollBars();
257 Resize();
258 }
259 }
260
InitFromStyle(WinBits nWinStyle)261 void ImpSvMEdit::InitFromStyle( WinBits nWinStyle )
262 {
263 ImpUpdateSrollBarVis( nWinStyle );
264 SetAlign( nWinStyle );
265
266 if ( nWinStyle & WB_NOHIDESELECTION )
267 mpTextWindow->SetAutoFocusHide( sal_False );
268 else
269 mpTextWindow->SetAutoFocusHide( sal_True );
270
271 if ( nWinStyle & WB_READONLY )
272 mpTextWindow->GetTextView()->SetReadOnly( sal_True );
273 else
274 mpTextWindow->GetTextView()->SetReadOnly( sal_False );
275
276 if ( nWinStyle & WB_IGNORETAB )
277 {
278 mpTextWindow->SetIgnoreTab( sal_True );
279 }
280 else
281 {
282 mpTextWindow->SetIgnoreTab( sal_False );
283 // #103667# MultiLineEdit has the flag, but focusable window also needs this flag
284 WinBits nStyle = mpTextWindow->GetStyle();
285 nStyle |= WINDOW_DLGCTRL_MOD1TAB;
286 mpTextWindow->SetStyle( nStyle );
287 }
288 }
289
~ImpSvMEdit()290 ImpSvMEdit::~ImpSvMEdit()
291 {
292 EndListening( *mpTextWindow->GetTextEngine() );
293 delete mpTextWindow;
294 delete mpHScrollBar;
295 delete mpVScrollBar;
296 delete mpScrollBox;
297 }
298
ImpSetScrollBarRanges()299 void ImpSvMEdit::ImpSetScrollBarRanges()
300 {
301 if ( mpVScrollBar )
302 {
303 sal_uLong nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
304 mpVScrollBar->SetRange( Range( 0, (long)nTextHeight-1 ) );
305 }
306 if ( mpHScrollBar )
307 {
308 // sal_uLong nTextWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
309 // Es gibt kein Notify bei Breiten-Aenderung...
310 // sal_uLong nW = Max( (sal_uLong)mpTextWindow->GetOutputSizePixel().Width()*5, (sal_uLong)nTextWidth );
311 // mpHScrollBar->SetRange( Range( 0, (long)nW ) );
312 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
313 }
314 }
315
ImpInitScrollBars()316 void ImpSvMEdit::ImpInitScrollBars()
317 {
318 static const sal_Unicode sampleText[] = { 'x', '\0' };
319 if ( mpHScrollBar || mpVScrollBar )
320 {
321 ImpSetScrollBarRanges();
322 Size aCharBox;
323 aCharBox.Width() = mpTextWindow->GetTextWidth( sampleText );
324 aCharBox.Height() = mpTextWindow->GetTextHeight();
325 Size aOutSz = mpTextWindow->GetOutputSizePixel();
326 if ( mpHScrollBar )
327 {
328 mpHScrollBar->SetVisibleSize( aOutSz.Width() );
329 mpHScrollBar->SetPageSize( aOutSz.Width() * 8 / 10 );
330 mpHScrollBar->SetLineSize( aCharBox.Width()*10 );
331 ImpSetHScrollBarThumbPos();
332 }
333 if ( mpVScrollBar )
334 {
335 mpVScrollBar->SetVisibleSize( aOutSz.Height() );
336 mpVScrollBar->SetPageSize( aOutSz.Height() * 8 / 10 );
337 mpVScrollBar->SetLineSize( aCharBox.Height() );
338 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
339 }
340 }
341 }
342
ImpSetHScrollBarThumbPos()343 void ImpSvMEdit::ImpSetHScrollBarThumbPos()
344 {
345 long nX = mpTextWindow->GetTextView()->GetStartDocPos().X();
346 if ( !mpTextWindow->GetTextEngine()->IsRightToLeft() )
347 mpHScrollBar->SetThumbPos( nX );
348 else
349 mpHScrollBar->SetThumbPos( mnTextWidth - mpHScrollBar->GetVisibleSize() - nX );
350
351 }
352
IMPL_LINK(ImpSvMEdit,ScrollHdl,ScrollBar *,pCurScrollBar)353 IMPL_LINK( ImpSvMEdit, ScrollHdl, ScrollBar*, pCurScrollBar )
354 {
355 long nDiffX = 0, nDiffY = 0;
356
357 if ( pCurScrollBar == mpVScrollBar )
358 nDiffY = mpTextWindow->GetTextView()->GetStartDocPos().Y() - pCurScrollBar->GetThumbPos();
359 else if ( pCurScrollBar == mpHScrollBar )
360 nDiffX = mpTextWindow->GetTextView()->GetStartDocPos().X() - pCurScrollBar->GetThumbPos();
361
362 mpTextWindow->GetTextView()->Scroll( nDiffX, nDiffY );
363 // mpTextWindow->GetTextView()->ShowCursor( sal_False, sal_True );
364
365 return 0;
366 }
367
368
369 // void ImpSvMEdit::ImpModified()
370 // {
371 // // Wann wird das gerufen ?????????????????????
372 // pSvMultiLineEdit->Modify();
373 // }
374
SetAlign(WinBits nWinStyle)375 void ImpSvMEdit::SetAlign( WinBits nWinStyle )
376 {
377 sal_Bool bRTL = Application::GetSettings().GetLayoutRTL();
378 mpTextWindow->GetTextEngine()->SetRightToLeft( bRTL );
379
380 if ( nWinStyle & WB_CENTER )
381 mpTextWindow->GetTextEngine()->SetTextAlign( TXTALIGN_CENTER );
382 else if ( nWinStyle & WB_RIGHT )
383 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_RIGHT : TXTALIGN_LEFT );
384 else if ( nWinStyle & WB_LEFT )
385 mpTextWindow->GetTextEngine()->SetTextAlign( !bRTL ? TXTALIGN_LEFT : TXTALIGN_RIGHT );
386 }
387
SetTextWindowOffset(const Point & rOffset)388 void ImpSvMEdit::SetTextWindowOffset( const Point& rOffset )
389 {
390 maTextWindowOffset = rOffset;
391 Resize();
392 }
393
SetModified(sal_Bool bMod)394 void ImpSvMEdit::SetModified( sal_Bool bMod )
395 {
396 mpTextWindow->GetTextEngine()->SetModified( bMod );
397 }
398
IsModified() const399 sal_Bool ImpSvMEdit::IsModified() const
400 {
401 return mpTextWindow->GetTextEngine()->IsModified();
402 }
403
SetInsertMode(sal_Bool bInsert)404 void ImpSvMEdit::SetInsertMode( sal_Bool bInsert )
405 {
406 mpTextWindow->GetTextView()->SetInsertMode( bInsert );
407 }
408
SetReadOnly(sal_Bool bRdOnly)409 void ImpSvMEdit::SetReadOnly( sal_Bool bRdOnly )
410 {
411 mpTextWindow->GetTextView()->SetReadOnly( bRdOnly );
412 // Farbe anpassen ???????????????????????????
413 }
414
IsReadOnly() const415 sal_Bool ImpSvMEdit::IsReadOnly() const
416 {
417 return mpTextWindow->GetTextView()->IsReadOnly();
418 }
419
SetMaxTextLen(xub_StrLen nLen)420 void ImpSvMEdit::SetMaxTextLen( xub_StrLen nLen )
421 {
422 mpTextWindow->GetTextEngine()->SetMaxTextLen( nLen );
423 }
424
GetMaxTextLen() const425 xub_StrLen ImpSvMEdit::GetMaxTextLen() const
426 {
427 return sal::static_int_cast< xub_StrLen >(
428 mpTextWindow->GetTextEngine()->GetMaxTextLen());
429 }
430
InsertText(const String & rStr)431 void ImpSvMEdit::InsertText( const String& rStr )
432 {
433 mpTextWindow->GetTextView()->InsertText( rStr );
434 }
435
GetSelected() const436 String ImpSvMEdit::GetSelected() const
437 {
438 return mpTextWindow->GetTextView()->GetSelected();
439 }
440
GetSelected(LineEnd aSeparator) const441 String ImpSvMEdit::GetSelected( LineEnd aSeparator ) const
442 {
443 return mpTextWindow->GetTextView()->GetSelected( aSeparator );
444 }
445
Resize()446 void ImpSvMEdit::Resize()
447 {
448 size_t nIteration = 1;
449 do
450 {
451 WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
452 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
453 ImpUpdateSrollBarVis( nWinStyle );
454
455 Size aSz = pSvMultiLineEdit->GetOutputSizePixel();
456 Size aEditSize = aSz;
457 long nSBWidth = pSvMultiLineEdit->GetSettings().GetStyleSettings().GetScrollBarSize();
458 nSBWidth = pSvMultiLineEdit->CalcZoom( nSBWidth );
459
460 if ( mpHScrollBar )
461 aSz.Height() -= nSBWidth+1;
462 if ( mpVScrollBar )
463 aSz.Width() -= nSBWidth+1;
464
465 if ( !mpHScrollBar )
466 mpTextWindow->GetTextEngine()->SetMaxTextWidth( aSz.Width() );
467 else
468 mpHScrollBar->SetPosSizePixel( 0, aEditSize.Height()-nSBWidth, aSz.Width(), nSBWidth );
469
470 Point aTextWindowPos( maTextWindowOffset );
471 if ( mpVScrollBar )
472 {
473 if( Application::GetSettings().GetLayoutRTL() )
474 {
475 mpVScrollBar->SetPosSizePixel( 0, 0, nSBWidth, aSz.Height() );
476 aTextWindowPos.X() += nSBWidth;
477 }
478 else
479 mpVScrollBar->SetPosSizePixel( aEditSize.Width()-nSBWidth, 0, nSBWidth, aSz.Height() );
480 }
481
482 if ( mpScrollBox )
483 mpScrollBox->SetPosSizePixel( aSz.Width(), aSz.Height(), nSBWidth, nSBWidth );
484
485 Size aTextWindowSize( aSz );
486 aTextWindowSize.Width() -= maTextWindowOffset.X();
487 aTextWindowSize.Height() -= maTextWindowOffset.Y();
488 if ( aTextWindowSize.Width() < 0 )
489 aTextWindowSize.Width() = 0;
490 if ( aTextWindowSize.Height() < 0 )
491 aTextWindowSize.Height() = 0;
492
493 Size aOldTextWindowSize( mpTextWindow->GetSizePixel() );
494 mpTextWindow->SetPosSizePixel( aTextWindowPos, aTextWindowSize );
495 if ( aOldTextWindowSize == aTextWindowSize )
496 break;
497
498 // Changing the text window size might effectively have changed the need for
499 // scrollbars, so do another iteration.
500 ++nIteration;
501 OSL_ENSURE( nIteration < 3, "ImpSvMEdit::Resize: isn't this expected to terminate with the second iteration?" );
502
503 } while ( nIteration <= 3 ); // artificial break after four iterations
504
505 ImpInitScrollBars();
506 }
507
GetFocus()508 void ImpSvMEdit::GetFocus()
509 {
510 mpTextWindow->GrabFocus();
511 }
512
Cut()513 void ImpSvMEdit::Cut()
514 {
515 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
516 mpTextWindow->GetTextView()->Cut();
517 }
518
Copy()519 void ImpSvMEdit::Copy()
520 {
521 mpTextWindow->GetTextView()->Copy();
522 }
523
Paste()524 void ImpSvMEdit::Paste()
525 {
526 if ( !mpTextWindow->GetTextView()->IsReadOnly() )
527 mpTextWindow->GetTextView()->Paste();
528 }
529
SetText(const String & rStr)530 void ImpSvMEdit::SetText( const String& rStr )
531 {
532 sal_Bool bWasModified = mpTextWindow->GetTextEngine()->IsModified();
533 mpTextWindow->GetTextEngine()->SetText( rStr );
534 if ( !bWasModified )
535 mpTextWindow->GetTextEngine()->SetModified( sal_False );
536
537 mpTextWindow->GetTextView()->SetSelection( TextSelection() );
538
539 WinBits nWinStyle( pSvMultiLineEdit->GetStyle() );
540 if ( ( nWinStyle & WB_AUTOVSCROLL ) == WB_AUTOVSCROLL )
541 ImpUpdateSrollBarVis( nWinStyle );
542 }
543
GetText() const544 String ImpSvMEdit::GetText() const
545 {
546 return mpTextWindow->GetTextEngine()->GetText();
547 }
548
GetText(LineEnd aSeparator) const549 String ImpSvMEdit::GetText( LineEnd aSeparator ) const
550 {
551 return mpTextWindow->GetTextEngine()->GetText( aSeparator );
552 }
553
GetTextLines() const554 String ImpSvMEdit::GetTextLines() const
555 {
556 return mpTextWindow->GetTextEngine()->GetTextLines();
557 }
558
GetTextLines(LineEnd aSeparator) const559 String ImpSvMEdit::GetTextLines( LineEnd aSeparator ) const
560 {
561 return mpTextWindow->GetTextEngine()->GetTextLines( aSeparator );
562 }
563
Notify(SfxBroadcaster &,const SfxHint & rHint)564 void ImpSvMEdit::Notify( SfxBroadcaster&, const SfxHint& rHint )
565 {
566 if ( rHint.ISA( TextHint ) )
567 {
568 const TextHint& rTextHint = (const TextHint&)rHint;
569 if( rTextHint.GetId() == TEXT_HINT_VIEWSCROLLED )
570 {
571 if ( mpHScrollBar )
572 ImpSetHScrollBarThumbPos();
573 if ( mpVScrollBar )
574 mpVScrollBar->SetThumbPos( mpTextWindow->GetTextView()->GetStartDocPos().Y() );
575 }
576 else if( rTextHint.GetId() == TEXT_HINT_TEXTHEIGHTCHANGED )
577 {
578 if ( mpTextWindow->GetTextView()->GetStartDocPos().Y() )
579 {
580 long nOutHeight = mpTextWindow->GetOutputSizePixel().Height();
581 long nTextHeight = mpTextWindow->GetTextEngine()->GetTextHeight();
582 if ( nTextHeight < nOutHeight )
583 mpTextWindow->GetTextView()->Scroll( 0, mpTextWindow->GetTextView()->GetStartDocPos().Y() );
584 }
585
586 ImpSetScrollBarRanges();
587 }
588 else if( rTextHint.GetId() == TEXT_HINT_TEXTFORMATTED )
589 {
590 if ( mpHScrollBar )
591 {
592 sal_uLong nWidth = mpTextWindow->GetTextEngine()->CalcTextWidth();
593 if ( nWidth != mnTextWidth )
594 {
595 mnTextWidth = sal::static_int_cast< xub_StrLen >(nWidth);
596 mpHScrollBar->SetRange( Range( 0, (long)mnTextWidth-1 ) );
597 ImpSetHScrollBarThumbPos();
598 }
599 }
600 }
601 else if( rTextHint.GetId() == TEXT_HINT_MODIFIED )
602 {
603 pSvMultiLineEdit->Modify();
604 }
605 }
606 }
607
SetSelection(const Selection & rSelection)608 void ImpSvMEdit::SetSelection( const Selection& rSelection )
609 {
610 String aText = mpTextWindow->GetTextEngine()->GetText();
611
612 Selection aNewSelection( rSelection );
613 if ( aNewSelection.Min() < 0 )
614 aNewSelection.Min() = 0;
615 else if ( aNewSelection.Min() > aText.Len() )
616 aNewSelection.Min() = aText.Len();
617 if ( aNewSelection.Max() < 0 )
618 aNewSelection.Max() = 0;
619 else if ( aNewSelection.Max() > aText.Len() )
620 aNewSelection.Max() = aText.Len();
621
622 long nEnd = Max( aNewSelection.Min(), aNewSelection.Max() );
623 TextSelection aTextSel;
624 sal_uLong nPara = 0;
625 sal_uInt16 nChar = 0;
626 sal_uInt16 x = 0;
627 while ( x <= nEnd )
628 {
629 if ( x == aNewSelection.Min() )
630 aTextSel.GetStart() = TextPaM( nPara, nChar );
631 if ( x == aNewSelection.Max() )
632 aTextSel.GetEnd() = TextPaM( nPara, nChar );
633
634 if ( ( x < aText.Len() ) && ( aText.GetChar( x ) == '\n' ) )
635 {
636 nPara++;
637 nChar = 0;
638 }
639 else
640 nChar++;
641 x++;
642 }
643 mpTextWindow->GetTextView()->SetSelection( aTextSel );
644 }
645
GetSelection() const646 const Selection& ImpSvMEdit::GetSelection() const
647 {
648 maSelection = Selection();
649 TextSelection aTextSel( mpTextWindow->GetTextView()->GetSelection() );
650 aTextSel.Justify();
651 // Selektion flachklopfen => jeder Umbruch ein Zeichen...
652
653 ExtTextEngine* pExtTextEngine = mpTextWindow->GetTextEngine();
654 // Absaetze davor:
655 sal_uLong n;
656 for ( n = 0; n < aTextSel.GetStart().GetPara(); n++ )
657 {
658 maSelection.Min() += pExtTextEngine->GetTextLen( n );
659 maSelection.Min()++;
660 }
661
662 // Erster Absatz mit Selektion:
663 maSelection.Max() = maSelection.Min();
664 maSelection.Min() += aTextSel.GetStart().GetIndex();
665
666 for ( n = aTextSel.GetStart().GetPara(); n < aTextSel.GetEnd().GetPara(); n++ )
667 {
668 maSelection.Max() += pExtTextEngine->GetTextLen( n );
669 maSelection.Max()++;
670 }
671
672 maSelection.Max() += aTextSel.GetEnd().GetIndex();
673
674 return maSelection;
675 }
676
CalcMinimumSize() const677 Size ImpSvMEdit::CalcMinimumSize() const
678 {
679 Size aSz( mpTextWindow->GetTextEngine()->CalcTextWidth(),
680 mpTextWindow->GetTextEngine()->GetTextHeight() );
681
682 if ( mpHScrollBar )
683 aSz.Height() += mpHScrollBar->GetSizePixel().Height();
684 if ( mpVScrollBar )
685 aSz.Width() += mpVScrollBar->GetSizePixel().Width();
686
687 return aSz;
688 }
689
CalcSize(sal_uInt16 nColumns,sal_uInt16 nLines) const690 Size ImpSvMEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
691 {
692 static const sal_Unicode sampleText[] = { 'X', '\0' };
693
694 Size aSz;
695 Size aCharSz;
696 aCharSz.Width() = mpTextWindow->GetTextWidth( sampleText );
697 aCharSz.Height() = mpTextWindow->GetTextHeight();
698
699 if ( nLines )
700 aSz.Height() = nLines*aCharSz.Height();
701 else
702 aSz.Height() = mpTextWindow->GetTextEngine()->GetTextHeight();
703
704 if ( nColumns )
705 aSz.Width() = nColumns*aCharSz.Width();
706 else
707 aSz.Width() = mpTextWindow->GetTextEngine()->CalcTextWidth();
708
709 if ( mpHScrollBar )
710 aSz.Height() += mpHScrollBar->GetSizePixel().Height();
711 if ( mpVScrollBar )
712 aSz.Width() += mpVScrollBar->GetSizePixel().Width();
713
714 return aSz;
715 }
716
GetMaxVisColumnsAndLines(sal_uInt16 & rnCols,sal_uInt16 & rnLines) const717 void ImpSvMEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
718 {
719 static const sal_Unicode sampleText[] = { 'x', '\0' };
720 Size aOutSz = mpTextWindow->GetOutputSizePixel();
721 Size aCharSz( mpTextWindow->GetTextWidth( sampleText ), mpTextWindow->GetTextHeight() );
722 rnCols = (sal_uInt16) (aOutSz.Width()/aCharSz.Width());
723 rnLines = (sal_uInt16) (aOutSz.Height()/aCharSz.Height());
724 }
725
Enable(sal_Bool bEnable)726 void ImpSvMEdit::Enable( sal_Bool bEnable )
727 {
728 mpTextWindow->Enable( bEnable );
729 if ( mpHScrollBar )
730 mpHScrollBar->Enable( bEnable );
731 if ( mpVScrollBar )
732 mpVScrollBar->Enable( bEnable );
733 }
734
HandleCommand(const CommandEvent & rCEvt)735 sal_Bool ImpSvMEdit::HandleCommand( const CommandEvent& rCEvt )
736 {
737 sal_Bool bDone = sal_False;
738 if ( ( rCEvt.GetCommand() == COMMAND_WHEEL ) ||
739 ( rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL ) ||
740 ( rCEvt.GetCommand() == COMMAND_AUTOSCROLL ) )
741 {
742 mpTextWindow->HandleScrollCommand( rCEvt, mpHScrollBar, mpVScrollBar );
743 bDone = sal_True;
744 }
745 return bDone;
746 }
747
748
TextWindow(Window * pParent)749 TextWindow::TextWindow( Window* pParent ) : Window( pParent )
750 {
751 mbInMBDown = sal_False;
752 mbSelectOnTab = sal_True;
753 mbFocusSelectionHide = sal_False;
754 mbIgnoreTab = sal_False;
755 mbActivePopup = sal_False;
756 mbSelectOnTab = sal_True;
757
758 SetPointer( Pointer( POINTER_TEXT ) );
759
760 mpExtTextEngine = new ExtTextEngine;
761 mpExtTextEngine->SetMaxTextLen( STRING_MAXLEN );
762 if( pParent->GetStyle() & WB_BORDER )
763 mpExtTextEngine->SetLeftMargin( 2 );
764 mpExtTextEngine->SetLocale( GetSettings().GetLocale() );
765 mpExtTextView = new ExtTextView( mpExtTextEngine, this );
766 mpExtTextEngine->InsertView( mpExtTextView );
767 mpExtTextEngine->EnableUndo( sal_True );
768 mpExtTextView->ShowCursor();
769
770 Color aBackgroundColor = GetSettings().GetStyleSettings().GetWorkspaceColor();
771 SetBackground( aBackgroundColor );
772 pParent->SetBackground( aBackgroundColor );
773 }
774
~TextWindow()775 TextWindow::~TextWindow()
776 {
777 delete mpExtTextView;
778 delete mpExtTextEngine;
779 }
780
MouseMove(const MouseEvent & rMEvt)781 void TextWindow::MouseMove( const MouseEvent& rMEvt )
782 {
783 mpExtTextView->MouseMove( rMEvt );
784 Window::MouseMove( rMEvt );
785 }
786
MouseButtonDown(const MouseEvent & rMEvt)787 void TextWindow::MouseButtonDown( const MouseEvent& rMEvt )
788 {
789 mbInMBDown = sal_True; // Dann im GetFocus nicht alles selektieren wird
790 mpExtTextView->MouseButtonDown( rMEvt );
791 Window::MouseButtonDown( rMEvt );
792 GrabFocus();
793 mbInMBDown = sal_False;
794 }
795
MouseButtonUp(const MouseEvent & rMEvt)796 void TextWindow::MouseButtonUp( const MouseEvent& rMEvt )
797 {
798 mpExtTextView->MouseButtonUp( rMEvt );
799 Window::MouseButtonUp( rMEvt );
800 }
801
KeyInput(const KeyEvent & rKEvent)802 void TextWindow::KeyInput( const KeyEvent& rKEvent )
803 {
804 sal_Bool bDone = sal_False;
805 sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
806 if ( nCode == com::sun::star::awt::Key::SELECT_ALL ||
807 ( (nCode == KEY_A) && rKEvent.GetKeyCode().IsMod1() && !rKEvent.GetKeyCode().IsMod2() )
808 )
809 {
810 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
811 bDone = sal_True;
812 }
813 else if ( (nCode == KEY_S) && rKEvent.GetKeyCode().IsShift() && rKEvent.GetKeyCode().IsMod1() )
814 {
815 if ( Edit::GetGetSpecialCharsFunction() )
816 {
817 // Damit die Selektion erhalten bleibt
818 mbActivePopup = sal_True;
819 XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
820 if ( aChars.Len() )
821 {
822 mpExtTextView->InsertText( aChars );
823 mpExtTextView->GetTextEngine()->SetModified( sal_True );
824 }
825 mbActivePopup = sal_False;
826 bDone = sal_True;
827 }
828 }
829 else if ( nCode == KEY_TAB )
830 {
831 if ( !mbIgnoreTab || rKEvent.GetKeyCode().IsMod1() )
832 bDone = mpExtTextView->KeyInput( rKEvent );
833 }
834 else
835 {
836 bDone = mpExtTextView->KeyInput( rKEvent );
837 }
838
839 if ( !bDone )
840 Window::KeyInput( rKEvent );
841 }
842
Paint(const Rectangle & rRect)843 void TextWindow::Paint( const Rectangle& rRect )
844 {
845 mpExtTextView->Paint( rRect );
846 }
847
Resize()848 void TextWindow::Resize()
849 {
850 }
851
Command(const CommandEvent & rCEvt)852 void TextWindow::Command( const CommandEvent& rCEvt )
853 {
854 if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
855 {
856 PopupMenu* pPopup = Edit::CreatePopupMenu();
857 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
858 if ( rStyleSettings.GetOptions() & STYLE_OPTION_HIDEDISABLED )
859 pPopup->SetMenuFlags( MENU_FLAG_HIDEDISABLEDENTRIES );
860 if ( !mpExtTextView->HasSelection() )
861 {
862 pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
863 pPopup->EnableItem( SV_MENU_EDIT_COPY, sal_False );
864 pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
865 }
866 if ( mpExtTextView->IsReadOnly() )
867 {
868 pPopup->EnableItem( SV_MENU_EDIT_CUT, sal_False );
869 pPopup->EnableItem( SV_MENU_EDIT_PASTE, sal_False );
870 pPopup->EnableItem( SV_MENU_EDIT_DELETE, sal_False );
871 pPopup->EnableItem( SV_MENU_EDIT_INSERTSYMBOL, sal_False );
872 }
873 if ( !mpExtTextView->GetTextEngine()->HasUndoManager() || !mpExtTextView->GetTextEngine()->GetUndoManager().GetUndoActionCount() )
874 {
875 pPopup->EnableItem( SV_MENU_EDIT_UNDO, sal_False );
876 }
877 // if ( ( maSelection.Min() == 0 ) && ( maSelection.Max() == maText.Len() ) )
878 // {
879 // pPopup->EnableItem( SV_MENU_EDIT_SELECTALL, sal_False );
880 // }
881 if ( !Edit::GetGetSpecialCharsFunction() )
882 {
883 sal_uInt16 nPos = pPopup->GetItemPos( SV_MENU_EDIT_INSERTSYMBOL );
884 pPopup->RemoveItem( nPos );
885 pPopup->RemoveItem( nPos-1 );
886 }
887
888 mbActivePopup = sal_True;
889 Point aPos = rCEvt.GetMousePosPixel();
890 if ( !rCEvt.IsMouseEvent() )
891 {
892 // !!! Irgendwann einmal Menu zentriert in der Selektion anzeigen !!!
893 Size aSize = GetOutputSizePixel();
894 aPos = Point( aSize.Width()/2, aSize.Height()/2 );
895 }
896 // pPopup->RemoveDisabledEntries();
897 sal_uInt16 n = pPopup->Execute( this, aPos );
898 Edit::DeletePopupMenu( pPopup );
899 switch ( n )
900 {
901 case SV_MENU_EDIT_UNDO: mpExtTextView->Undo();
902 mpExtTextEngine->SetModified( sal_True );
903 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
904 break;
905 case SV_MENU_EDIT_CUT: mpExtTextView->Cut();
906 mpExtTextEngine->SetModified( sal_True );
907 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
908 break;
909 case SV_MENU_EDIT_COPY: mpExtTextView->Copy();
910 break;
911 case SV_MENU_EDIT_PASTE: mpExtTextView->Paste();
912 mpExtTextEngine->SetModified( sal_True );
913 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
914 break;
915 case SV_MENU_EDIT_DELETE: mpExtTextView->DeleteSelected();
916 mpExtTextEngine->SetModified( sal_True );
917 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
918 break;
919 case SV_MENU_EDIT_SELECTALL: mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFFFFFF, 0xFFFF ) ) );
920 break;
921 case SV_MENU_EDIT_INSERTSYMBOL:
922 {
923 XubString aChars = Edit::GetGetSpecialCharsFunction()( this, GetFont() );
924 if ( aChars.Len() )
925 {
926 mpExtTextView->InsertText( aChars );
927 mpExtTextEngine->SetModified( sal_True );
928 mpExtTextEngine->Broadcast( TextHint( TEXT_HINT_MODIFIED ) );
929 }
930 }
931 break;
932 }
933 mbActivePopup = sal_False;
934 }
935 else
936 {
937 mpExtTextView->Command( rCEvt );
938 }
939 Window::Command( rCEvt );
940 }
941
GetFocus()942 void TextWindow::GetFocus()
943 {
944 Window::GetFocus();
945
946 if ( !mbActivePopup )
947 {
948 sal_Bool bGotoCursor = !mpExtTextView->IsReadOnly();
949 if ( mbFocusSelectionHide
950 && IsReallyVisible()
951 && !mpExtTextView->IsReadOnly()
952 && ( mbSelectOnTab
953 && ( !mbInMBDown
954 || ( GetSettings().GetStyleSettings().GetSelectionOptions() & SELECTION_OPTION_FOCUS ) ) ) )
955 {
956 // Alles selektieren, aber nicht scrollen
957 sal_Bool bAutoScroll = mpExtTextView->IsAutoScroll();
958 mpExtTextView->SetAutoScroll( sal_False );
959 mpExtTextView->SetSelection( TextSelection( TextPaM( 0, 0 ), TextPaM( 0xFFFF, 0xFFFF ) ) );
960 mpExtTextView->SetAutoScroll( bAutoScroll );
961 bGotoCursor = sal_False;
962 }
963 mpExtTextView->SetPaintSelection( sal_True );
964 mpExtTextView->ShowCursor( bGotoCursor );
965 }
966 }
967
968
LoseFocus()969 void TextWindow::LoseFocus()
970 {
971 Window::LoseFocus();
972
973 if ( mbFocusSelectionHide && !mbActivePopup )
974 mpExtTextView->SetPaintSelection( sal_False );
975 }
976
977
978 // virtual
979 ::css::uno::Reference< ::css::awt::XWindowPeer >
GetComponentInterface(sal_Bool bCreate)980 TextWindow::GetComponentInterface(sal_Bool bCreate)
981 {
982 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
983 Window::GetComponentInterface(false));
984 if (!xPeer.is() && bCreate)
985 {
986 xPeer = new ::svt::TextWindowPeer(*GetTextView(), true);
987 SetComponentInterface(xPeer);
988 }
989 return xPeer;
990 }
991
MultiLineEdit(Window * pParent,WinBits nWinStyle)992 MultiLineEdit::MultiLineEdit( Window* pParent, WinBits nWinStyle )
993 : Edit( pParent, nWinStyle )
994 {
995 SetType( WINDOW_MULTILINEEDIT );
996 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
997 ImplInitSettings( sal_True, sal_True, sal_True );
998 pUpdateDataTimer = 0;
999
1000 SetCompoundControl( sal_True );
1001 SetStyle( ImplInitStyle( nWinStyle ) );
1002 }
1003
MultiLineEdit(Window * pParent,const ResId & rResId)1004 MultiLineEdit::MultiLineEdit( Window* pParent, const ResId& rResId )
1005 : Edit( pParent, rResId.SetRT( RSC_MULTILINEEDIT ) )
1006 {
1007 SetType( WINDOW_MULTILINEEDIT );
1008 WinBits nWinStyle = rResId.GetWinBits();
1009 pImpSvMEdit = new ImpSvMEdit( this, nWinStyle );
1010 ImplInitSettings( sal_True, sal_True, sal_True );
1011 pUpdateDataTimer = 0;
1012
1013 sal_uInt16 nMaxLen = Edit::GetMaxTextLen();
1014 if ( nMaxLen )
1015 SetMaxTextLen( nMaxLen );
1016
1017 SetText( Edit::GetText() );
1018
1019 if ( IsVisible() )
1020 pImpSvMEdit->Resize();
1021
1022 SetCompoundControl( sal_True );
1023 SetStyle( ImplInitStyle( nWinStyle ) );
1024
1025 // Base Edit ctor could call Show already, but that would cause problems
1026 // with accessibility, as Show might (indirectly) trigger a call to virtual
1027 // GetComponentInterface, which is the Edit's base version instead of the
1028 // MultiLineEdit's version while in the base Edit ctor:
1029 if ((GetStyle() & WB_HIDE) == 0)
1030 Show();
1031 }
1032
~MultiLineEdit()1033 MultiLineEdit::~MultiLineEdit()
1034 {
1035 {
1036 ::std::auto_ptr< ImpSvMEdit > pDelete( pImpSvMEdit );
1037 pImpSvMEdit = NULL;
1038 }
1039 delete pUpdateDataTimer;
1040 }
1041
ImplInitStyle(WinBits nStyle)1042 WinBits MultiLineEdit::ImplInitStyle( WinBits nStyle )
1043 {
1044 if ( !(nStyle & WB_NOTABSTOP) )
1045 nStyle |= WB_TABSTOP;
1046
1047 if ( !(nStyle & WB_NOGROUP) )
1048 nStyle |= WB_GROUP;
1049
1050 if ( !(nStyle & WB_IGNORETAB ))
1051 nStyle |= WINDOW_DLGCTRL_MOD1TAB;
1052
1053 return nStyle;
1054 }
1055
1056
ImplInitSettings(sal_Bool,sal_Bool,sal_Bool bBackground)1057 void MultiLineEdit::ImplInitSettings( sal_Bool /*bFont*/, sal_Bool /*bForeground*/, sal_Bool bBackground )
1058 {
1059 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1060
1061 // Der Font muss immer mit manipuliert werden, weil die TextEngine
1062 // sich nicht um TextColor/Background kuemmert
1063
1064 Color aTextColor = rStyleSettings.GetFieldTextColor();
1065 if ( IsControlForeground() )
1066 aTextColor = GetControlForeground();
1067 if ( !IsEnabled() )
1068 aTextColor = rStyleSettings.GetDisableColor();
1069
1070 Font aFont = rStyleSettings.GetFieldFont();
1071 if ( IsControlFont() )
1072 aFont.Merge( GetControlFont() );
1073 aFont.SetTransparent( IsPaintTransparent() );
1074 SetZoomedPointFont( aFont );
1075 Font TheFont = GetFont();
1076 TheFont.SetColor( aTextColor );
1077 if( IsPaintTransparent() )
1078 TheFont.SetFillColor( Color( COL_TRANSPARENT ) );
1079 else
1080 TheFont.SetFillColor( IsControlBackground() ? GetControlBackground() : rStyleSettings.GetFieldColor() );
1081 pImpSvMEdit->GetTextWindow()->SetFont( TheFont );
1082 pImpSvMEdit->GetTextWindow()->GetTextEngine()->SetFont( TheFont );
1083 pImpSvMEdit->GetTextWindow()->SetTextColor( aTextColor );
1084
1085 if ( bBackground )
1086 {
1087 if( IsPaintTransparent() )
1088 {
1089 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1090 pImpSvMEdit->GetTextWindow()->SetBackground();
1091 pImpSvMEdit->GetTextWindow()->SetControlBackground();
1092 SetBackground();
1093 SetControlBackground();
1094 }
1095 else
1096 {
1097 if( IsControlBackground() )
1098 pImpSvMEdit->GetTextWindow()->SetBackground( GetControlBackground() );
1099 else
1100 pImpSvMEdit->GetTextWindow()->SetBackground( rStyleSettings.GetFieldColor() );
1101 // Auch am MultiLineEdit einstellen, weil die TextComponent
1102 // ggf. die Scrollbars hidet.
1103 SetBackground( pImpSvMEdit->GetTextWindow()->GetBackground() );
1104 }
1105 }
1106 }
1107
Modify()1108 void MultiLineEdit::Modify()
1109 {
1110 aModifyHdlLink.Call( this );
1111
1112 CallEventListeners( VCLEVENT_EDIT_MODIFY );
1113
1114 if ( pUpdateDataTimer )
1115 pUpdateDataTimer->Start();
1116 }
1117
IMPL_LINK(MultiLineEdit,ImpUpdateDataHdl,Timer *,EMPTYARG)1118 IMPL_LINK( MultiLineEdit, ImpUpdateDataHdl, Timer*, EMPTYARG )
1119 {
1120 UpdateData();
1121 return 0;
1122 }
1123
UpdateData()1124 void MultiLineEdit::UpdateData()
1125 {
1126 aUpdateDataHdlLink.Call( this );
1127 }
1128
SetModifyFlag()1129 void MultiLineEdit::SetModifyFlag()
1130 {
1131 pImpSvMEdit->SetModified( sal_True );
1132 }
1133
ClearModifyFlag()1134 void MultiLineEdit::ClearModifyFlag()
1135 {
1136 pImpSvMEdit->SetModified( sal_False );
1137 }
1138
IsModified() const1139 sal_Bool MultiLineEdit::IsModified() const
1140 {
1141 return pImpSvMEdit->IsModified();
1142 }
1143
EnableUpdateData(sal_uLong nTimeout)1144 void MultiLineEdit::EnableUpdateData( sal_uLong nTimeout )
1145 {
1146 if ( !nTimeout )
1147 DisableUpdateData();
1148 else
1149 {
1150 if ( !pUpdateDataTimer )
1151 {
1152 pUpdateDataTimer = new Timer;
1153 pUpdateDataTimer->SetTimeoutHdl( LINK( this, MultiLineEdit, ImpUpdateDataHdl ) );
1154 }
1155 pUpdateDataTimer->SetTimeout( nTimeout );
1156 }
1157 }
1158
SetReadOnly(sal_Bool bReadOnly)1159 void MultiLineEdit::SetReadOnly( sal_Bool bReadOnly )
1160 {
1161 pImpSvMEdit->SetReadOnly( bReadOnly );
1162 Edit::SetReadOnly( bReadOnly );
1163
1164 // #94921# ReadOnly can be overwritten in InitFromStyle() when WB not set.
1165 WinBits nStyle = GetStyle();
1166 if ( bReadOnly )
1167 nStyle |= WB_READONLY;
1168 else
1169 nStyle &= ~WB_READONLY;
1170 SetStyle( nStyle );
1171 }
1172
IsReadOnly() const1173 sal_Bool MultiLineEdit::IsReadOnly() const
1174 {
1175 return pImpSvMEdit->IsReadOnly();
1176 }
1177
SetMaxTextLen(xub_StrLen nMaxLen)1178 void MultiLineEdit::SetMaxTextLen( xub_StrLen nMaxLen )
1179 {
1180 pImpSvMEdit->SetMaxTextLen( nMaxLen );
1181 }
1182
GetMaxTextLen() const1183 xub_StrLen MultiLineEdit::GetMaxTextLen() const
1184 {
1185 return pImpSvMEdit->GetMaxTextLen();
1186 }
1187
ReplaceSelected(const String & rStr)1188 void MultiLineEdit::ReplaceSelected( const String& rStr )
1189 {
1190 pImpSvMEdit->InsertText( rStr );
1191 }
1192
DeleteSelected()1193 void MultiLineEdit::DeleteSelected()
1194 {
1195 pImpSvMEdit->InsertText( String() );
1196 }
1197
GetSelected() const1198 String MultiLineEdit::GetSelected() const
1199 {
1200 return pImpSvMEdit->GetSelected();
1201 }
1202
GetSelected(LineEnd aSeparator) const1203 String MultiLineEdit::GetSelected( LineEnd aSeparator ) const
1204 {
1205 return pImpSvMEdit->GetSelected( aSeparator );
1206 }
1207
Cut()1208 void MultiLineEdit::Cut()
1209 {
1210 pImpSvMEdit->Cut();
1211 }
1212
Copy()1213 void MultiLineEdit::Copy()
1214 {
1215 pImpSvMEdit->Copy();
1216 }
1217
Paste()1218 void MultiLineEdit::Paste()
1219 {
1220 pImpSvMEdit->Paste();
1221 }
1222
SetText(const String & rStr)1223 void MultiLineEdit::SetText( const String& rStr )
1224 {
1225 pImpSvMEdit->SetText( rStr );
1226 }
1227
GetText() const1228 String MultiLineEdit::GetText() const
1229 {
1230 return pImpSvMEdit->GetText();
1231 }
1232
GetText(LineEnd aSeparator) const1233 String MultiLineEdit::GetText( LineEnd aSeparator ) const
1234 {
1235 return pImpSvMEdit->GetText( aSeparator );
1236 }
1237
GetTextLines() const1238 String MultiLineEdit::GetTextLines() const
1239 {
1240 return pImpSvMEdit->GetTextLines();
1241 }
1242
GetTextLines(LineEnd aSeparator) const1243 String MultiLineEdit::GetTextLines( LineEnd aSeparator ) const
1244 {
1245 return pImpSvMEdit->GetTextLines( aSeparator );
1246 }
1247
Resize()1248 void MultiLineEdit::Resize()
1249 {
1250 pImpSvMEdit->Resize();
1251 }
1252
GetFocus()1253 void MultiLineEdit::GetFocus()
1254 {
1255 if ( pImpSvMEdit == NULL ) // might be called from within the dtor, when pImpSvMEdit == NULL is a valid state
1256 return;
1257
1258 Edit::GetFocus();
1259
1260 pImpSvMEdit->GetFocus();
1261 }
1262
1263
SetSelection(const Selection & rSelection)1264 void MultiLineEdit::SetSelection( const Selection& rSelection )
1265 {
1266 pImpSvMEdit->SetSelection( rSelection );
1267 }
1268
GetSelection() const1269 const Selection& MultiLineEdit::GetSelection() const
1270 {
1271 return pImpSvMEdit->GetSelection();
1272 }
1273
CalcMinimumSize() const1274 Size MultiLineEdit::CalcMinimumSize() const
1275 {
1276 Size aSz = pImpSvMEdit->CalcMinimumSize();
1277
1278 sal_Int32 nLeft, nTop, nRight, nBottom;
1279 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1280 aSz.Width() += nLeft+nRight;
1281 aSz.Height() += nTop+nBottom;
1282
1283 return aSz;
1284 }
1285
CalcAdjustedSize(const Size & rPrefSize) const1286 Size MultiLineEdit::CalcAdjustedSize( const Size& rPrefSize ) const
1287 {
1288 Size aSz = rPrefSize;
1289 sal_Int32 nLeft, nTop, nRight, nBottom;
1290 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1291
1292 // In der Hoehe auf ganze Zeilen justieren
1293
1294 long nHeight = aSz.Height() - nTop - nBottom;
1295 long nLineHeight = pImpSvMEdit->CalcSize( 1, 1 ).Height();
1296 long nLines = nHeight / nLineHeight;
1297 if ( nLines < 1 )
1298 nLines = 1;
1299
1300 aSz.Height() = nLines * nLineHeight;
1301 aSz.Height() += nTop+nBottom;
1302
1303 return aSz;
1304 }
1305
CalcSize(sal_uInt16 nColumns,sal_uInt16 nLines) const1306 Size MultiLineEdit::CalcSize( sal_uInt16 nColumns, sal_uInt16 nLines ) const
1307 {
1308 Size aSz = pImpSvMEdit->CalcSize( nColumns, nLines );
1309
1310 sal_Int32 nLeft, nTop, nRight, nBottom;
1311 ((Window*)this)->GetBorder( nLeft, nTop, nRight, nBottom );
1312 aSz.Width() += nLeft+nRight;
1313 aSz.Height() += nTop+nBottom;
1314 return aSz;
1315 }
1316
GetMaxVisColumnsAndLines(sal_uInt16 & rnCols,sal_uInt16 & rnLines) const1317 void MultiLineEdit::GetMaxVisColumnsAndLines( sal_uInt16& rnCols, sal_uInt16& rnLines ) const
1318 {
1319 pImpSvMEdit->GetMaxVisColumnsAndLines( rnCols, rnLines );
1320 }
1321
StateChanged(StateChangedType nType)1322 void MultiLineEdit::StateChanged( StateChangedType nType )
1323 {
1324 if( nType == STATE_CHANGE_ENABLE )
1325 {
1326 pImpSvMEdit->Enable( IsEnabled() );
1327 ImplInitSettings( sal_True, sal_False, sal_False );
1328 }
1329 else if( nType == STATE_CHANGE_READONLY )
1330 {
1331 pImpSvMEdit->SetReadOnly( IsReadOnly() );
1332 }
1333 else if ( nType == STATE_CHANGE_ZOOM )
1334 {
1335 pImpSvMEdit->GetTextWindow()->SetZoom( GetZoom() );
1336 ImplInitSettings( sal_True, sal_False, sal_False );
1337 Resize();
1338 }
1339 else if ( nType == STATE_CHANGE_CONTROLFONT )
1340 {
1341 ImplInitSettings( sal_True, sal_False, sal_False );
1342 Resize();
1343 Invalidate();
1344 }
1345 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1346 {
1347 ImplInitSettings( sal_False, sal_True, sal_False );
1348 Invalidate();
1349 }
1350 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1351 {
1352 ImplInitSettings( sal_False, sal_False, sal_True );
1353 Invalidate();
1354 }
1355 else if ( nType == STATE_CHANGE_STYLE )
1356 {
1357 pImpSvMEdit->InitFromStyle( GetStyle() );
1358 SetStyle( ImplInitStyle( GetStyle() ) );
1359 }
1360 else if ( nType == STATE_CHANGE_INITSHOW )
1361 {
1362 if( IsPaintTransparent() )
1363 {
1364 pImpSvMEdit->GetTextWindow()->SetPaintTransparent( sal_True );
1365 pImpSvMEdit->GetTextWindow()->SetBackground();
1366 pImpSvMEdit->GetTextWindow()->SetControlBackground();
1367 SetBackground();
1368 SetControlBackground();
1369 }
1370 }
1371
1372 Control::StateChanged( nType );
1373 }
1374
DataChanged(const DataChangedEvent & rDCEvt)1375 void MultiLineEdit::DataChanged( const DataChangedEvent& rDCEvt )
1376 {
1377 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1378 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1379 {
1380 ImplInitSettings( sal_True, sal_True, sal_True );
1381 Resize();
1382 Invalidate();
1383 }
1384 else
1385 Control::DataChanged( rDCEvt );
1386 }
1387
Draw(OutputDevice * pDev,const Point & rPos,const Size & rSize,sal_uLong nFlags)1388 void MultiLineEdit::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, sal_uLong nFlags )
1389 {
1390 ImplInitSettings( sal_True, sal_True, sal_True );
1391
1392 Point aPos = pDev->LogicToPixel( rPos );
1393 Size aSize = pDev->LogicToPixel( rSize );
1394 Font aFont = pImpSvMEdit->GetTextWindow()->GetDrawPixelFont( pDev );
1395 aFont.SetTransparent( sal_True );
1396 OutDevType eOutDevType = pDev->GetOutDevType();
1397
1398 pDev->Push();
1399 pDev->SetMapMode();
1400 pDev->SetFont( aFont );
1401 pDev->SetTextFillColor();
1402
1403 // Border/Background
1404 pDev->SetLineColor();
1405 pDev->SetFillColor();
1406 sal_Bool bBorder = !(nFlags & WINDOW_DRAW_NOBORDER ) && (GetStyle() & WB_BORDER);
1407 sal_Bool bBackground = !(nFlags & WINDOW_DRAW_NOBACKGROUND) && IsControlBackground();
1408 if ( bBorder || bBackground )
1409 {
1410 Rectangle aRect( aPos, aSize );
1411 if ( bBorder )
1412 {
1413 DecorationView aDecoView( pDev );
1414 aRect = aDecoView.DrawFrame( aRect, FRAME_DRAW_DOUBLEIN );
1415 }
1416 if ( bBackground )
1417 {
1418 pDev->SetFillColor( GetControlBackground() );
1419 pDev->DrawRect( aRect );
1420 }
1421 }
1422
1423 // Inhalt
1424 if ( ( nFlags & WINDOW_DRAW_MONO ) || ( eOutDevType == OUTDEV_PRINTER ) )
1425 pDev->SetTextColor( Color( COL_BLACK ) );
1426 else
1427 {
1428 if ( !(nFlags & WINDOW_DRAW_NODISABLE ) && !IsEnabled() )
1429 {
1430 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1431 pDev->SetTextColor( rStyleSettings.GetDisableColor() );
1432 }
1433 else
1434 {
1435 pDev->SetTextColor( GetTextColor() );
1436 }
1437 }
1438
1439 XubString aText = GetText();
1440 Size aTextSz( pDev->GetTextWidth( aText ), pDev->GetTextHeight() );
1441 sal_uLong nLines = (sal_uLong) (aSize.Height() / aTextSz.Height());
1442 if ( !nLines )
1443 nLines = 1;
1444 aTextSz.Height() = nLines*aTextSz.Height();
1445 long nOnePixel = GetDrawPixel( pDev, 1 );
1446 long nOffX = 3*nOnePixel;
1447 long nOffY = 2*nOnePixel;
1448
1449 // Clipping?
1450 if ( ( nOffY < 0 ) || ( (nOffY+aTextSz.Height()) > aSize.Height() ) || ( (nOffX+aTextSz.Width()) > aSize.Width() ) )
1451 {
1452 Rectangle aClip( aPos, aSize );
1453 if ( aTextSz.Height() > aSize.Height() )
1454 aClip.Bottom() += aTextSz.Height() - aSize.Height() + 1; // Damit HP-Drucker nicht 'weg-optimieren'
1455 pDev->IntersectClipRegion( aClip );
1456 }
1457
1458 TextEngine aTE;
1459 aTE.SetText( GetText() );
1460 aTE.SetMaxTextWidth( aSize.Width() );
1461 aTE.SetFont( aFont );
1462 aTE.SetTextAlign( pImpSvMEdit->GetTextWindow()->GetTextEngine()->GetTextAlign() );
1463 aTE.Draw( pDev, Point( aPos.X() + nOffX, aPos.Y() + nOffY ) );
1464
1465 pDev->Pop();
1466 }
1467
Notify(NotifyEvent & rNEvt)1468 long MultiLineEdit::Notify( NotifyEvent& rNEvt )
1469 {
1470 long nDone = 0;
1471 if( rNEvt.GetType() == EVENT_COMMAND )
1472 {
1473 nDone = pImpSvMEdit->HandleCommand( *rNEvt.GetCommandEvent() );
1474 }
1475 return nDone ? nDone : Edit::Notify( rNEvt );
1476 }
1477
PreNotify(NotifyEvent & rNEvt)1478 long MultiLineEdit::PreNotify( NotifyEvent& rNEvt )
1479 {
1480 long nDone = 0;
1481
1482 #if (OSL_DEBUG_LEVEL > 1) && defined(DBG_UTIL)
1483 if( rNEvt.GetType() == EVENT_KEYINPUT )
1484 {
1485 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1486 if ( ( rKEvent.GetKeyCode().GetCode() == KEY_W ) && rKEvent.GetKeyCode().IsMod1() && rKEvent.GetKeyCode().IsMod2() )
1487 {
1488 SetRightToLeft( !IsRightToLeft() );
1489 }
1490 }
1491 #endif
1492
1493 if( ( rNEvt.GetType() == EVENT_KEYINPUT ) && ( !GetTextView()->IsCursorEnabled() ) )
1494 {
1495 const KeyEvent& rKEvent = *rNEvt.GetKeyEvent();
1496 if ( !rKEvent.GetKeyCode().IsShift() && ( rKEvent.GetKeyCode().GetGroup() == KEYGROUP_CURSOR ) )
1497 {
1498 nDone = 1;
1499 TextSelection aSel = pImpSvMEdit->GetTextWindow()->GetTextView()->GetSelection();
1500 if ( aSel.HasRange() )
1501 {
1502 aSel.GetStart() = aSel.GetEnd();
1503 pImpSvMEdit->GetTextWindow()->GetTextView()->SetSelection( aSel );
1504 }
1505 else
1506 {
1507 switch ( rKEvent.GetKeyCode().GetCode() )
1508 {
1509 case KEY_UP:
1510 {
1511 if ( pImpSvMEdit->GetVScrollBar() )
1512 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEUP );
1513 }
1514 break;
1515 case KEY_DOWN:
1516 {
1517 if ( pImpSvMEdit->GetVScrollBar() )
1518 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1519 }
1520 break;
1521 case KEY_PAGEUP :
1522 {
1523 if ( pImpSvMEdit->GetVScrollBar() )
1524 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEUP );
1525 }
1526 break;
1527 case KEY_PAGEDOWN:
1528 {
1529 if ( pImpSvMEdit->GetVScrollBar() )
1530 pImpSvMEdit->GetVScrollBar()->DoScrollAction( SCROLL_PAGEDOWN );
1531 }
1532 break;
1533 case KEY_LEFT:
1534 {
1535 if ( pImpSvMEdit->GetHScrollBar() )
1536 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEUP );
1537 }
1538 break;
1539 case KEY_RIGHT:
1540 {
1541 if ( pImpSvMEdit->GetHScrollBar() )
1542 pImpSvMEdit->GetHScrollBar()->DoScrollAction( SCROLL_LINEDOWN );
1543 }
1544 break;
1545 case KEY_HOME:
1546 {
1547 if ( rKEvent.GetKeyCode().IsMod1() )
1548 pImpSvMEdit->GetTextWindow()->GetTextView()->
1549 SetSelection( TextSelection( TextPaM( 0, 0 ) ) );
1550 }
1551 break;
1552 case KEY_END:
1553 {
1554 if ( rKEvent.GetKeyCode().IsMod1() )
1555 pImpSvMEdit->GetTextWindow()->GetTextView()->
1556 SetSelection( TextSelection( TextPaM( 0xFFFF, 0xFFFF ) ) );
1557 }
1558 break;
1559 default:
1560 {
1561 nDone = 0;
1562 }
1563 }
1564 }
1565 }
1566 }
1567
1568 return nDone ? nDone : Edit::PreNotify( rNEvt );
1569 }
1570
1571 //
1572 // Internas fuer abgeleitete Klassen, z.B. TextComponent
1573
GetTextEngine() const1574 ExtTextEngine* MultiLineEdit::GetTextEngine() const
1575 {
1576 return pImpSvMEdit->GetTextWindow()->GetTextEngine();
1577 }
1578
GetTextView() const1579 ExtTextView* MultiLineEdit::GetTextView() const
1580 {
1581 return pImpSvMEdit->GetTextWindow()->GetTextView();
1582 }
1583
GetHScrollBar() const1584 ScrollBar* MultiLineEdit::GetHScrollBar() const
1585 {
1586 return pImpSvMEdit->GetHScrollBar();
1587 }
1588
1589
GetVScrollBar() const1590 ScrollBar* MultiLineEdit::GetVScrollBar() const
1591 {
1592 return pImpSvMEdit->GetVScrollBar();
1593 }
1594
EnableFocusSelectionHide(sal_Bool bHide)1595 void MultiLineEdit::EnableFocusSelectionHide( sal_Bool bHide )
1596 {
1597 pImpSvMEdit->GetTextWindow()->SetAutoFocusHide( bHide );
1598 }
1599
IsFocusSelectionHideEnabled() const1600 sal_Bool MultiLineEdit::IsFocusSelectionHideEnabled() const
1601 {
1602 return pImpSvMEdit->GetTextWindow()->IsAutoFocusHide();
1603 }
1604
1605
SetLeftMargin(sal_uInt16 n)1606 void MultiLineEdit::SetLeftMargin( sal_uInt16 n )
1607 {
1608 if ( GetTextEngine() )
1609 GetTextEngine()->SetLeftMargin( n );
1610 }
1611
GetLeftMargin() const1612 sal_uInt16 MultiLineEdit::GetLeftMargin() const
1613 {
1614 if ( GetTextEngine() )
1615 return GetTextEngine()->GetLeftMargin();
1616 else
1617 return 0;
1618 }
1619
SetRightToLeft(sal_Bool bRightToLeft)1620 void MultiLineEdit::SetRightToLeft( sal_Bool bRightToLeft )
1621 {
1622 if ( GetTextEngine() )
1623 {
1624 GetTextEngine()->SetRightToLeft( bRightToLeft );
1625 GetTextView()->ShowCursor();
1626 }
1627 }
1628
IsRightToLeft() const1629 sal_Bool MultiLineEdit::IsRightToLeft() const
1630 {
1631 sal_Bool bRightToLeft = sal_False;
1632
1633 if ( GetTextEngine() )
1634 bRightToLeft = GetTextEngine()->IsRightToLeft();
1635
1636 return bRightToLeft;
1637 }
1638
1639 // virtual
1640 ::css::uno::Reference< ::css::awt::XWindowPeer >
GetComponentInterface(sal_Bool bCreate)1641 MultiLineEdit::GetComponentInterface(sal_Bool bCreate)
1642 {
1643 ::css::uno::Reference< ::css::awt::XWindowPeer > xPeer(
1644 Edit::GetComponentInterface(false));
1645 if (!xPeer.is() && bCreate)
1646 {
1647 ::std::auto_ptr< VCLXMultiLineEdit > xEdit(new VCLXMultiLineEdit());
1648 xEdit->SetWindow(this);
1649 xPeer = xEdit.release();
1650 SetComponentInterface(xPeer);
1651 }
1652 return xPeer;
1653 }
1654 /*-- 11.08.2004 11:29:23---------------------------------------------------
1655
1656 -----------------------------------------------------------------------*/
DisableSelectionOnFocus()1657 void MultiLineEdit::DisableSelectionOnFocus()
1658 {
1659 pImpSvMEdit->GetTextWindow()->DisableSelectionOnFocus();
1660 }
1661