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