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