xref: /trunk/main/vcl/source/window/split.cxx (revision 9f62ea84)
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_vcl.hxx"
26 
27 #include <tools/rc.h>
28 #include <tools/poly.hxx>
29 
30 #include <vcl/event.hxx>
31 #include <vcl/split.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/syswin.hxx>
34 #include <vcl/taskpanelist.hxx>
35 #include <vcl/gradient.hxx>
36 #include <vcl/lineinfo.hxx>
37 
38 #include <rtl/instance.hxx>
39 
40 #include <window.h>
41 
42 namespace
43 {
44     struct ImplBlackWall
45         : public rtl::StaticWithInit<Wallpaper, ImplBlackWall> {
46         Wallpaper operator () () {
47             return Wallpaper(COL_BLACK);
48         }
49     };
50     struct ImplWhiteWall
51         : public rtl::StaticWithInit<Wallpaper, ImplWhiteWall> {
52         Wallpaper operator () () {
53             return Wallpaper(COL_LIGHTGRAY);
54         }
55     };
56 }
57 
58 // =======================================================================
59 
60 void Splitter::ImplInitSplitterData()
61 {
62     ImplGetWindowImpl()->mbSplitter        = sal_True;
63 	mpRefWin		  = NULL;
64 	mnSplitPos		  = 0;
65 	mnLastSplitPos	  = 0;
66 	mnStartSplitPos   = 0;
67 	mbDragFull		  = sal_False;
68     mbKbdSplitting    = sal_False;
69     mbInKeyEvent      = 0;
70     mnKeyboardStepSize = SPLITTER_DEFAULTSTEPSIZE;
71 }
72 
73 // -----------------------------------------------------------------------
74 
75 void Splitter::ImplInit( Window* pParent, WinBits nWinStyle )
76 {
77 	Window::ImplInit( pParent, nWinStyle, NULL );
78 
79 	mpRefWin = pParent;
80 
81 	const StyleSettings& rSettings = GetSettings().GetStyleSettings();
82 	long nA = rSettings.GetScrollBarSize();
83 	long nB = rSettings.GetSplitSize();
84 
85 	PointerStyle ePointerStyle;
86 
87 	if ( nWinStyle & WB_HSCROLL )
88 	{
89 		ePointerStyle = POINTER_HSPLIT;
90 		mbHorzSplit = sal_True;
91 		SetSizePixel( Size( nB, nA ) );
92 	}
93 	else
94 	{
95 		ePointerStyle = POINTER_VSPLIT;
96 		mbHorzSplit = sal_False;
97 		SetSizePixel( Size( nA, nB ) );
98 	}
99 
100 	SetPointer( Pointer( ePointerStyle ) );
101 
102     if( GetSettings().GetStyleSettings().GetFaceColor().IsDark() )
103 	    SetBackground( ImplWhiteWall::get() );
104     else
105 	    SetBackground( ImplBlackWall::get() );
106 
107     TaskPaneList *pTList = GetSystemWindow()->GetTaskPaneList();
108     pTList->AddWindow( this );
109 }
110 
111 // -----------------------------------------------------------------------
112 
113 void Splitter::ImplSplitMousePos( Point& rPos )
114 {
115 	if ( mbHorzSplit )
116 	{
117 		if ( rPos.X() > maDragRect.Right()-1 )
118 			rPos.X() = maDragRect.Right()-1;
119 		if ( rPos.X() < maDragRect.Left()+1 )
120 			rPos.X() = maDragRect.Left()+1;
121 	}
122 	else
123 	{
124 		if ( rPos.Y() > maDragRect.Bottom()-1 )
125 			rPos.Y() = maDragRect.Bottom()-1;
126 		if ( rPos.Y() < maDragRect.Top()+1 )
127 			rPos.Y() = maDragRect.Top()+1;
128 	}
129 }
130 
131 // -----------------------------------------------------------------------
132 
133 void Splitter::ImplDrawSplitter()
134 {
135 	Rectangle aInvRect( maDragRect );
136 
137 	if ( mbHorzSplit )
138 	{
139 		aInvRect.Left() 	= maDragPos.X() - 1;
140 		aInvRect.Right()	= maDragPos.X() + 1;
141 	}
142 	else
143 	{
144 		aInvRect.Top()		= maDragPos.Y() - 1;
145 		aInvRect.Bottom()	= maDragPos.Y() + 1;
146 	}
147 
148 	mpRefWin->InvertTracking( mpRefWin->PixelToLogic(aInvRect), SHOWTRACK_SPLIT );
149 }
150 
151 // -----------------------------------------------------------------------
152 
153 Splitter::Splitter( Window* pParent, WinBits nStyle ) :
154 	Window( WINDOW_SPLITTER )
155 {
156 	ImplInitSplitterData();
157 	ImplInit( pParent, nStyle );
158 }
159 
160 // -----------------------------------------------------------------------
161 
162 Splitter::Splitter( Window* pParent, const ResId& rResId ) :
163 	Window( WINDOW_SPLITTER )
164 {
165 	ImplInitSplitterData();
166 	rResId.SetRT( RSC_SPLITTER );
167 	WinBits nStyle = ImplInitRes( rResId );
168 	ImplInit( pParent, nStyle );
169 	ImplLoadRes( rResId );
170 
171 	if ( !(nStyle & WB_HIDE) )
172 		Show();
173 }
174 
175 // -----------------------------------------------------------------------
176 
177 Splitter::~Splitter()
178 {
179     TaskPaneList *pTList = GetSystemWindow()->GetTaskPaneList();
180     pTList->RemoveWindow( this );
181 }
182 
183 // -----------------------------------------------------------------------
184 
185 void Splitter::SetKeyboardStepSize( long nStepSize )
186 {
187     mnKeyboardStepSize = nStepSize;
188 }
189 
190 // -----------------------------------------------------------------------
191 
192 long Splitter::GetKeyboardStepSize() const
193 {
194     return mnKeyboardStepSize;
195 }
196 
197 // -----------------------------------------------------------------------
198 
199 Splitter* Splitter::ImplFindSibling()
200 {
201     // look for another splitter with the same parent but different orientation
202     Window *pWin = GetParent()->GetWindow( WINDOW_FIRSTCHILD );
203     Splitter *pSplitter = NULL;
204     while( pWin )
205     {
206         if( pWin->ImplIsSplitter() )
207         {
208             pSplitter = (Splitter*) pWin;
209             if( pSplitter != this && IsHorizontal() != pSplitter->IsHorizontal() )
210                 return pSplitter;
211         }
212         pWin = pWin->GetWindow( WINDOW_NEXT );
213     }
214     return NULL;
215 }
216 
217 // -----------------------------------------------------------------------
218 
219 sal_Bool Splitter::ImplSplitterActive()
220 {
221     // is splitter in document or at scrollbar handle ?
222 
223     sal_Bool bActive = sal_True;
224 	const StyleSettings& rSettings = GetSettings().GetStyleSettings();
225 	long nA = rSettings.GetScrollBarSize();
226 	long nB = rSettings.GetSplitSize();
227 
228     Size aSize = GetOutputSize();
229 	if ( mbHorzSplit )
230 	{
231         if( aSize.Width() == nB && aSize.Height() == nA )
232             bActive = sal_False;
233 	}
234 	else
235 	{
236         if( aSize.Width() == nA && aSize.Height() == nB )
237             bActive = sal_False;
238 	}
239     return bActive;
240 }
241 
242 // -----------------------------------------------------------------------
243 
244 void Splitter::MouseButtonDown( const MouseEvent& rMEvt )
245 {
246 	if ( rMEvt.GetClicks() == 2 )
247 	{
248 		if ( mnLastSplitPos != mnSplitPos )
249 		{
250 			StartSplit();
251 			Point aPos = rMEvt.GetPosPixel();
252 			if ( mbHorzSplit )
253 				aPos.X() = mnLastSplitPos;
254 			else
255 				aPos.Y() = mnLastSplitPos;
256 			ImplSplitMousePos( aPos );
257 			Splitting( aPos );
258 			ImplSplitMousePos( aPos );
259 			long nTemp = mnSplitPos;
260 			if ( mbHorzSplit )
261 				SetSplitPosPixel( aPos.X() );
262 			else
263 				SetSplitPosPixel( aPos.Y() );
264 			mnLastSplitPos = nTemp;
265 			Split();
266 			EndSplit();
267 		}
268 	}
269 	else
270 		StartDrag();
271 }
272 
273 // -----------------------------------------------------------------------
274 
275 void Splitter::Tracking( const TrackingEvent& rTEvt )
276 {
277 	if ( rTEvt.IsTrackingEnded() )
278 	{
279 		if ( !mbDragFull )
280 			ImplDrawSplitter();
281 
282 		if ( !rTEvt.IsTrackingCanceled() )
283 		{
284 			long nNewPos;
285 			if ( mbHorzSplit )
286 				nNewPos = maDragPos.X();
287 			else
288 				nNewPos = maDragPos.Y();
289 			if ( nNewPos != mnStartSplitPos )
290 			{
291 				SetSplitPosPixel( nNewPos );
292 				mnLastSplitPos = 0;
293 				Split();
294 			}
295 			EndSplit();
296 		}
297 		else if ( mbDragFull )
298 		{
299 			SetSplitPosPixel( mnStartSplitPos );
300 			Split();
301 		}
302 		mnStartSplitPos = 0;
303 	}
304 	else
305 	{
306 		//Point aNewPos = mpRefWin->ScreenToOutputPixel( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
307 		Point aNewPos = mpRefWin->NormalizedScreenToOutputPixel( OutputToNormalizedScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
308 		ImplSplitMousePos( aNewPos );
309 		Splitting( aNewPos );
310 		ImplSplitMousePos( aNewPos );
311 
312 		if ( mbHorzSplit )
313 		{
314 			if ( aNewPos.X() == maDragPos.X() )
315 				return;
316 		}
317 		else
318 		{
319 			if ( aNewPos.Y() == maDragPos.Y() )
320 				return;
321 		}
322 
323 		if ( mbDragFull )
324 		{
325 			maDragPos = aNewPos;
326 			long nNewPos;
327 			if ( mbHorzSplit )
328 				nNewPos = maDragPos.X();
329 			else
330 				nNewPos = maDragPos.Y();
331 			if ( nNewPos != mnSplitPos )
332 			{
333 				SetSplitPosPixel( nNewPos );
334 				mnLastSplitPos = 0;
335 				Split();
336 			}
337 
338 			GetParent()->Update();
339 		}
340 		else
341 		{
342 			ImplDrawSplitter();
343 			maDragPos = aNewPos;
344 			ImplDrawSplitter();
345 		}
346 	}
347 }
348 
349 // -----------------------------------------------------------------------
350 
351 void Splitter::ImplKbdTracking( KeyCode aKeyCode )
352 {
353     sal_uInt16 nCode = aKeyCode.GetCode();
354 	if ( nCode == KEY_ESCAPE || nCode == KEY_RETURN )
355 	{
356         if( !mbKbdSplitting )
357             return;
358         else
359             mbKbdSplitting = sal_False;
360 
361 		if ( nCode != KEY_ESCAPE )
362 		{
363 			long nNewPos;
364 			if ( mbHorzSplit )
365 				nNewPos = maDragPos.X();
366 			else
367 				nNewPos = maDragPos.Y();
368 			if ( nNewPos != mnStartSplitPos )
369 			{
370 				SetSplitPosPixel( nNewPos );
371 				mnLastSplitPos = 0;
372 				Split();
373 			}
374 		}
375 		else
376 		{
377 			SetSplitPosPixel( mnStartSplitPos );
378 			Split();
379 			EndSplit();
380 		}
381 		mnStartSplitPos = 0;
382 	}
383 	else
384 	{
385 		Point aNewPos;
386         Size aSize = mpRefWin->GetOutputSize();
387         Point aPos = GetPosPixel();
388         // depending on the position calc allows continous moves or snaps to row/columns
389         // continous mode is active when position is at the origin or end of the splitter
390         // otherwise snap mode is active
391         // default here is snap, holding shift sets continous mode
392         if( mbHorzSplit )
393             aNewPos = Point( ImplSplitterActive() ? aPos.X() : mnSplitPos, aKeyCode.IsShift() ? 0 : aSize.Height()/2);
394         else
395             aNewPos = Point( aKeyCode.IsShift() ? 0 : aSize.Width()/2, ImplSplitterActive() ? aPos.Y() : mnSplitPos );
396 
397         Point aOldWindowPos = GetPosPixel();
398 
399         int maxiter = 500;  // avoid endless loop
400         int delta=0;
401         int delta_step = mbHorzSplit  ? aSize.Width()/10 : aSize.Height()/10;
402 
403         // use the specified step size if it was set
404         if( mnKeyboardStepSize != SPLITTER_DEFAULTSTEPSIZE )
405             delta_step = mnKeyboardStepSize;
406 
407         while( maxiter-- && aOldWindowPos == GetPosPixel() )
408         {
409             // inc/dec position until application performs changes
410             // thus a single key press really moves the splitter
411             if( aKeyCode.IsShift() )
412                 delta++;
413             else
414                 delta += delta_step;
415 
416             switch( nCode )
417             {
418             case KEY_LEFT:
419                 aNewPos.X()-=delta;
420                 break;
421             case KEY_RIGHT:
422                 aNewPos.X()+=delta;
423                 break;
424             case KEY_UP:
425                 aNewPos.Y()-=delta;
426                 break;
427             case KEY_DOWN:
428                 aNewPos.Y()+=delta;
429                 break;
430             default:
431                 maxiter = 0;    // leave loop
432                 break;
433             }
434 		    ImplSplitMousePos( aNewPos );
435 		    Splitting( aNewPos );
436 		    ImplSplitMousePos( aNewPos );
437 
438 		    if ( mbHorzSplit )
439 		    {
440 			    if ( aNewPos.X() == maDragPos.X() )
441 				    continue;
442 		    }
443 		    else
444 		    {
445 			    if ( aNewPos.Y() == maDragPos.Y() )
446 				    continue;
447 		    }
448 
449 			maDragPos = aNewPos;
450 			long nNewPos;
451 			if ( mbHorzSplit )
452 				nNewPos = maDragPos.X();
453 			else
454 				nNewPos = maDragPos.Y();
455 			if ( nNewPos != mnSplitPos )
456 			{
457 				SetSplitPosPixel( nNewPos );
458 				mnLastSplitPos = 0;
459 				Split();
460 			}
461 			GetParent()->Update();
462         }
463 	}
464 }
465 
466 // -----------------------------------------------------------------------
467 
468 void Splitter::StartSplit()
469 {
470 	maStartSplitHdl.Call( this );
471 }
472 
473 // -----------------------------------------------------------------------
474 
475 void Splitter::Split()
476 {
477 	maSplitHdl.Call( this );
478 }
479 
480 // -----------------------------------------------------------------------
481 
482 void Splitter::EndSplit()
483 {
484 	if ( maEndSplitHdl.IsSet() )
485 		maEndSplitHdl.Call( this );
486 }
487 
488 // -----------------------------------------------------------------------
489 
490 void Splitter::Splitting( Point& /* rSplitPos */ )
491 {
492 }
493 
494 // -----------------------------------------------------------------------
495 
496 void Splitter::SetDragRectPixel( const Rectangle& rDragRect, Window* _pRefWin )
497 {
498 	maDragRect = rDragRect;
499 	if ( !_pRefWin )
500 		mpRefWin = GetParent();
501 	else
502 		mpRefWin = _pRefWin;
503 }
504 
505 // -----------------------------------------------------------------------
506 
507 void Splitter::SetSplitPosPixel( long nNewPos )
508 {
509 	mnSplitPos = nNewPos;
510 }
511 
512 // -----------------------------------------------------------------------
513 
514 void Splitter::SetLastSplitPosPixel( long nNewPos )
515 {
516 	mnLastSplitPos = nNewPos;
517 }
518 
519 // -----------------------------------------------------------------------
520 
521 void Splitter::StartDrag()
522 {
523 	if ( IsTracking() )
524 		return;
525 
526 	StartSplit();
527 
528 	// Tracking starten
529 	StartTracking();
530 
531 	// Start-Positon ermitteln
532 	maDragPos = mpRefWin->GetPointerPosPixel();
533 	ImplSplitMousePos( maDragPos );
534 	Splitting( maDragPos );
535 	ImplSplitMousePos( maDragPos );
536 	if ( mbHorzSplit )
537 		mnStartSplitPos = maDragPos.X();
538 	else
539 		mnStartSplitPos = maDragPos.Y();
540 
541 	mbDragFull = (Application::GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_SPLIT) != 0;
542 	if ( !mbDragFull )
543 		ImplDrawSplitter();
544 }
545 
546 
547 // -----------------------------------------------------------------------
548 
549 void Splitter::ImplStartKbdSplitting()
550 {
551     if( mbKbdSplitting )
552         return;
553 
554     mbKbdSplitting = sal_True;
555 
556 	StartSplit();
557 
558 	// determine start position
559     // because we have no mouse position we take either the position
560     // of the splitter window or the last split position
561     // the other coordinate is just the center of the reference window
562     Size aSize = mpRefWin->GetOutputSize();
563     Point aPos = GetPosPixel();
564     if( mbHorzSplit )
565         maDragPos = Point( ImplSplitterActive() ? aPos.X() : mnSplitPos, aSize.Height()/2 );
566     else
567         maDragPos = Point( aSize.Width()/2, ImplSplitterActive() ? aPos.Y() : mnSplitPos );
568 	ImplSplitMousePos( maDragPos );
569 	Splitting( maDragPos );
570 	ImplSplitMousePos( maDragPos );
571 	if ( mbHorzSplit )
572 		mnStartSplitPos = maDragPos.X();
573 	else
574 		mnStartSplitPos = maDragPos.Y();
575 }
576 
577 // -----------------------------------------------------------------------
578 
579 void Splitter::ImplRestoreSplitter()
580 {
581     // set splitter in the center of the ref window
582     StartSplit();
583     Size aSize = mpRefWin->GetOutputSize();
584     Point aPos = Point( aSize.Width()/2 , aSize.Height()/2);
585     if ( mnLastSplitPos != mnSplitPos && mnLastSplitPos > 5 )
586     {
587         // restore last pos if it was a useful position (>5)
588 	    if ( mbHorzSplit )
589 		    aPos.X() = mnLastSplitPos;
590 	    else
591 		    aPos.Y() = mnLastSplitPos;
592     }
593 
594     ImplSplitMousePos( aPos );
595     Splitting( aPos );
596     ImplSplitMousePos( aPos );
597     long nTemp = mnSplitPos;
598     if ( mbHorzSplit )
599 	    SetSplitPosPixel( aPos.X() );
600     else
601 	    SetSplitPosPixel( aPos.Y() );
602     mnLastSplitPos = nTemp;
603     Split();
604 	EndSplit();
605 }
606 
607 
608 // -----------------------------------------------------------------------
609 
610 void Splitter::GetFocus()
611 {
612     if( !ImplSplitterActive() )
613         ImplRestoreSplitter();
614 
615     Invalidate();
616 }
617 
618 // -----------------------------------------------------------------------
619 
620 void Splitter::LoseFocus()
621 {
622     if( mbKbdSplitting )
623     {
624         KeyCode aReturnKey( KEY_RETURN );
625         ImplKbdTracking( aReturnKey );
626         mbKbdSplitting = sal_False;
627     }
628     Invalidate();
629 }
630 
631 // -----------------------------------------------------------------------
632 
633 void Splitter::KeyInput( const KeyEvent& rKEvt )
634 {
635     if( mbInKeyEvent )
636         return;
637 
638     mbInKeyEvent = 1;
639 
640     Splitter *pSibling = ImplFindSibling();
641     KeyCode aKeyCode = rKEvt.GetKeyCode();
642     sal_uInt16 nCode = aKeyCode.GetCode();
643     switch ( nCode )
644     {
645         case KEY_UP:
646         case KEY_DOWN:
647             if( !mbHorzSplit )
648             {
649                 ImplStartKbdSplitting();
650                 ImplKbdTracking( aKeyCode );
651             }
652             else
653             {
654                 if( pSibling )
655                 {
656                     pSibling->GrabFocus();
657                     pSibling->KeyInput( rKEvt );
658                 }
659             }
660             break;
661         case KEY_RIGHT:
662         case KEY_LEFT:
663             if( mbHorzSplit )
664             {
665                 ImplStartKbdSplitting();
666                 ImplKbdTracking( aKeyCode );
667             }
668             else
669             {
670                 if( pSibling )
671                 {
672                     pSibling->GrabFocus();
673                     pSibling->KeyInput( rKEvt );
674                 }
675             }
676             break;
677 
678         case KEY_DELETE:
679             if( ImplSplitterActive() )
680             {
681                 if( mbKbdSplitting )
682                 {
683                     KeyCode aKey( KEY_ESCAPE );
684                     ImplKbdTracking( aKey );
685                 }
686 
687 			    StartSplit();
688 			    Point aPos;
689 			    if ( mbHorzSplit )
690 				    aPos.X() = 0;
691 			    else
692 				    aPos.Y() = 0;
693 			    ImplSplitMousePos( aPos );
694 			    Splitting( aPos );
695 			    ImplSplitMousePos( aPos );
696 			    long nTemp = mnSplitPos;
697 			    if ( mbHorzSplit )
698 				    SetSplitPosPixel( aPos.X() );
699 			    else
700 				    SetSplitPosPixel( aPos.Y() );
701 			    mnLastSplitPos = nTemp;
702 			    Split();
703 				EndSplit();
704 
705                 // Shift-Del deletes both splitters
706                 if( aKeyCode.IsShift() && pSibling )
707                     pSibling->KeyInput( rKEvt );
708 
709                 GrabFocusToDocument();
710             }
711             break;
712 
713         case KEY_ESCAPE:
714             if( mbKbdSplitting )
715                 ImplKbdTracking( aKeyCode );
716             else
717                 GrabFocusToDocument();
718             break;
719 
720         case KEY_RETURN:
721             ImplKbdTracking( aKeyCode );
722             GrabFocusToDocument();
723             break;
724         default:    // let any key input fix the splitter
725             Window::KeyInput( rKEvt );
726             GrabFocusToDocument();
727             break;
728     }
729     mbInKeyEvent = 0;
730 }
731 
732 // -----------------------------------------------------------------------
733 
734 long Splitter::Notify( NotifyEvent& rNEvt )
735 {
736     return Window::Notify( rNEvt );
737 }
738 
739 // -----------------------------------------------------------------------
740 
741 void Splitter::DataChanged( const DataChangedEvent& rDCEvt )
742 {
743     Window::DataChanged( rDCEvt );
744     if( rDCEvt.GetType() == DATACHANGED_SETTINGS )
745     {
746         Color oldFaceColor = ((AllSettings *) rDCEvt.GetData())->GetStyleSettings().GetFaceColor();
747         Color newFaceColor = Application::GetSettings().GetStyleSettings().GetFaceColor();
748         if( oldFaceColor.IsDark() != newFaceColor.IsDark() )
749         {
750             if( newFaceColor.IsDark() )
751 	            SetBackground( ImplWhiteWall::get() );
752             else
753 	            SetBackground( ImplBlackWall::get() );
754         }
755     }
756 }
757 
758 // -----------------------------------------------------------------------
759 
760 void Splitter::Paint( const Rectangle& rPaintRect )
761 {
762     if( HasFocus() || mbKbdSplitting )
763     {
764         Color oldFillCol = GetFillColor();
765         Color oldLineCol = GetLineColor();
766 
767         SetLineColor();
768         SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
769         DrawRect( rPaintRect );
770 
771         Color aSelectionBorderCol( GetSettings().GetStyleSettings().GetActiveColor() );
772         SetFillColor( aSelectionBorderCol );
773         SetLineColor();
774 
775 	    Polygon aPoly( rPaintRect );
776 		PolyPolygon aPolyPoly( aPoly );
777 		DrawTransparent( aPolyPoly, 85 );
778 
779         SetLineColor( aSelectionBorderCol );
780         SetFillColor();
781 
782         if( mbKbdSplitting )
783         {
784             LineInfo aInfo( LINE_DASH );
785             //aInfo.SetDashLen( 2 );
786             //aInfo.SetDashCount( 1 );
787             aInfo.SetDistance( 1 );
788             aInfo.SetDotLen( 2 );
789             aInfo.SetDotCount( 1 );
790 
791             DrawPolyLine( aPoly, aInfo );
792         }
793         else
794             DrawRect( rPaintRect );
795 
796         SetFillColor( oldFillCol);
797         SetLineColor( oldLineCol);
798     }
799     else
800     {
801         Window::Paint( rPaintRect );
802     }
803 }
804