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