xref: /trunk/main/sc/source/ui/inc/tabview.hxx (revision 1277c5ae2e150303b6627eb4b54e336d0bb4e548)
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 #ifndef SC_TABVIEW_HXX
23 #define SC_TABVIEW_HXX
24 
25 #include <vcl/scrbar.hxx>
26 
27 //REMOVE    #ifndef SO2_DECL_SVINPLACECLIENT_DEFINED
28 //REMOVE    #define SO2_DECL_SVINPLACECLIENT_DEFINED
29 //REMOVE    SO2_DECL_REF(SvInPlaceClient)
30 //REMOVE    #endif
31 
32 #include <sfx2/ipclient.hxx>
33 
34 #include "viewutil.hxx"
35 #include "select.hxx"
36 
37 class ScEditEngineDefaulter;
38 class ScGridWindow;
39 class ScOutlineWindow;
40 class ScRowBar;
41 class ScColBar;
42 class ScTabControl;
43 class ScTabViewShell;
44 class SfxPrinter;
45 class ScDrawView;
46 class SvBorder;
47 class FuPoor;
48 class Splitter;
49 class ScTabSplitter;
50 class SdrView;
51 class SdrObject;
52 class ScHintWindow;
53 class ScPageBreakData;
54 class ScHighlightRanges;
55 struct ChartSelectionInfo;
56 class SdrHdlList;
57 
58 namespace com { namespace sun { namespace star {
59 namespace chart2 { namespace data {
60     struct HighlightedRange;
61 }}}}}
62 
63 #define SPLIT_HANDLE_SIZE   3
64 #define SC_FORCEMODE_NONE   0xff
65 
66 // ---------------------------------------------------------------------------
67 // Hilfs-Fenster
68 
69 class ScCornerButton : public Window
70 {
71 private:
72     ScViewData*     pViewData;
73 
74 protected:
75     virtual void    Paint( const Rectangle& rRect );
76     virtual void    Resize();
77     virtual void    MouseButtonDown( const MouseEvent& rMEvt );
78 public:
79                     ScCornerButton( Window* pParent, ScViewData* pData );
80                     ~ScCornerButton();
81 
82     virtual void    StateChanged( StateChangedType nType );
83     virtual void    DataChanged( const DataChangedEvent& rDCEvt );
84 };
85 
86 // ---------------------------------------------------------------------------
87 
88 class ScTabView
89 {
90 private:
91     Window*             pFrameWin;              // als erstes !!!
92     ScViewData          aViewData;              // muss ganz vorne stehen !
93 
94     ScViewSelectionEngine*  pSelEngine;
95     ScViewFunctionSet       aFunctionSet;
96 
97     ScHeaderSelectionEngine* pHdrSelEng;
98     ScHeaderFunctionSet      aHdrFunc;
99 
100     SfxInPlaceClient*   pIPClient;
101 
102     ScDrawView*         pDrawView;
103 
104     Size                aFrameSize;             // wie bei DoResize uebergeben
105     Point               aBorderPos;
106 
107     sal_Bool                bDrawSelMode;       // nur Zeichenobjekte selektieren ?
108 
109     FuPoor*             pDrawActual;
110     FuPoor*             pDrawOld;
111 
112     ScGridWindow*       pGridWin[4];
113     ScColBar*           pColBar[2];
114     ScRowBar*           pRowBar[2];
115     ScOutlineWindow*    pColOutline[2];
116     ScOutlineWindow*    pRowOutline[2];
117     ScTabSplitter*      pHSplitter;
118     ScTabSplitter*      pVSplitter;
119     ScTabControl*       pTabControl;
120     ScrollBar           aVScrollTop;
121     ScrollBar           aVScrollBottom;         // anfangs sichtbar
122     ScrollBar           aHScrollLeft;           // anfangs sichtbar
123     ScrollBar           aHScrollRight;
124     ScCornerButton      aCornerButton;
125     ScCornerButton      aTopButton;
126     ScrollBarBox        aScrollBarBox;
127 
128     ScHintWindow*       pInputHintWindow;       // Eingabemeldung bei Gueltigkeit
129 
130     ScPageBreakData*    pPageBreakData;         // fuer Seitenumbruch-Modus
131     ScHighlightRanges*  pHighlightRanges;
132 
133     ScDocument*         pBrushDocument;         // cell formats for format paint brush
134     SfxItemSet*         pDrawBrushSet;          // drawing object attributes for paintbrush
135     sal_Bool                bLockPaintBrush;    // keep for more than one use?
136 
137     Timer               aScrollTimer;
138     ScGridWindow*       pTimerWindow;
139     MouseEvent          aTimerMEvt;
140 
141     sal_uLong               nTipVisible;
142 
143     sal_Bool                bDragging;              // fuer Scrollbars
144     long                nPrevDragPos;
145 
146     sal_Bool                bIsBlockMode;       // Block markieren
147     sal_Bool                bBlockNeg;          // wird Markierung aufgehoben?
148     sal_Bool                bBlockCols;         // werden ganze Spalten markiert?
149     sal_Bool                bBlockRows;         // werden ganze Zeilen markiert?
150 
151     SCCOL               nBlockStartX;
152     SCCOL               nBlockStartXOrig;
153     SCCOL               nBlockEndX;
154 
155     SCROW               nBlockStartY;
156     SCROW               nBlockStartYOrig;
157     SCROW               nBlockEndY;
158 
159     SCTAB               nBlockStartZ;
160     SCTAB               nBlockEndZ;
161 
162     SCCOL               nOldCurX;
163     SCROW               nOldCurY;
164 
165     double              mfPendingTabBarWidth; // Tab bar width relative to frame window width.
166 
167     sal_Bool                bMinimized;
168     sal_Bool                bInUpdateHeader;
169     sal_Bool                bInActivatePart;
170     sal_Bool                bInZoomUpdate;
171     sal_Bool                bMoveIsShift;
172     sal_Bool                bNewStartIfMarking;
173 
174     void            Init();
175 
176     void            DoAddWin( ScGridWindow* pWin );
177 
178     void            InitScrollBar( ScrollBar& rScrollBar, long nMaxVal );
179     DECL_LINK(      ScrollHdl, ScrollBar* );
180     DECL_LINK(      EndScrollHdl, ScrollBar* );
181 
182     DECL_LINK(      SplitHdl, Splitter* );
183     void            DoHSplit(long nSplitPos);
184     void            DoVSplit(long nSplitPos);
185 
186     DECL_LINK(      TimerHdl, Timer* );
187 
188     void            UpdateVarZoom();
189 
190     void            UpdateVisibleRange();
191 
192     static void     SetScrollBar( ScrollBar& rScroll, long nRangeMax, long nVisible, long nPos, sal_Bool bLayoutRTL );
193     static long     GetScrollBarPos( ScrollBar& rScroll, sal_Bool bLayoutRTL );
194 
195 protected:
196     void            UpdateHeaderWidth( const ScVSplitPos* pWhich = NULL,
197                                         const SCROW* pPosY = NULL );
198 
199     void            HideTip();
200     void            ShowRefTip();
201 
202     void            ZoomChanged();
203     void            UpdateShow();
204     void            GetBorderSize( SvBorder& rBorder, const Size& rSize );
205 
206     void            ResetDrawDragMode();
207     sal_Bool            IsDrawTextEdit() const;
208     void            DrawEnableAnim(sal_Bool bSet);
209     //HMHvoid           DrawShowMarkHdl(sal_Bool bShow);
210 
211     void            MakeDrawView( sal_uInt8 nForceDesignMode = SC_FORCEMODE_NONE );
212 
213     void            HideNoteMarker();
214 
215     void            UpdateIMap( SdrObject* pObj );
216 
217 public:
218                     ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell );
219 //UNUSED2009-05     ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell );
220                     ~ScTabView();
221 
222     void            MakeDrawLayer();
223 
224     void            HideListBox();
225 
HasHintWindow() const226     sal_Bool            HasHintWindow() const   { return pInputHintWindow != NULL; }
227     void            RemoveHintWindow();
228     void            TestHintWindow();
229 
230     DECL_LINK(      TabBarResize, void* );
231     /** Sets an absolute tab bar width (in pixels). */
232     void            SetTabBarWidth( long nNewWidth );
233     /** Sets a relative tab bar width.
234         @param fRelTabBarWidth  Tab bar width relative to frame window width (0.0 ... 1.0). */
235     void            SetRelTabBarWidth( double fRelTabBarWidth );
236     /** Sets a relative tab bar width. Tab bar is resized again in next DoResize().
237         @param fRelTabBarWidth  Tab bar width relative to frame window width (0.0 ... 1.0). */
238     void            SetPendingRelTabBarWidth( double fRelTabBarWidth );
239     /** Returns the current tab bar width in pixels. */
240     long            GetTabBarWidth() const;
241     /** Returns the current tab bar width relative to the frame window width (0.0 ... 1.0). */
242     double          GetRelTabBarWidth() const;
243     /** Returns the pending tab bar width relative to the frame window width (0.0 ... 1.0). */
244     double          GetPendingRelTabBarWidth() const;
245 
246     void            DoResize( const Point& rOffset, const Size& rSize, sal_Bool bInner = sal_False );
247     void            RepeatResize( sal_Bool bUpdateFix = sal_True );
248     void            UpdateFixPos();
249     Point           GetGridOffset() const;
250 
IsDrawSelMode() const251     sal_Bool            IsDrawSelMode() const       { return bDrawSelMode; }
SetDrawSelMode(sal_Bool bNew)252     void            SetDrawSelMode(sal_Bool bNew)   { bDrawSelMode = bNew; }
253 
SetDrawFuncPtr(FuPoor * pFuncPtr)254     void            SetDrawFuncPtr(FuPoor* pFuncPtr)    { pDrawActual = pFuncPtr; }
SetDrawFuncOldPtr(FuPoor * pFuncPtr)255     void            SetDrawFuncOldPtr(FuPoor* pFuncPtr) { pDrawOld = pFuncPtr; }
GetDrawFuncPtr()256     FuPoor*         GetDrawFuncPtr()                    { return pDrawActual; }
GetDrawFuncOldPtr()257     FuPoor*         GetDrawFuncOldPtr()                 { return pDrawOld; }
258 
259     void            DrawDeselectAll();
260     void            DrawMarkListHasChanged();
261     void            UpdateAnchorHandles();
262 //UNUSED2008-05 String          GetSelectedChartName() const;
263 
GetPageBreakData()264     ScPageBreakData* GetPageBreakData()     { return pPageBreakData; }
GetHighlightRanges()265     ScHighlightRanges* GetHighlightRanges() { return pHighlightRanges; }
266 
267     void            UpdatePageBreakData( sal_Bool bForcePaint = sal_False );
268 
269     void            DrawMarkRect( const Rectangle& rRect );
270 
GetViewData()271     ScViewData*         GetViewData()       { return &aViewData; }
GetViewData() const272     const ScViewData*   GetViewData() const { return &aViewData; }
273 
GetFunctionSet()274     ScViewFunctionSet*      GetFunctionSet()    { return &aFunctionSet; }
GetSelEngine()275     ScViewSelectionEngine*  GetSelEngine()      { return pSelEngine; }
276 
277     sal_Bool            SelMouseButtonDown( const MouseEvent& rMEvt );
278 
GetScDrawView()279     ScDrawView*     GetScDrawView()         { return pDrawView; }
280     SdrView*        GetSdrView();           // gegen CLOKs
281 
IsMinimized() const282     sal_Bool            IsMinimized() const     { return bMinimized; }
283 
284     // bSameTabButMoved = true if the same sheet as before is activated, used after moving/copying/inserting/deleting a sheet
285     void            TabChanged( bool bSameTabButMoved = false );
286     void            SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll );
287     SC_DLLPUBLIC void   RefreshZoom();
288     void            SetPagebreakMode( sal_Bool bSet );
289 
290     void            UpdateLayerLocks();
291 
292     void            UpdateDrawTextOutliner();
293     void            DigitLanguageChanged();
294 
295     void            UpdateInputLine();
296 
297     void            InitRefMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, ScRefType eType,
298                                     sal_Bool bPaint = sal_True );
299     void            DoneRefMode( sal_Bool bContinue = sal_False );
300     void            UpdateRef( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ );
301     void            StopRefMode();
302 
303 //UNUSED2008-05 void            EndSelection();
304     void            StopMarking();
305     void            FakeButtonUp( ScSplitPos eWhich );
306 
307     Window*         GetActiveWin();
308     Window*         GetWindowByPos( ScSplitPos ePos );
309 
310     ScSplitPos      FindWindow( Window* pWindow ) const;
311 
312     void            SetActivePointer( const Pointer& rPointer );
313 //UNUSED2008-05 void            SetActivePointer( const ResId& rId );
314 
315     void            ActiveGrabFocus();
316 //UNUSED2008-05 void            ActiveCaptureMouse();
317 //UNUSED2008-05 void            ActiveReleaseMouse();
318 //UNUSED2008-05 Point           ActivePixelToLogic( const Point& rDevicePoint );
319 
320     void            ClickCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bControl );
321 
322     SC_DLLPUBLIC void           SetCursor( SCCOL nPosX, SCROW nPosY, sal_Bool bNew = sal_False );
323 
324     SC_DLLPUBLIC void           CellContentChanged();
325     void            SelectionChanged();
326     void            CursorPosChanged();
327     void            UpdateInputContext();
328 
329     void            CheckSelectionTransfer();
330 
331     void            InvertHorizontal( ScVSplitPos eWhich, long nDragPos );
332     void            InvertVertical( ScHSplitPos eWhich, long nDragPos );
333 
334     Point           GetInsertPos();
335 
336     Point           GetChartInsertPos( const Size& rSize, const ScRange& rCellRange );
337     Point           GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart );
338 
339     void            UpdateAutoFillMark();
340 
341     void            HideCursor();               // nur aktiver Teil
342     void            ShowCursor();
343     void            HideAllCursors();
344     void            ShowAllCursors();
345 
346     void            AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
347                                     const ScSplitPos* pWhich = NULL );
348 
349     SvxZoomType     GetZoomType() const;
350     void            SetZoomType( SvxZoomType eNew, sal_Bool bAll );
351     sal_uInt16          CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom );
352 
353 //  void            CalcZoom( SvxZoomType eType, sal_uInt16& rZoom, SCCOL& rCol, SCROW& rRow );
354 
355     sal_Bool        HasPageFieldDataAtCursor() const;
356     void            StartDataSelect();
357 
358                     //  MoveCursorAbs       - absolut
359                     //  MoveCursorRel       - einzelne Zellen
360                     //  MoveCursorPage      - Bildschirmseite
361                     //  MoveCursorArea      - Datenblock
362                     //  MoveCursorEnd       - links oben / benutzter Bereich
363 
364     SC_DLLPUBLIC void           MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
365                                     sal_Bool bShift, sal_Bool bControl,
366                                     sal_Bool bKeepOld = sal_False, sal_Bool bKeepSel = sal_False );
367     void            MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
368                                     sal_Bool bShift, sal_Bool bKeepSel = sal_False );
369     void            MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
370                                     sal_Bool bShift, sal_Bool bKeepSel = sal_False );
371     void            MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
372                                     sal_Bool bShift, sal_Bool bKeepSel = sal_False );
373     void            MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
374                                     sal_Bool bShift, sal_Bool bKeepSel = sal_False );
375     void            MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, sal_Bool bShift );
376 
377     void            MoveCursorEnter( sal_Bool bShift );     // Shift fuer Richtung (kein Markieren)
378 
379     sal_Bool        MoveCursorKeyInput( const KeyEvent& rKeyEvent );
380 
381     void            FindNextUnprot( sal_Bool bShift, sal_Bool bInSelection = sal_True );
382 
383     void            SetNewStartIfMarking();
384 
385     // bSameTabButMoved = true if the same sheet as before is activated, used after moving/copying/inserting/deleting a sheet
386     SC_DLLPUBLIC void SetTabNo( SCTAB nTab, sal_Bool bNew = sal_False, sal_Bool bExtendSelection = sal_False, bool bSameTabButMoved = false );
387     void            SelectNextTab( short nDir, sal_Bool bExtendSelection = sal_False );
388 
389     void            ActivateView( sal_Bool bActivate, sal_Bool bFirst );
390     void            ActivatePart( ScSplitPos eWhich );
IsInActivatePart() const391     sal_Bool            IsInActivatePart() const    { return bInActivatePart; }
392 
393     void            SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt );
394     void            ResetTimer();
395 
396     void            ScrollX( long nDeltaX, ScHSplitPos eWhich, sal_Bool bUpdBars = sal_True );
397     void            ScrollY( long nDeltaY, ScVSplitPos eWhich, sal_Bool bUpdBars = sal_True );
398     SC_DLLPUBLIC void           ScrollLines( long nDeltaX, long nDeltaY );              // aktives
399 
400     sal_Bool            ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos );
401 
402     void            ScrollToObject( SdrObject* pDrawObj );
403     void            MakeVisible( const Rectangle& rHMMRect );
404 
405                                     // Zeichnen
406 
407     void            InvertBlockMark(SCCOL nBlockStartX, SCROW nBlockStartY,
408                                 SCCOL nBlockEndX, SCROW nBlockEndY);
409 
410 //UNUSED2008-05 void            DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
411 //UNUSED2008-05                               ScSplitPos ePos );
412 //UNUSED2008-05 void            PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab );
413 //UNUSED2008-05 void            PaintLeftRow( SCROW nRow );
414 //UNUSED2008-05 void            PaintTopCol( SCCOL nCol );
415 
416     void            PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
417                                         ScUpdateMode eMode = SC_UPDATE_ALL );
418 
419     void            PaintGrid();
420 
421     void            PaintTopArea( SCCOL nStartCol, SCCOL nEndCol );
422     void            PaintTop();
423 
424     void            PaintLeftArea( SCROW nStartRow, SCROW nEndRow );
425     void            PaintLeft();
426 
427     sal_Bool            PaintExtras();
428 
429     void            RecalcPPT();
430 
431     void            CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress);
432 
433     void            UpdateSelectionOverlay();
434     void            UpdateShrinkOverlay();
435     void            UpdateAllOverlays();
436 
437     void            UpdateFormulas();
438     void            InterpretVisible();
439     void            CheckNeedsRepaint();
440 
441     void            PaintRangeFinder( long nNumber = -1 );
442     void            AddHighlightRange( const ScRange& rRange, const Color& rColor );
443     void            ClearHighlightRanges();
444 
445     void            DoChartSelection( const ::com::sun::star::uno::Sequence<
446                                       ::com::sun::star::chart2::data::HighlightedRange > & rHilightRanges );
447 
448     long            GetGridWidth( ScHSplitPos eWhich );
449     long            GetGridHeight( ScVSplitPos eWhich );
450 
451     void            UpdateScrollBars();
452     void            SetNewVisArea();
453 
454     void            InvalidateAttribs();
455 
456     void            MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow );
457     void            KillEditView( sal_Bool bNoPaint );
458     void            UpdateEditView();
459 
460                                     //  Bloecke
461 
462     void            SelectAll( sal_Bool bContinue = sal_False );
463     void            SelectAllTables();
464     void            DeselectAllTables();
465 
466     void            MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
467                                 sal_Bool bCols = sal_False, sal_Bool bRows = sal_False, sal_Bool bCellSelection = sal_False );
468     void            InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
469                                     sal_Bool bTestNeg = sal_False,
470                                     sal_Bool bCols = sal_False, sal_Bool bRows = sal_False, sal_Bool bForceNeg = sal_False );
471     void            InitOwnBlockMode();
472     void            DoneBlockMode( sal_Bool bContinue = sal_False );
473 
IsBlockMode() const474     sal_Bool            IsBlockMode() const     { return bIsBlockMode; }
475 
476     void            MarkColumns();
477     void            MarkRows();
478     void            MarkDataArea( sal_Bool bIncludeCursor = sal_True );
479     void            MarkMatrixFormula();
480     void            Unmark();
481 
482     void            MarkRange( const ScRange& rRange, sal_Bool bSetCursor = sal_True, sal_Bool bContinue = sal_False );
483 
484     sal_Bool            IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
485 
486     void            PaintMarks( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
487     void            PaintBlock( sal_Bool bReset = sal_False );
488 
489     void            SetMarkData( const ScMarkData& rNew );
490     void            MarkDataChanged();
491 
492     void            LockModifiers( sal_uInt16 nModifiers );
493     sal_uInt16          GetLockedModifiers() const;
494     void            ViewOptionsHasChanged( sal_Bool bHScrollChanged,
495                                             sal_Bool bGraphicsChanged = sal_False);
496 
497     Point           GetMousePosPixel();
498 
499     void            SnapSplitPos( Point& rScreenPosPixel );
500     void            FreezeSplitters( sal_Bool bFreeze );
501     void            RemoveSplit();
502     void            SplitAtCursor();
503     void            SplitAtPixel( const Point& rPixel, sal_Bool bHor, sal_Bool bVer );
504     void            InvalidateSplit();
505 
506     void            ErrorMessage( sal_uInt16 nGlobStrId );
507     Window*         GetParentOrChild( sal_uInt16 nChildId );
508 
509     void            EnableRefInput(sal_Bool bFlag=sal_True);
510 
GetFrameWin() const511     Window*         GetFrameWin() const { return pFrameWin; }
512 
HasPaintBrush() const513     sal_Bool            HasPaintBrush() const           { return pBrushDocument || pDrawBrushSet; }
GetBrushDocument() const514     ScDocument*     GetBrushDocument() const        { return pBrushDocument; }
GetDrawBrushSet() const515     SfxItemSet*     GetDrawBrushSet() const         { return pDrawBrushSet; }
IsPaintBrushLocked() const516     sal_Bool            IsPaintBrushLocked() const      { return bLockPaintBrush; }
517     void            SetBrushDocument( ScDocument* pNew, sal_Bool bLock );
518     void            SetDrawBrushSet( SfxItemSet* pNew, sal_Bool bLock );
519     void            ResetBrushDocument();
520 };
521 
522 #endif
523 
524 /* vim: set noet sw=4 ts=4: */
525