xref: /AOO41X/main/vcl/source/window/split.cxx (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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