summaryrefslogtreecommitdiff
path: root/svtools/source/control/ruler.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/control/ruler.cxx')
-rw-r--r--svtools/source/control/ruler.cxx3064
1 files changed, 3064 insertions, 0 deletions
diff --git a/svtools/source/control/ruler.cxx b/svtools/source/control/ruler.cxx
new file mode 100644
index 000000000000..6124f5f8b042
--- /dev/null
+++ b/svtools/source/control/ruler.cxx
@@ -0,0 +1,3064 @@
+/*************************************************************************
+ *
+ * $RCSfile: ruler.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:58:57 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#ifndef _INTN_HXX
+#include <tools/intn.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVAPP_HXX
+#ifdef VCL
+#include <vcl/svapp.hxx>
+#else
+#include <vcl/svapp.hxx>
+#endif
+#endif
+#ifndef _POLY_HXX
+#include <vcl/poly.hxx>
+#endif
+
+#define _SV_RULER_CXX
+#define private public
+#include <ruler.hxx>
+
+// =======================================================================
+
+#define RULER_OFF 2
+#define RULER_TEXTOFF 2
+#define RULER_RESIZE_OFF 4
+#define RULER_LINE_WIDTH 7
+#define RULER_MIN_SIZE 3
+
+#define RULER_TICK1_WIDTH 1
+#define RULER_TICK2_WIDTH 3
+#define RULER_TICK3_WIDTH 5
+
+#define RULER_VAR_SIZE 8
+
+#define RULER_TAB_HEIGHT2 2
+#define RULER_TAB_WIDTH2 2
+#define RULER_TAB_CWIDTH 8
+#define RULER_TAB_CWIDTH2 4
+#define RULER_TAB_CWIDTH3 4
+#define RULER_TAB_CWIDTH4 2
+#define RULER_TAB_DHEIGHT 4
+#define RULER_TAB_DHEIGHT2 1
+#define RULER_TAB_DWIDTH 5
+#define RULER_TAB_DWIDTH2 3
+#define RULER_TAB_DWIDTH3 3
+#define RULER_TAB_DWIDTH4 1
+
+#define RULER_UPDATE_LINES 0x01
+#define RULER_UPDATE_DRAW 0x02
+
+#define RULER_CLIP 150
+
+// =======================================================================
+
+#define RULER_UNIT_MM 0
+#define RULER_UNIT_CM 1
+#define RULER_UNIT_M 2
+#define RULER_UNIT_KM 3
+#define RULER_UNIT_INCH 4
+#define RULER_UNIT_FOOT 5
+#define RULER_UNIT_MILE 6
+#define RULER_UNIT_POINT 7
+#define RULER_UNIT_PICA 8
+#define RULER_UNIT_COUNT 9
+
+struct ImplRulerUnitData
+{
+ MapUnit eMapUnit; // MAP_UNIT zum Umrechnen
+ long nTickUnit; // Teiler fuer Einheit
+ long nTick1; // Schrittweite
+ long nTick2; // Tick fuer halbe Werte
+ long nTick3; // Tick fuer Zahlenausgabe
+ long n100THMM; // Teiler fuer Einheit
+ USHORT nUnitDigits; // Anzahl Nachkommastellen
+ sal_Char aUnitStr[8]; // Einheiten-String
+};
+
+static ImplRulerUnitData aImplRulerUnitTab[RULER_UNIT_COUNT] =
+{
+{ MAP_100TH_MM, 100, 25, 50, 100, 100, 3, " mm" }, // MM
+{ MAP_100TH_MM, 1000, 250, 500, 1000, 1000, 3, " cm" }, // CM
+{ MAP_MM, 1000, 250, 500, 1000, 10000, 4, " m" }, // M
+{ MAP_CM, 100000, 25000, 50000, 100000, 100000, 6, " km" }, // KM
+{ MAP_100TH_INCH, 100, 10, 50, 100, 2540, 3, "\"" }, // INCH
+{ MAP_100TH_INCH, 1200, 120, 600, 1200, 30480, 3, "'" }, // FOOT
+{ MAP_10TH_INCH, 633600, 63360, 316800, 633600, 1609344, 4, " miles" }, // MILE
+{ MAP_POINT, 1, 12, 12, 36, 353, 2, " pt" }, // POINT
+{ MAP_100TH_MM, 423, 423, 423, 846, 423, 3, " pi" } // PICA
+};
+
+// =======================================================================
+
+struct ImplRulerHitTest
+{
+ long nPos;
+ RulerType eType;
+ USHORT nAryPos;
+ USHORT mnDragSize;
+ BOOL bSize;
+ BOOL bSizeBar;
+};
+
+// =======================================================================
+
+ImplRulerData::ImplRulerData()
+{
+ memset( this, 0, sizeof( ImplRulerData ) );
+
+ // PageBreite == EditWinBreite
+ bAutoPageWidth = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+ImplRulerData::~ImplRulerData()
+{
+ if ( pLines )
+ delete pLines;
+
+ if ( pArrows )
+ delete pArrows;
+
+ if ( pBorders )
+ delete pBorders;
+
+ if ( pIndents )
+ delete pIndents;
+
+ if ( pTabs )
+ delete pTabs;
+}
+
+// -----------------------------------------------------------------------
+
+ImplRulerData& ImplRulerData::operator=( const ImplRulerData& rData )
+{
+ if ( pLines )
+ delete pLines;
+
+ if ( pArrows )
+ delete pArrows;
+
+ if ( pBorders )
+ delete pBorders;
+
+ if ( pIndents )
+ delete pIndents;
+
+ if ( pTabs )
+ delete pTabs;
+
+ memcpy( this, &rData, sizeof( ImplRulerData ) );
+
+ if ( rData.pLines )
+ {
+ pLines = new RulerLine[nLines];
+ memcpy( pLines, rData.pLines, nLines*sizeof( RulerLine ) );
+ }
+
+ if ( rData.pArrows )
+ {
+ pArrows = new RulerArrow[nArrows];
+ memcpy( pArrows, rData.pArrows, nArrows*sizeof( RulerArrow ) );
+ }
+
+ if ( rData.pBorders )
+ {
+ pBorders = new RulerBorder[nBorders];
+ memcpy( pBorders, rData.pBorders, nBorders*sizeof( RulerBorder ) );
+ }
+
+ if ( rData.pIndents )
+ {
+ pIndents = new RulerIndent[nIndents];
+ memcpy( pIndents, rData.pIndents, nIndents*sizeof( RulerIndent ) );
+ }
+
+ if ( rData.pTabs )
+ {
+ pTabs = new RulerTab[nTabs];
+ memcpy( pTabs, rData.pTabs, nTabs*sizeof( RulerTab ) );
+ }
+
+ return *this;
+}
+
+// =======================================================================
+
+void Ruler::ImplInit( WinBits nWinBits )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Default WinBits setzen
+ if ( !(nWinBits & WB_VERT) )
+ nWinBits |= WB_HORZ;
+
+ // Variablen initialisieren
+ mnWinStyle = nWinBits; // Window-Style
+ mnBorderOff = 0; // Border-Offset
+ mnWinOff = 0; // EditWinOffset
+ mnWinWidth = 0; // EditWinWidth
+ mnWidth = 0; // Fensterbreite
+ mnHeight = 0; // Fensterhoehe
+ mnVirOff = 0; // Offset des VirtualDeice vom linke/oberen Rand
+ mnVirWidth = 0; // Breite bzw. Hoehe vom VirtualDevice
+ mnVirHeight = 0; // Hoehe bzw. Breite vom VirtualDevice
+ mnDragPos = 0; // Drag-Position (NullPunkt)
+ mnUpdateEvtId = 0; // Noch kein Update-Event verschickt
+ mnDragAryPos = 0; // Drag-Array-Index
+ mnDragSize = 0; // Wird beim Draggen die Groesse geaendert
+ mnDragScroll = 0; // Soll beim Draggen gescrollt werden
+ mnDragModifier = 0; // Modifier-Tasten beim Draggen
+ mnExtraStyle = 0; // Style des Extra-Feldes
+ mnExtraClicks = 0; // Click-Anzahl fuer Extra-Feld
+ mnExtraModifier = 0; // Modifier-Tasten beim Click im Extrafeld
+ mbCalc = TRUE; // Muessen Pagebreiten neu berechnet werden
+ mbFormat = TRUE; // Muss neu ausgegeben werden
+ mbDrag = FALSE; // Sind wir im Drag-Modus
+ mbDragDelete = FALSE; // Wird Maus beim Draggen unten rausgezogen
+ mbDragCanceled = FALSE; // Wurde Dragging abgebrochen
+ mbAutoWinWidth = TRUE; // EditWinBreite == RulerBreite
+ mbActive = TRUE; // Ist Lineal aktiv
+ mnUpdateFlags = 0; // Was soll im Update-Handler upgedatet werden
+ mpData = &maData; // Wir zeigen auf die normalen Daten
+ meExtraType = RULER_EXTRA_DONTKNOW; // Was im ExtraFeld dargestellt wird
+ meDragType = RULER_TYPE_DONTKNOW; // Gibt an, was gedragt wird
+
+ // Units initialisieren
+ mnUnitIndex = RULER_UNIT_CM;
+ meUnit = FUNIT_CM;
+ maZoom = Fraction( 1, 1 );
+ meSourceUnit = MAP_100TH_MM;
+
+ // Border-Breiten berechnen
+ if ( nWinBits & WB_BORDER )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ mnBorderWidth = 2;
+ else
+ mnBorderWidth = 1;
+ }
+ else
+ mnBorderWidth = 0;
+
+ // Einstellungen setzen
+ ImplInitSettings( TRUE, TRUE, TRUE );
+
+ // Default-Groesse setzen
+ long nDefHeight = GetTextHeight() + RULER_OFF*2 + RULER_TEXTOFF*2 + mnBorderWidth;
+ Size aDefSize;
+ if ( nWinBits & WB_HORZ )
+ aDefSize.Height() = nDefHeight;
+ else
+ aDefSize.Width() = nDefHeight;
+ SetOutputSizePixel( aDefSize );
+}
+
+// -----------------------------------------------------------------------
+
+Ruler::Ruler( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle & WB_3DLOOK ),
+ maVirDev( *this ),
+ maMapMode( MAP_100TH_MM )
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Ruler::~Ruler()
+{
+ if ( mnUpdateEvtId )
+ Application::RemoveUserEvent( mnUpdateEvtId );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplVDrawLine( long nX1, long nY1, long nX2, long nY2 )
+{
+ if ( nX1 < -RULER_CLIP )
+ {
+ nX1 = -RULER_CLIP;
+ if ( nX2 < -RULER_CLIP )
+ return;
+ }
+ long nClip = mnVirWidth+RULER_CLIP;
+ if ( nX2 > nClip )
+ {
+ nX2 = nClip;
+ if ( nX1 > nClip )
+ return;
+ }
+
+ if ( mnWinStyle & WB_HORZ )
+ maVirDev.DrawLine( Point( nX1, nY1 ), Point( nX2, nY2 ) );
+ else
+ maVirDev.DrawLine( Point( nY1, nX1 ), Point( nY2, nX2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplVDrawRect( long nX1, long nY1, long nX2, long nY2 )
+{
+ if ( nX1 < -RULER_CLIP )
+ {
+ nX1 = -RULER_CLIP;
+ if ( nX2 < -RULER_CLIP )
+ return;
+ }
+ long nClip = mnVirWidth+RULER_CLIP;
+ if ( nX2 > nClip )
+ {
+ nX2 = nClip;
+ if ( nX1 > nClip )
+ return;
+ }
+
+ if ( mnWinStyle & WB_HORZ )
+ maVirDev.DrawRect( Rectangle( nX1, nY1, nX2, nY2 ) );
+ else
+ maVirDev.DrawRect( Rectangle( nY1, nX1, nY2, nX2 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplVDrawText( long nX, long nY, const String& rText )
+{
+ if ( (nX > -RULER_CLIP) && (nX < mnVirWidth+RULER_CLIP) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ maVirDev.DrawText( Point( nX, nY ), rText );
+ else
+ maVirDev.DrawText( Point( nY, nX ), rText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplInvertLines( BOOL bErase )
+{
+ // Positionslinien
+ if ( mpData->nLines && mbActive && !mbDrag && !mbFormat &&
+ !(mnUpdateFlags & RULER_UPDATE_LINES) )
+ {
+ long n;
+ long nNullWinOff = mpData->nNullVirOff+mnVirOff;
+ long nRulX1 = mpData->nRulVirOff+mnVirOff;
+ long nRulX2 = nRulX1+mpData->nRulWidth;
+ long nY = (RULER_OFF*2)+mnVirHeight-1;
+
+ // Rectangle berechnen
+ Rectangle aRect;
+ if ( mnWinStyle & WB_HORZ )
+ aRect.Bottom() = nY;
+ else
+ aRect.Right() = nY;
+
+ // Linien ausgeben
+ for ( USHORT i = 0; i < mpData->nLines; i++ )
+ {
+ n = mpData->pLines[i].nPos+nNullWinOff;
+ if ( (n >= nRulX1) && (n < nRulX2) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aRect.Left() = n;
+ aRect.Right() = n;
+ }
+ else
+ {
+ aRect.Top() = n;
+ aRect.Bottom() = n;
+ }
+ if ( bErase )
+ {
+ Rectangle aTempRect = aRect;
+ if ( mnWinStyle & WB_HORZ )
+ aTempRect.Bottom() = RULER_OFF-1;
+ else
+ aTempRect.Right() = RULER_OFF-1;
+ Erase( aTempRect );
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aTempRect.Bottom() = aRect.Bottom();
+ aTempRect.Top() = aTempRect.Bottom()-RULER_OFF+1;
+ }
+ else
+ {
+ aTempRect.Right() = aRect.Right();
+ aTempRect.Left() = aTempRect.Right()-RULER_OFF+1;
+ }
+ Erase( aTempRect );
+ }
+ Invert( aRect );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawTicks( long nMin, long nMax, long nStart, long nCenter )
+{
+ long n = 0;
+ long nTick = 0;
+ long nTick3 = aImplRulerUnitTab[mnUnitIndex].nTick3;
+ long nTickCount = aImplRulerUnitTab[mnUnitIndex].nTick1;
+ Size aPixSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
+ long nTickWidth;
+ long nX;
+ long nY;
+ BOOL bNoTicks = FALSE;
+
+ // Groessenvorberechnung
+ if ( mnWinStyle & WB_HORZ )
+ nTickWidth = aPixSize.Width();
+ else
+ nTickWidth = aPixSize.Height();
+ long nMaxWidth = maVirDev.PixelToLogic( Size( mpData->nPageWidth, 0 ), maMapMode ).Width();
+ if ( nMaxWidth < 0 )
+ nMaxWidth *= -1;
+ nMaxWidth /= aImplRulerUnitTab[mnUnitIndex].nTickUnit;
+ UniString aNumStr( UniString::CreateFromInt32( nMaxWidth ) );
+ long nTxtWidth = GetTextWidth( aNumStr );
+ if ( (nTxtWidth*2) > nTickWidth )
+ {
+ long nMulti = 1;
+ long nOrgTick3 = nTick3;
+ long nTextOff = 2;
+ while ( nTickWidth < nTxtWidth+nTextOff )
+ {
+ long nOldMulti = nMulti;
+ if ( !nTickWidth )
+ nMulti *= 10;
+ else if ( nMulti < 10 )
+ nMulti++;
+ else if ( nMulti < 100 )
+ nMulti += 10;
+ else if ( nMulti < 1000 )
+ nMulti += 100;
+ else
+ nMulti += 1000;
+ // Ueberlauf, dann geben wir nichts aus, da wir bei so einem
+ // unsinnigen Massstab sowieso nichts vernuenftiges anzeigen
+ // koennen
+ if ( nMulti < nOldMulti )
+ {
+ bNoTicks = TRUE;
+ break;
+ }
+ if ( nMulti >= 100 )
+ nTextOff = 4;
+ nTick3 = nOrgTick3 * nMulti;
+ aPixSize = maVirDev.LogicToPixel( Size( nTick3, nTick3 ), maMapMode );
+ if ( mnWinStyle & WB_HORZ )
+ nTickWidth = aPixSize.Width();
+ else
+ nTickWidth = aPixSize.Height();
+ }
+ nTickCount = nTick3;
+ }
+ else
+ maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
+
+ if ( !bNoTicks )
+ {
+ long nTxtWidth2;
+ long nTxtHeight2 = GetTextHeight()/2;
+ while ( ((nStart-n) >= nMin) || ((nStart+n) <= nMax) )
+ {
+ // Null-Punkt
+ if ( !nTick )
+ {
+ if ( nStart > nMin )
+ {
+ // Nur 0 malen, wenn Margin1 nicht gleich dem NullPunkt ist
+ if ( (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) || (mpData->nMargin1 != 0) )
+ {
+ aNumStr = (sal_Unicode)'0';
+ nTxtWidth2 = maVirDev.GetTextWidth( aNumStr )/2;
+ if ( mnWinStyle & WB_HORZ )
+ nX = nStart-nTxtWidth2;
+ else
+ nX = nStart+nTxtWidth2;
+ ImplVDrawText( nX, nCenter-nTxtHeight2, aNumStr );
+ }
+ }
+ }
+ else
+ {
+ aPixSize = maVirDev.LogicToPixel( Size( nTick, nTick ), maMapMode );
+
+ if ( mnWinStyle & WB_HORZ )
+ n = aPixSize.Width();
+ else
+ n = aPixSize.Height();
+
+ // Tick3 - Ausgabe (Text)
+ if ( !(nTick % nTick3) )
+ {
+ aNumStr = UniString::CreateFromInt32( nTick / aImplRulerUnitTab[mnUnitIndex].nTickUnit );
+ nTxtWidth2 = GetTextWidth( aNumStr )/2;
+
+ nX = nStart+n;
+ nY = nCenter-nTxtHeight2;
+ if ( nX < nMax )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ nX -= nTxtWidth2;
+ else
+ nX += nTxtWidth2;
+ ImplVDrawText( nX, nY, aNumStr );
+ }
+ nX = nStart-n;
+ if ( nX > nMin )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ nX -= nTxtWidth2;
+ else
+ nX += nTxtWidth2;
+ ImplVDrawText( nX, nY, aNumStr );
+ }
+ }
+ // Tick/Tick2 - Ausgabe (Striche)
+ else
+ {
+ if ( !(nTick % aImplRulerUnitTab[mnUnitIndex].nTick2) )
+ nTickWidth = RULER_TICK2_WIDTH;
+ else
+ nTickWidth = RULER_TICK1_WIDTH;
+ long nT1 = nCenter-(nTickWidth/2);
+ long nT2 = nT1+nTickWidth-1;
+ long nT;
+
+ nT = nStart+n;
+ if ( nT < nMax )
+ ImplVDrawLine( nT, nT1, nT, nT2 );
+ nT = nStart-n;
+ if ( nT > nMin )
+ ImplVDrawLine( nT, nT1, nT, nT2 );
+ }
+ }
+
+ nTick += nTickCount;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawArrows( long nCenter )
+{
+ USHORT i;
+ long n1;
+ long n2;
+ long n3;
+ long n4;
+ long nLogWidth;
+ String aStr;
+ String aStr2;
+ BOOL bDrawUnit;
+ long nTxtWidth;
+ long nTxtHeight2 = GetTextHeight()/2;
+ International aIntn = Application::GetAppInternational();
+
+ aIntn.SetNumTrailingZeros( FALSE );
+ maVirDev.SetLineColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
+ for ( i = 0; i < mpData->nArrows; i++ )
+ {
+ n1 = mpData->pArrows[i].nPos+mpData->nNullVirOff+1;
+ n2 = n1+mpData->pArrows[i].nWidth-2;
+
+ // Einheit umrechnen
+ nLogWidth = mpData->pArrows[i].nLogWidth;
+ if ( meSourceUnit == MAP_TWIP )
+ {
+ if ( nLogWidth >= 100000 )
+ nLogWidth = (nLogWidth*254)/144;
+ else
+ nLogWidth = (nLogWidth*2540)/1440;
+ }
+ if ( nLogWidth >= 1000000 )
+ nLogWidth = (nLogWidth / aImplRulerUnitTab[mnUnitIndex].n100THMM) * 1000;
+ else
+ nLogWidth = (nLogWidth*1000) / aImplRulerUnitTab[mnUnitIndex].n100THMM;
+ aStr = aIntn.GetNum( nLogWidth, aImplRulerUnitTab[mnUnitIndex].nUnitDigits );
+
+ // Einheit an den String haengen
+ aStr2 = aStr;
+ aStr2.AppendAscii( aImplRulerUnitTab[mnUnitIndex].aUnitStr );
+
+ // Textbreite ermitteln
+ bDrawUnit = TRUE;
+ nTxtWidth = GetTextWidth( aStr2 );
+ if ( nTxtWidth < mpData->pArrows[i].nWidth-10 )
+ aStr = aStr2;
+ else
+ {
+ nTxtWidth = GetTextWidth( aStr );
+ if ( nTxtWidth > mpData->pArrows[i].nWidth-10 )
+ bDrawUnit = FALSE;
+ }
+
+ // Ist genuegen Platz fuer Einheiten-String vorhanden
+ if ( bDrawUnit )
+ {
+ n3 = n1 + ((n2-n1)/2) - 1;
+ if ( mnWinStyle & WB_HORZ )
+ n3 -= nTxtWidth/2;
+ else
+ n3 += nTxtWidth/2;
+ if ( mnWinStyle & WB_HORZ )
+ {
+ n4 = n3 + nTxtWidth + 2;
+ ImplVDrawLine( n1, nCenter, n3, nCenter );
+ ImplVDrawLine( n4, nCenter, n2, nCenter );
+ }
+ else
+ {
+ n4 = n3 - nTxtWidth - 2;
+ ImplVDrawLine( n1, nCenter, n4, nCenter );
+ ImplVDrawLine( n3, nCenter, n2, nCenter );
+ }
+ ImplVDrawText( n3, nCenter-nTxtHeight2, aStr );
+ }
+ else
+ ImplVDrawLine( n1, nCenter, n2, nCenter );
+ ImplVDrawLine( n1+1, nCenter-1, n1+1, nCenter+1 );
+ ImplVDrawLine( n1+2, nCenter-2, n1+2, nCenter+2 );
+ ImplVDrawLine( n2-1, nCenter-1, n2-1, nCenter+1 );
+ ImplVDrawLine( n2-2, nCenter-2, n2-2, nCenter+2 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawBorders( long nMin, long nMax, long nVirTop, long nVirBottom )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long n;
+ long n1;
+ long n2;
+ long nTemp1;
+ long nTemp2;
+ USHORT i;
+
+ for ( i = 0; i < mpData->nBorders; i++ )
+ {
+ if ( mpData->pBorders[i].nStyle & RULER_STYLE_INVISIBLE )
+ continue;
+
+ n1 = mpData->pBorders[i].nPos+mpData->nNullVirOff;
+ n2 = n1+mpData->pBorders[i].nWidth;
+
+ if ( ((n1 >= nMin) && (n1 <= nMax)) || ((n2 >= nMin) && (n2 <= nMax)) )
+ {
+ if ( (n2-n1) > 3 )
+ {
+ maVirDev.SetLineColor();
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ ImplVDrawRect( n1, nVirTop, n2, nVirBottom );
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ ImplVDrawLine( n1+1, nVirTop, n1+1, nVirBottom );
+ ImplVDrawLine( n1, nVirTop, n2, nVirTop );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
+ ImplVDrawLine( n1, nVirBottom, n2, nVirBottom );
+ ImplVDrawLine( n2-1, nVirTop, n2-1, nVirBottom );
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( n1, nVirTop, n1, nVirBottom );
+ ImplVDrawLine( n2, nVirTop, n2, nVirBottom );
+ }
+
+ if ( mpData->pBorders[i].nStyle & RULER_BORDER_VARIABLE )
+ {
+ if ( n2-n1 > RULER_VAR_SIZE+4 )
+ {
+ nTemp1 = n1 + (((n2-n1+1)-RULER_VAR_SIZE) / 2);
+ nTemp2 = nVirTop + (((nVirBottom-nVirTop+1)-RULER_VAR_SIZE) / 2);
+ long nTemp3 = nTemp1+RULER_VAR_SIZE-1;
+ long nTemp4 = nTemp2+RULER_VAR_SIZE-1;
+ long nTempY = nTemp2;
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ while ( nTempY <= nTemp4 )
+ {
+ ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
+ nTempY += 2;
+ }
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ nTempY = nTemp2+1;
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ while ( nTempY <= nTemp4 )
+ {
+ ImplVDrawLine( nTemp1, nTempY, nTemp3, nTempY );
+ nTempY += 2;
+ }
+ }
+ }
+ }
+
+ if ( mpData->pBorders[i].nStyle & RULER_BORDER_SIZEABLE )
+ {
+ if ( n2-n1 > RULER_VAR_SIZE+10 )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ ImplVDrawLine( n1+4, nVirTop+3, n1+4, nVirBottom-3 );
+ ImplVDrawLine( n2-5, nVirTop+3, n2-5, nVirBottom-3 );
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ ImplVDrawLine( n1+5, nVirTop+3, n1+5, nVirBottom-3 );
+ ImplVDrawLine( n2-4, nVirTop+3, n2-4, nVirBottom-3 );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( n1+4, nVirTop+3, n1+4, nVirBottom-3 );
+ ImplVDrawLine( n2-4, nVirTop+3, n2-4, nVirBottom-3 );
+ }
+ }
+ }
+ }
+ else
+ {
+ n = n1+((n2-n1)/2);
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ if ( mpData->pBorders[i].nStyle & RULER_BORDER_SNAP )
+ ImplVDrawLine( n, nVirTop, n, nVirBottom );
+ else
+ {
+ ImplVDrawLine( n-1, nVirTop, n-1, nVirBottom );
+ ImplVDrawLine( n+1, nVirTop, n+1, nVirBottom );
+ maVirDev.SetLineColor();
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ ImplVDrawRect( n, nVirTop, n, nVirBottom );
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawIndent( const Polygon& rPoly, USHORT nStyle )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Point aPos1;
+ Point aPos2;
+ USHORT nIndentStyle = nStyle & RULER_INDENT_STYLE;
+
+ if ( nStyle & RULER_STYLE_INVISIBLE )
+ return;
+
+ if ( nStyle & RULER_STYLE_DONTKNOW )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ }
+
+ maVirDev.DrawPolygon( rPoly );
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && !(nStyle & RULER_STYLE_DONTKNOW) )
+ {
+ if ( nIndentStyle == RULER_INDENT_BOTTOM )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ aPos1 = rPoly.GetPoint( 2 );
+ aPos1.X()++;
+ aPos2 = rPoly.GetPoint( 1 );
+ aPos2.X()++;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ aPos2.X()--;
+ aPos2.Y()++;
+ aPos1 = rPoly.GetPoint( 0 );
+ aPos1.Y()++;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ aPos2 = rPoly.GetPoint( 4 );
+ aPos2.Y()++;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2.X()--;
+ aPos1 = rPoly.GetPoint( 3 );
+ aPos1.X()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ aPos1.Y()--;
+ aPos2 = rPoly.GetPoint( 2 );
+ aPos2.X()++;
+ aPos2.Y()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ aPos1 = rPoly.GetPoint( 2 );
+ aPos1.X()++;
+ aPos1.Y()++;
+ aPos2 = rPoly.GetPoint( 3 );
+ aPos2.Y()++;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2 = rPoly.GetPoint( 1 );
+ aPos2.X()++;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2.X()--;
+ aPos2.Y()--;
+ aPos1 = rPoly.GetPoint( 0 );
+ aPos1.Y()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ aPos2 = rPoly.GetPoint( 4 );
+ aPos2.Y()--;
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos2.X()--;
+ aPos1 = rPoly.GetPoint( 3 );
+ aPos1.X()--;
+ maVirDev.DrawLine( aPos2, aPos1 );
+ }
+
+ maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ maVirDev.SetFillColor();
+ maVirDev.DrawPolygon( rPoly );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawIndents( long nMin, long nMax, long nVirTop, long nVirBottom )
+{
+ USHORT i;
+ long n;
+ long nIndentHeight = (mnVirHeight/2) - 1;
+ long nIndentWidth2 = nIndentHeight-3;
+ Polygon aPoly( 5 );
+
+ for ( i = 0; i < mpData->nIndents; i++ )
+ {
+ if ( mpData->pIndents[i].nStyle & RULER_STYLE_INVISIBLE )
+ continue;
+
+ USHORT nStyle = mpData->pIndents[i].nStyle;
+ USHORT nIndentStyle = nStyle & RULER_INDENT_STYLE;
+
+ n = mpData->pIndents[i].nPos+mpData->nNullVirOff;
+
+ if ( (n >= nMin) && (n <= nMax) )
+ {
+ if ( nIndentStyle == RULER_INDENT_BOTTOM )
+ {
+ aPoly.SetPoint( Point( n+0, nVirBottom-nIndentHeight ), 0 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirBottom-3 ), 1 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirBottom ), 2 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirBottom ), 3 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirBottom-3 ), 4 );
+ }
+ else
+ {
+ aPoly.SetPoint( Point( n+0, nVirTop+nIndentHeight ), 0 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirTop+3 ), 1 );
+ aPoly.SetPoint( Point( n-nIndentWidth2, nVirTop ), 2 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirTop ), 3 );
+ aPoly.SetPoint( Point( n+nIndentWidth2, nVirTop+3 ), 4 );
+ }
+
+ ImplDrawIndent( aPoly, nStyle );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCenterTabPos( Point& rPos, USHORT nStyle )
+{
+ rPos.Y() += RULER_TAB_HEIGHT/2;
+ if ( nStyle == RULER_TAB_LEFT )
+ rPos.X() -= RULER_TAB_WIDTH/2;
+ else if ( nStyle == RULER_TAB_RIGHT )
+ rPos.X() += RULER_TAB_WIDTH/2;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawRulerTab( OutputDevice* pDevice,
+ const Point& rPos, USHORT nStyle )
+{
+ if ( nStyle & RULER_STYLE_INVISIBLE )
+ return;
+
+ USHORT nTabStyle = nStyle & RULER_TAB_STYLE;
+
+ if ( nTabStyle == RULER_TAB_DEFAULT )
+ {
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_DWIDTH2 + 1,
+ rPos.Y() - RULER_TAB_DHEIGHT2 + 1,
+ rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH,
+ rPos.Y() ) );
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3,
+ rPos.Y() - RULER_TAB_DHEIGHT + 1,
+ rPos.X() - RULER_TAB_DWIDTH2 + RULER_TAB_DWIDTH3 + RULER_TAB_DWIDTH4 - 1,
+ rPos.Y() ) );
+
+ }
+ else if ( nTabStyle == RULER_TAB_LEFT )
+ {
+ pDevice->DrawRect( Rectangle( rPos.X(),
+ rPos.Y() - RULER_TAB_HEIGHT2 + 1,
+ rPos.X() + RULER_TAB_WIDTH - 1,
+ rPos.Y() ) );
+ pDevice->DrawRect( Rectangle( rPos.X(),
+ rPos.Y() - RULER_TAB_HEIGHT + 1,
+ rPos.X() + RULER_TAB_WIDTH2 - 1,
+ rPos.Y() ) );
+ }
+ else if ( nTabStyle == RULER_TAB_RIGHT )
+ {
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_WIDTH + 1,
+ rPos.Y() - RULER_TAB_HEIGHT2 + 1,
+ rPos.X(),
+ rPos.Y() ) );
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_WIDTH2 + 1,
+ rPos.Y() - RULER_TAB_HEIGHT + 1,
+ rPos.X(),
+ rPos.Y() ) );
+ }
+ else
+ {
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_CWIDTH2 + 1,
+ rPos.Y() - RULER_TAB_HEIGHT2 + 1,
+ rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH,
+ rPos.Y() ) );
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3,
+ rPos.Y() - RULER_TAB_HEIGHT + 1,
+ rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH3 + RULER_TAB_CWIDTH4 - 1,
+ rPos.Y() ) );
+
+ if ( nTabStyle == RULER_TAB_DECIMAL )
+ {
+ pDevice->DrawRect( Rectangle( rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH - 1,
+ rPos.Y() - RULER_TAB_HEIGHT + 1 + 1,
+ rPos.X() - RULER_TAB_CWIDTH2 + RULER_TAB_CWIDTH,
+ rPos.Y() - RULER_TAB_HEIGHT + 1 + 2 ) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawTab( OutputDevice* pDevice, const Point& rPos, USHORT nStyle )
+{
+ if ( nStyle & RULER_STYLE_INVISIBLE )
+ return;
+
+ pDevice->SetLineColor();
+ if ( nStyle & RULER_STYLE_DONTKNOW )
+ pDevice->SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
+ else
+ pDevice->SetFillColor( GetSettings().GetStyleSettings().GetWindowTextColor() );
+
+ ImplDrawRulerTab( pDevice, rPos, nStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawTabs( long nMin, long nMax, long nVirBottom )
+{
+ for ( USHORT i = 0; i < mpData->nTabs; i++ )
+ {
+ if ( mpData->pTabs[i].nStyle & RULER_STYLE_INVISIBLE )
+ continue;
+
+ long n = mpData->pTabs[i].nPos+mpData->nNullVirOff;
+ if ( (n >= nMin) && (n <= nMax) )
+ ImplDrawTab( &maVirDev, Point( n, nVirBottom ), mpData->pTabs[i].nStyle );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor;
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ else
+ aColor = rStyleSettings.GetButtonTextColor();
+ SetTextColor( aColor );
+ SetTextFillColor();
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+
+ maVirDev.SetSettings( GetSettings() );
+ maVirDev.SetBackground( GetBackground() );
+ Font aFont = GetFont();
+ if ( mnWinStyle & WB_VERT )
+ aFont.SetOrientation( 900 );
+ maVirDev.SetFont( aFont );
+ maVirDev.SetTextColor( GetTextColor() );
+ maVirDev.SetTextFillColor( GetTextFillColor() );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplCalc()
+{
+ // Offset berechnen
+ mpData->nRulVirOff = mnWinOff + mpData->nPageOff;
+ if ( mpData->nRulVirOff > mnVirOff )
+ mpData->nRulVirOff -= mnVirOff;
+ else
+ mpData->nRulVirOff = 0;
+ long nRulWinOff = mpData->nRulVirOff+mnVirOff;
+
+ // Nicht sichtbaren Bereich der Page berechnen
+ long nNotVisPageWidth;
+ if ( mpData->nPageOff < 0 )
+ {
+ nNotVisPageWidth = -(mpData->nPageOff);
+ if ( nRulWinOff < mnWinOff )
+ nNotVisPageWidth -= mnWinOff-nRulWinOff;
+ }
+ else
+ nNotVisPageWidth = 0;
+
+ // Breite berechnen
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( mbAutoWinWidth )
+ mnWinWidth = mnWidth - mnVirOff;
+ if ( mpData->bAutoPageWidth )
+ mpData->nPageWidth = mnWinWidth;
+ mpData->nRulWidth = Min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
+ if ( nRulWinOff+mpData->nRulWidth > mnWidth )
+ mpData->nRulWidth = mnWidth-nRulWinOff;
+ }
+ else
+ {
+ if ( mbAutoWinWidth )
+ mnWinWidth = mnHeight - mnVirOff;
+ if ( mpData->bAutoPageWidth )
+ mpData->nPageWidth = mnWinWidth;
+ mpData->nRulWidth = Min( mnWinWidth, mpData->nPageWidth-nNotVisPageWidth );
+ if ( nRulWinOff+mpData->nRulWidth > mnHeight )
+ mpData->nRulWidth = mnHeight-nRulWinOff;
+ }
+
+ mbCalc = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplFormat()
+{
+ // Wenn schon formatiert ist, brauchen wir es nicht nochmal
+ if ( !mbFormat )
+ return;
+
+ // Wenn Fenster noch keine Groesse hat, brauchen wir noch nichts machen
+ if ( !mnVirWidth )
+ return;
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long nP1; // Pixel-Position von Page1
+ long nP2; // Pixel-Position von Page2
+ long nM1; // Pixel-Position von Margin1
+ long nM2; // Pixel-Position von Margin2
+ long nVirTop; // Obere/Linke-Kante bei Ausgabe
+ long nVirBottom; // Untere/Rechte-Kante bei Ausgabe
+ long nVirLeft; // Linke/Obere-Kante bei Ausgabe
+ long nVirRight; // Rechte/Untere-Kante bei Ausgabe
+ long nNullVirOff; // Fuer schnellere Berechnung
+
+ // Werte berechnen
+ if ( mbCalc )
+ ImplCalc();
+ mpData->nNullVirOff = mnWinOff+mpData->nPageOff+mpData->nNullOff-mnVirOff;
+ nNullVirOff = mpData->nNullVirOff;
+ nVirLeft = mpData->nRulVirOff;
+ nVirRight = nVirLeft+mpData->nRulWidth-1;
+ nVirTop = 0;
+ nVirBottom = mnVirHeight-1;
+
+ if ( !IsReallyVisible() )
+ return;
+
+ Size aVirDevSize;
+ BOOL b3DLook = !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO);
+
+ // VirtualDevice initialisieren
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aVirDevSize.Width() = mnVirWidth;
+ aVirDevSize.Height() = mnVirHeight;
+ }
+ else
+ {
+ aVirDevSize.Height() = mnVirWidth;
+ aVirDevSize.Width() = mnVirHeight;
+ }
+ if ( aVirDevSize != maVirDev.GetOutputSizePixel() )
+ maVirDev.SetOutputSizePixel( aVirDevSize, TRUE );
+ else
+ maVirDev.Erase();
+
+ // Raender berechnen
+ if ( !(mpData->nMargin1Style & RULER_STYLE_INVISIBLE) )
+ {
+ nM1 = mpData->nMargin1+nNullVirOff;
+ if ( mpData->bAutoPageWidth )
+ {
+ nP1 = nVirLeft;
+ if ( nM1 < nVirLeft )
+ nP1--;
+ }
+ else
+ nP1 = nNullVirOff-mpData->nNullOff;
+ }
+ else
+ {
+ nM1 = nVirLeft-1;
+ nP1 = nM1;
+ }
+ if ( !(mpData->nMargin2Style & RULER_STYLE_INVISIBLE) )
+ {
+ nM2 = mpData->nMargin2+nNullVirOff;
+ if ( mpData->bAutoPageWidth )
+ {
+ nP2 = nVirRight;
+ if ( nM2 > nVirRight )
+ nP2++;
+ }
+ else
+ nP2 = nNullVirOff-mpData->nNullOff+mpData->nPageWidth;
+ if ( nM2 > nP2 )
+ nM2 = nP2;
+ }
+ else
+ {
+ nM2 = nVirRight+1;
+ nP2 = nM2;
+ }
+
+ // Obere/untere Kante ausgeben
+ if ( b3DLook )
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ ImplVDrawLine( nVirLeft, nVirTop, nP2, nVirTop );
+ if ( b3DLook )
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ ImplVDrawLine( nVirLeft, nVirBottom, nP2, nVirBottom );
+
+ // Jetzt wird zwischen dem Schatten ausgegeben
+ nVirTop++;
+ nVirBottom--;
+
+ // Margin1, Margin2 und Zwischenraum ausgeben
+ maVirDev.SetLineColor();
+ if ( b3DLook )
+ maVirDev.SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ if ( nM1 > nVirLeft )
+ ImplVDrawRect( nP1, nVirTop, nM1-1, nVirBottom );
+ if ( nM2 < nP2 )
+ ImplVDrawRect( nM2+1, nVirTop, nP2, nVirBottom );
+ if ( nM2-nM1 > 0 )
+ {
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ ImplVDrawRect( nM1, nVirTop, nM2-1, nVirBottom );
+ }
+ if ( b3DLook )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ if ( nM1 > nVirLeft )
+ {
+ ImplVDrawLine( nP1+1, nVirTop, nM1-1, nVirTop );
+ if ( nP1 >= nVirLeft )
+ {
+ ImplVDrawLine( nP1+1, nVirTop, nP1+1, nVirBottom );
+ ImplVDrawLine( nP1, nVirBottom+1, nP1+1, nVirBottom+1 );
+ }
+ }
+ if ( nM2 < nP2 )
+ {
+ ImplVDrawLine( nM2+1, nVirTop, nM2+1, nVirBottom );
+ ImplVDrawLine( nM2+1, nVirTop, nP2, nVirTop );
+ if ( nP2 <= nVirRight+1 )
+ {
+ ImplVDrawLine( nP2, nVirTop-1, nP2, nVirBottom );
+ ImplVDrawLine( nP2-1, nVirBottom+1, nP2, nVirBottom+1 );
+ }
+ }
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ if ( nM1 > nVirLeft )
+ {
+ ImplVDrawLine( nM1-1, nVirTop, nM1-1, nVirBottom );
+ ImplVDrawLine( nP1, nVirBottom, nM1-1, nVirBottom );
+ if ( nP1 >= nVirLeft )
+ {
+ ImplVDrawLine( nP1, nVirTop, nP1, nVirBottom );
+ ImplVDrawLine( nP1, nVirBottom, nP1+1, nVirBottom );
+ }
+ }
+ if ( nM2 < nP2 )
+ {
+ ImplVDrawLine( nM2+1, nVirBottom, nP2-1, nVirBottom );
+ if ( nP2 <= nVirRight+1 )
+ ImplVDrawLine( nP2-1, nVirTop, nP2-1, nVirBottom );
+ }
+ if ( nM2-nM1 > 0 )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ if ( nM1 >= nVirLeft )
+ ImplVDrawLine( nM1, nVirTop, nM1, nVirBottom );
+ ImplVDrawLine( nM1, nVirTop, nM2-1, nVirTop );
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ ImplVDrawLine( nM1, nVirBottom, nM2-1, nVirBottom );
+ if ( nM2 <= nVirRight )
+ ImplVDrawLine( nM2, nVirTop, nM2, nVirBottom );
+ }
+ }
+ else
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ if ( nP1 >= nVirLeft )
+ ImplVDrawLine( nP1, nVirTop, nP1, nVirBottom+1 );
+ if ( nM1 > nP1 )
+ ImplVDrawLine( nM1, nVirTop, nM1, nVirBottom );
+ if ( nM2 < nP2 )
+ ImplVDrawLine( nM2, nVirTop, nM2, nVirBottom );
+ if ( nP2 <= nVirRight+1 )
+ ImplVDrawLine( nP2, nVirTop, nP2, nVirBottom+1 );
+ }
+
+ // Lineal-Beschriftung (nur wenn keine Bemassungspfeile)
+ if ( !mpData->pArrows )
+ {
+ long nMin = nVirLeft;
+ long nMax = nP2;
+ long nStart = nNullVirOff;
+ long nCenter = nVirTop+((nVirBottom-nVirTop)/2);
+
+ // Nicht Schatten uebermalen
+ if ( nP1 > nVirLeft )
+ nMin++;
+ if ( nP2 < nVirRight )
+ nMax--;
+
+ // Beschriftung ausgeben
+ ImplDrawTicks( nMin, nMax, nStart, nCenter );
+ }
+
+ // Spalten ausgeben
+ if ( mpData->pBorders )
+ ImplDrawBorders( nVirLeft, nP2, nVirTop, nVirBottom );
+
+ // Einzuege ausgeben
+ if ( mpData->pIndents )
+ ImplDrawIndents( nVirLeft, nP2, nVirTop-1, nVirBottom+1 );
+
+ // Tabs
+ if ( mpData->pTabs )
+ ImplDrawTabs( nVirLeft, nP2, nVirBottom+1 );
+
+ // Bemassungspfeile
+ if ( mpData->pArrows )
+ ImplDrawArrows( nVirTop+((nVirBottom-nVirTop)/2) );
+
+ // Wir haben formatiert
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplInitExtraField( BOOL bUpdate )
+{
+ // Extra-Field beruecksichtigen
+ if ( mnWinStyle & WB_EXTRAFIELD )
+ {
+ maExtraRect.Left() = RULER_OFF;
+ maExtraRect.Top() = RULER_OFF;
+ maExtraRect.Right() = RULER_OFF+mnVirHeight-1;
+ maExtraRect.Bottom() = RULER_OFF+mnVirHeight-1;
+ mnVirOff = maExtraRect.Right()+1;
+ }
+ else
+ {
+ maExtraRect.SetEmpty();
+ mnVirOff = 0;
+ }
+
+ if ( bUpdate )
+ {
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDraw()
+{
+ if ( mbFormat )
+ ImplFormat();
+
+ if ( IsReallyVisible() )
+ {
+ // Lineal ueber das VirtualDevice ausgeben
+ Point aOffPos;
+ Size aVirDevSize = maVirDev.GetOutputSizePixel();
+ if ( mnWinStyle & WB_HORZ )
+ {
+ aOffPos.X() = mnVirOff;
+ aOffPos.Y() = RULER_OFF;
+ }
+ else
+ {
+ aOffPos.X() = RULER_OFF;
+ aOffPos.Y() = mnVirOff;
+ }
+ DrawOutDev( aOffPos, aVirDevSize, Point(), aVirDevSize, maVirDev );
+
+ // Positionslinien neu malen
+ ImplInvertLines( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrawExtra( BOOL bPaint )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aRect = maExtraRect;
+ BOOL bEraseRect = FALSE;
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+ }
+ else
+ {
+ aRect.Left() += 1;
+ aRect.Top() += 1;
+ aRect.Right() -= 1;
+ aRect.Bottom() -= 1;
+ }
+
+ if ( !bPaint && !(mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ else
+ SetFillColor( rStyleSettings.GetWindowColor() );
+ bEraseRect = TRUE;
+ }
+ else
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && (mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
+ {
+ SetFillColor( rStyleSettings.GetCheckedColor() );
+ bEraseRect = TRUE;
+ }
+ }
+
+ if ( bEraseRect )
+ {
+ SetLineColor();
+ DrawRect( aRect );
+ }
+
+ // Inhalt ausgeben
+ if ( meExtraType == RULER_EXTRA_NULLOFFSET )
+ {
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( Point( aRect.Left()+1, aRect.Top()+4 ),
+ Point( aRect.Right()-1, aRect.Top()+4 ) );
+ DrawLine( Point( aRect.Left()+4, aRect.Top()+1 ),
+ Point( aRect.Left()+4, aRect.Bottom()-1 ) );
+ }
+ else if ( meExtraType == RULER_EXTRA_TAB )
+ {
+ USHORT nTabStyle = mnExtraStyle & RULER_TAB_STYLE;
+ Point aCenter = aRect.Center();
+ ImplCenterTabPos( aCenter, nTabStyle );
+ ImplDrawTab( this, aCenter, nTabStyle );
+ }
+
+ if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) && (mnExtraStyle & RULER_STYLE_HIGHLIGHT) )
+ Invert( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplUpdate( BOOL bMustCalc )
+{
+ // Hier schon Linien loeschen, damit Sie vor dem Neuberechnen schon
+ // geloscht sind, da danach die alten Positionen nicht mehr bestimmt
+ // werden koennen
+ if ( !mbFormat )
+ ImplInvertLines();
+
+ // Flags setzen
+ if ( bMustCalc )
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+
+ // Wenn wir am Draggen sind, wird nach dem Drag-Handler automatisch
+ // das Lineal neu upgedatet
+ if ( mbDrag )
+ return;
+
+ // Gegebenenfalls Update ausloesen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ mnUpdateFlags |= RULER_UPDATE_DRAW;
+ if ( !mnUpdateEvtId )
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::ImplHitTest( const Point& rPos, ImplRulerHitTest* pHitTest ) const
+{
+ USHORT i;
+ USHORT nStyle;
+ long nHitBottom;
+ long nX;
+ long nY;
+ long n1;
+ long n2;
+
+ if ( !mbActive )
+ return FALSE;
+
+ // Position ermitteln
+ if ( mnWinStyle & WB_HORZ )
+ {
+ nX = rPos.X();
+ nY = rPos.Y();
+ }
+ else
+ {
+ nX = rPos.Y();
+ nY = rPos.X();
+ }
+ nHitBottom = mnVirHeight+(RULER_OFF*2);
+
+ // Initialisieren
+ memset( pHitTest, 0, sizeof( ImplRulerHitTest ) );
+
+ // Damit ueberstehende Tabs und Einzuege mit beruecksichtigt werden
+ long nXExtraOff;
+ if ( mpData->pTabs || mpData->pIndents )
+ nXExtraOff = (mnVirHeight/2) - 4;
+ else
+ nXExtraOff = 0;
+
+ // Test auf ausserhalb
+ nX -= mnVirOff;
+ long nXTemp = nX;
+ if ( (nX < mpData->nRulVirOff-nXExtraOff) || (nX > mpData->nRulVirOff+mpData->nRulWidth+nXExtraOff) ||
+ (nY < 0) || (nY > nHitBottom) )
+ {
+ pHitTest->nPos = 0;
+ pHitTest->eType = RULER_TYPE_OUTSIDE;
+ return FALSE;
+ }
+
+ nX -= mpData->nNullVirOff;
+ pHitTest->nPos = nX;
+ pHitTest->eType = RULER_TYPE_DONTKNOW;
+
+ // Zuerst die Tabs testen
+ Rectangle aRect;
+ if ( mpData->pTabs )
+ {
+ aRect.Bottom() = nHitBottom;
+ aRect.Top() = aRect.Bottom()-RULER_TAB_HEIGHT-RULER_OFF;
+
+ for ( i = mpData->nTabs; i; i-- )
+ {
+ nStyle = mpData->pTabs[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ nStyle &= RULER_TAB_STYLE;
+
+ // Default-Tabs werden nur angezeigt
+ if ( nStyle != RULER_TAB_DEFAULT )
+ {
+ n1 = mpData->pTabs[i-1].nPos;
+
+ if ( nStyle == RULER_TAB_LEFT )
+ {
+ aRect.Left() = n1;
+ aRect.Right() = n1+RULER_TAB_WIDTH-1;
+ }
+ else if ( nStyle == RULER_TAB_RIGHT )
+ {
+ aRect.Right() = n1;
+ aRect.Left() = n1-RULER_TAB_WIDTH-1;
+ }
+ else
+ {
+ aRect.Left() = n1-RULER_TAB_CWIDTH2+1;
+ aRect.Right() = n1-RULER_TAB_CWIDTH2+RULER_TAB_CWIDTH;
+ }
+
+ if ( aRect.IsInside( Point( nX, nY ) ) )
+ {
+ pHitTest->eType = RULER_TYPE_TAB;
+ pHitTest->nAryPos = i-1;
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ // Dann die Einzuege
+ if ( mpData->pIndents )
+ {
+ long nIndentHeight = (mnVirHeight/2) - 1;
+ long nIndentWidth2 = nIndentHeight-3;
+
+ for ( i = mpData->nIndents; i; i-- )
+ {
+ nStyle = mpData->pIndents[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ nStyle &= RULER_INDENT_STYLE;
+ n1 = mpData->pIndents[i-1].nPos;
+
+ if ( nStyle == RULER_INDENT_BOTTOM )
+ {
+ aRect.Left() = n1-nIndentWidth2;
+ aRect.Right() = n1+nIndentWidth2;
+ aRect.Top() = nHitBottom-nIndentHeight-RULER_OFF+1;
+ aRect.Bottom() = nHitBottom;
+ }
+ else
+ {
+ aRect.Left() = n1-nIndentWidth2;
+ aRect.Right() = n1+nIndentWidth2;
+ aRect.Top() = 0;
+ aRect.Bottom() = nIndentHeight+RULER_OFF-1;
+ }
+
+ if ( aRect.IsInside( Point( nX, nY ) ) )
+ {
+ pHitTest->eType = RULER_TYPE_INDENT;
+ pHitTest->nAryPos = i-1;
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ // Jetzt zaehlt nichts mehr, was links oder rechts uebersteht
+ if ( (nXTemp < mpData->nRulVirOff) || (nXTemp > mpData->nRulVirOff+mpData->nRulWidth) )
+ {
+ pHitTest->nPos = 0;
+ pHitTest->eType = RULER_TYPE_OUTSIDE;
+ return FALSE;
+ }
+
+ // Danach die Spalten testen
+ for ( i = mpData->nBorders; i; i-- )
+ {
+ n1 = mpData->pBorders[i-1].nPos;
+ n2 = n1 + mpData->pBorders[i-1].nWidth;
+
+ // Spalten werden mit mindestens 3 Pixel breite gezeichnet
+ if ( !mpData->pBorders[i-1].nWidth )
+ {
+ n1--;
+ n2++;
+ }
+
+ if ( (nX >= n1) && (nX <= n2) )
+ {
+ nStyle = mpData->pBorders[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ pHitTest->eType = RULER_TYPE_BORDER;
+ pHitTest->nAryPos = i-1;
+
+ if ( !(nStyle & RULER_BORDER_SIZEABLE) )
+ {
+ if ( nStyle & RULER_BORDER_MOVEABLE )
+ {
+ pHitTest->bSizeBar = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
+ }
+ }
+ else
+ {
+ long nMOff = RULER_MOUSE_BORDERWIDTH;
+ while ( nMOff*2 >= (n2-n1-RULER_MOUSE_BORDERMOVE) )
+ {
+ if ( nMOff < 2 )
+ {
+ nMOff = 0;
+ break;
+ }
+ else
+ nMOff--;
+ }
+
+ if ( nX <= n1+nMOff )
+ {
+ pHitTest->bSize = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_1;
+ }
+ else if ( nX >= n2-nMOff )
+ {
+ pHitTest->bSize = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_2;
+ }
+ else
+ {
+ if ( nStyle & RULER_BORDER_MOVEABLE )
+ {
+ pHitTest->bSizeBar = TRUE;
+ pHitTest->mnDragSize = RULER_DRAGSIZE_MOVE;
+ }
+ }
+ }
+
+ return TRUE;
+ }
+ }
+ }
+
+ // Und zum Schluss die Raender
+ if ( (mpData->nMargin1Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
+ {
+ n1 = mpData->nMargin1;
+ if ( (nX >= n1-RULER_MOUSE_MARGINWIDTH) && (nX <= n1+RULER_MOUSE_MARGINWIDTH) )
+ {
+ pHitTest->eType = RULER_TYPE_MARGIN1;
+ pHitTest->bSize = TRUE;
+ return TRUE;
+ }
+ }
+ if ( (mpData->nMargin2Style & (RULER_MARGIN_SIZEABLE | RULER_STYLE_INVISIBLE)) == RULER_MARGIN_SIZEABLE )
+ {
+ n1 = mpData->nMargin2;
+ if ( (nX >= n1-RULER_MOUSE_MARGINWIDTH) && (nX <= n1+RULER_MOUSE_MARGINWIDTH) )
+ {
+ pHitTest->eType = RULER_TYPE_MARGIN2;
+ pHitTest->bSize = TRUE;
+ return TRUE;
+ }
+ }
+
+ // Jetzt nocheinmal die Tabs testen, nur mit etwas mehr spielraum
+ if ( mpData->pTabs )
+ {
+ aRect.Top() = RULER_OFF;
+ aRect.Bottom() = nHitBottom;
+
+ for ( i = mpData->nTabs; i; i-- )
+ {
+ nStyle = mpData->pTabs[i-1].nStyle;
+ if ( !(nStyle & RULER_STYLE_INVISIBLE) )
+ {
+ nStyle &= RULER_TAB_STYLE;
+
+ // Default-Tabs werden nur angezeigt
+ if ( nStyle != RULER_TAB_DEFAULT )
+ {
+ n1 = mpData->pTabs[i-1].nPos;
+
+ if ( nStyle == RULER_TAB_LEFT )
+ {
+ aRect.Left() = n1;
+ aRect.Right() = n1+RULER_TAB_WIDTH-1;
+ }
+ else if ( nStyle == RULER_TAB_RIGHT )
+ {
+ aRect.Right() = n1;
+ aRect.Left() = n1-RULER_TAB_WIDTH-1;
+ }
+ else
+ {
+ aRect.Left() = n1-RULER_TAB_CWIDTH2+1;
+ aRect.Right() = n1-RULER_TAB_CWIDTH2+RULER_TAB_CWIDTH;
+ }
+
+ aRect.Left()--;
+ aRect.Right()++;
+
+ if ( aRect.IsInside( Point( nX, nY ) ) )
+ {
+ pHitTest->eType = RULER_TYPE_TAB;
+ pHitTest->nAryPos = i-1;
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::ImplDocHitTest( const Point& rPos, RulerType eDragType,
+ ImplRulerHitTest* pHitTest ) const
+{
+ Point aPos = rPos;
+
+ if ( mnWinStyle & WB_HORZ )
+ aPos.X() += mnWinOff;
+ else
+ aPos.Y() += mnWinOff;
+
+ if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_DONTKNOW) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPos.Y() = RULER_OFF+1;
+ else
+ aPos.X() = RULER_OFF+1;
+
+ // HitTest durchfuehren
+ if ( ImplHitTest( aPos, pHitTest ) )
+ {
+ if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
+ return TRUE;
+ }
+ }
+
+ if ( (eDragType == RULER_TYPE_INDENT) || (eDragType == RULER_TYPE_TAB) ||
+ (eDragType == RULER_TYPE_DONTKNOW) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPos.Y() = mnHeight-RULER_OFF-1;
+ else
+ aPos.X() = mnWidth-RULER_OFF-1;
+
+ // HitTest durchfuehren
+ if ( ImplHitTest( aPos, pHitTest ) )
+ {
+ if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
+ return TRUE;
+ }
+ }
+
+ if ( (eDragType == RULER_TYPE_MARGIN1) || (eDragType == RULER_TYPE_MARGIN2) ||
+ (eDragType == RULER_TYPE_BORDER) || (eDragType == RULER_TYPE_DONTKNOW) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPos.Y() = RULER_OFF + (mnVirHeight/2);
+ else
+ aPos.X() = RULER_OFF + (mnVirHeight/2);
+
+ // HitTest durchfuehren
+ if ( ImplHitTest( aPos, pHitTest ) )
+ {
+ if ( (pHitTest->eType == eDragType) || (eDragType == RULER_TYPE_DONTKNOW) )
+ return TRUE;
+ }
+ }
+
+ // Auf DontKnow setzen
+ pHitTest->eType = RULER_TYPE_DONTKNOW;
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::ImplStartDrag( ImplRulerHitTest* pHitTest, USHORT nModifier )
+{
+ // Wenn eine Spalte angeklick wurde, die weder verschiebar noch
+ // in der Groesse aenderbar ist, brauchen wir auch kein Drag ausloesen
+ if ( (pHitTest->eType == RULER_TYPE_BORDER) &&
+ !pHitTest->bSize && !pHitTest->bSizeBar )
+ return FALSE;
+
+ // Dragdaten setzen
+ meDragType = pHitTest->eType;
+ mnDragPos = pHitTest->nPos;
+ mnDragAryPos = pHitTest->nAryPos;
+ mnDragSize = pHitTest->mnDragSize;
+ mnDragModifier = nModifier;
+ maDragData = maData;
+ mpData = &maDragData;
+
+ // Handler rufen
+ if ( StartDrag() )
+ {
+ // Wenn der Handler das Draggen erlaubt, dann das Draggen
+ // initialisieren
+ ImplInvertLines();
+ mbDrag = TRUE;
+ mnStartDragPos = mnDragPos;
+ StartTracking();
+ return TRUE;
+ }
+ else
+ {
+ // Ansonsten muessen wir die Daten zuruecksetzen
+ meDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+ mnDragSize = 0;
+ mnDragModifier = 0;
+ mpData = &maData;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplDrag( const Point& rPos )
+{
+ long nX;
+ long nY;
+ long nOutHeight;
+
+ if ( mnWinStyle & WB_HORZ )
+ {
+ nX = rPos.X();
+ nY = rPos.Y();
+ nOutHeight = mnHeight;
+ }
+ else
+ {
+ nX = rPos.Y();
+ nY = rPos.X();
+ nOutHeight = mnWidth;
+ }
+
+ // X berechnen und einpassen
+ nX -= mnVirOff;
+ if ( nX < mpData->nRulVirOff )
+ {
+ nX = mpData->nRulVirOff;
+ mnDragScroll = RULER_SCROLL_1;
+ }
+ else if ( nX > mpData->nRulVirOff+mpData->nRulWidth )
+ {
+ nX = mpData->nRulVirOff+mpData->nRulWidth;
+ mnDragScroll = RULER_SCROLL_2;
+ }
+ nX -= mpData->nNullVirOff;
+
+ // Wenn oberhalb oder links vom Lineal, dann alte Werte
+ mbDragDelete = FALSE;
+ if ( nY < 0 )
+ {
+ if ( !mbDragCanceled )
+ {
+ // Daten wiederherstellen
+ mbDragCanceled = TRUE;
+ ImplRulerData aTempData;
+ aTempData = maDragData;
+ maDragData = maData;
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+
+ // Handler rufen
+ mnDragPos = mnStartDragPos;
+ Drag();
+
+ // Und neu ausgeben (zeitverzoegert)
+/*
+ mnUpdateFlags |= RULER_UPDATE_DRAW;
+ if ( mnUpdateEvtId )
+ Application::RemoveUserEvent( mnUpdateEvtId );
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+*/
+ ImplDraw();
+
+ // Daten wieder wie vor dem Cancel herstellen
+ maDragData = aTempData;
+ }
+ }
+ else
+ {
+ mbDragCanceled = FALSE;
+
+ // +2, damit nicht so schnell die Tabs geloescht werden
+ if ( nY > nOutHeight+2 )
+ mbDragDelete = TRUE;
+
+ mnDragPos = nX;
+
+ // Handler rufen
+ Drag();
+
+ // Und neu ausgeben
+ if ( mbFormat )
+ ImplDraw();
+ }
+
+ mnDragScroll = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ImplEndDrag()
+{
+ // Werte uebernehmen
+ if ( mbDragCanceled )
+ maDragData = maData;
+ else
+ maData = maDragData;
+ mpData = &maData;
+ mbDrag = FALSE;
+
+ // Handler rufen
+ EndDrag();
+
+ // Drag-Werte zuruecksetzen
+ meDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+ mnDragSize = 0;
+ mbDragCanceled = FALSE;
+ mbDragDelete = FALSE;
+ mnDragModifier = 0;
+ mnDragScroll = 0;
+ mnStartDragPos = 0;
+
+ // Und neu ausgeben
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( Ruler, ImplUpdateHdl, void*, EMPTYARG )
+{
+ mnUpdateEvtId = 0;
+
+ // Feststellen, was upgedatet werden muss
+ if ( mnUpdateFlags & RULER_UPDATE_DRAW )
+ {
+ mnUpdateFlags = 0;
+ ImplDraw();
+ }
+ else if ( mnUpdateFlags & RULER_UPDATE_LINES )
+ {
+ mnUpdateFlags = 0;
+ ImplInvertLines();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && !IsTracking() )
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT nMouseClicks = rMEvt.GetClicks();
+ USHORT nMouseModifier = rMEvt.GetModifier();
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( mbFormat )
+ {
+ ImplDraw();
+ mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ if ( maExtraRect.IsInside( aMousePos ) )
+ {
+ mnExtraClicks = nMouseClicks;
+ mnExtraModifier = nMouseModifier;
+ ExtraDown();
+ mnExtraClicks = 0;
+ mnExtraModifier = 0;
+ }
+ else
+ {
+ ImplRulerHitTest aHitTest;
+
+ if ( nMouseClicks == 1 )
+ {
+ if ( ImplHitTest( aMousePos, &aHitTest ) )
+ ImplStartDrag( &aHitTest, nMouseModifier );
+ else
+ {
+ // Position innerhalb des Lineal-Bereiches
+ if ( aHitTest.eType == RULER_TYPE_DONTKNOW )
+ {
+ mnDragPos = aHitTest.nPos;
+ Click();
+ mnDragPos = 0;
+
+ // Nocheinmal HitTest durchfuehren, da durch den Click
+ // zum Beispiel ein neuer Tab gesetzt werden konnte
+ if ( ImplHitTest( aMousePos, &aHitTest ) )
+ ImplStartDrag( &aHitTest, nMouseModifier );
+ }
+ }
+ }
+ else
+ {
+ if ( ImplHitTest( aMousePos, &aHitTest ) )
+ {
+ mnDragPos = aHitTest.nPos;
+ mnDragAryPos = aHitTest.nAryPos;
+ }
+ meDragType = aHitTest.eType;
+
+ DoubleClick();
+
+ meDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::MouseMove( const MouseEvent& rMEvt )
+{
+ PointerStyle ePtrStyle = POINTER_ARROW;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( mbFormat )
+ {
+ ImplDraw();
+ mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ ImplRulerHitTest aHitTest;
+ if ( ImplHitTest( rMEvt.GetPosPixel(), &aHitTest ) )
+ {
+ if ( aHitTest.bSize )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ ePtrStyle = POINTER_ESIZE;
+ else
+ ePtrStyle = POINTER_SSIZE;
+ }
+ else if ( aHitTest.bSizeBar )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ ePtrStyle = POINTER_HSIZEBAR;
+ else
+ ePtrStyle = POINTER_VSIZEBAR;
+ }
+ }
+
+ SetPointer( Pointer( ePtrStyle ) );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ // Bei Abbruch, den alten Status wieder herstellen
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ mbDragCanceled = TRUE;
+ mbFormat = TRUE;
+ }
+
+ ImplEndDrag();
+ }
+ else
+ ImplDrag( rTEvt.GetMouseEvent().GetPosPixel() );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Paint( const Rectangle& )
+{
+ ImplDraw();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Extra-Field beruecksichtigen
+ if ( mnWinStyle & WB_EXTRAFIELD )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Top() ),
+ Point( maExtraRect.Right()-1, maExtraRect.Top() ) );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Top() ),
+ Point( maExtraRect.Left(), maExtraRect.Bottom()-1 ) );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Bottom()-1 ),
+ Point( maExtraRect.Right()-1, maExtraRect.Bottom()-1 ) );
+ DrawLine( Point( maExtraRect.Right()-1, maExtraRect.Top() ),
+ Point( maExtraRect.Right()-1, maExtraRect.Bottom()-1 ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( maExtraRect.Left()+1, maExtraRect.Top()+1 ),
+ Point( maExtraRect.Right()-2, maExtraRect.Top()+1 ) );
+ DrawLine( Point( maExtraRect.Left()+1, maExtraRect.Top()+1 ),
+ Point( maExtraRect.Left()+1, maExtraRect.Bottom()-2 ) );
+ DrawLine( Point( maExtraRect.Left(), maExtraRect.Bottom() ),
+ Point( maExtraRect.Right(), maExtraRect.Bottom() ) );
+ DrawLine( Point( maExtraRect.Right(), maExtraRect.Top() ),
+ Point( maExtraRect.Right(), maExtraRect.Bottom() ) );
+ }
+ else
+ {
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ SetFillColor( rStyleSettings.GetWindowColor() );
+ DrawRect( maExtraRect );
+ }
+
+ // Imhalt vom Extrafeld ausgeben
+ ImplDrawExtra( TRUE );
+ }
+
+ if ( mnWinStyle & WB_BORDER )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( mnBorderOff, mnHeight-2 ),
+ Point( mnWidth, mnHeight-2 ) );
+ if ( mnBorderOff )
+ {
+ DrawLine( Point( mnBorderOff-1, mnHeight-2 ),
+ Point( mnBorderOff-1, mnHeight-1 ) );
+ }
+ }
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( Point( mnBorderOff, mnHeight-1 ),
+ Point( mnWidth, mnHeight-1 ) );
+ }
+ else
+ {
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( mnWidth-2, mnBorderOff ),
+ Point( mnWidth-2, mnHeight ) );
+ if ( mnBorderOff )
+ {
+ DrawLine( Point( mnWidth-2, mnBorderOff-1 ),
+ Point( mnWidth-1, mnBorderOff-1 ) );
+ }
+ }
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ DrawLine( Point( mnWidth-1, mnBorderOff ),
+ Point( mnWidth-1, mnHeight ) );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Resize()
+{
+ Size aWinSize = GetOutputSizePixel();
+
+ long nNewHeight;
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( aWinSize.Height() != mnHeight )
+ nNewHeight = aWinSize.Height();
+ else
+ nNewHeight = 0;
+ }
+ else
+ {
+ if ( aWinSize.Width() != mnWidth )
+ nNewHeight = aWinSize.Width();
+ else
+ nNewHeight = 0;
+ }
+
+ // Hier schon Linien loeschen
+ BOOL bVisible = IsReallyVisible();
+ if ( bVisible && mpData->nLines )
+ {
+ ImplInvertLines();
+ mnUpdateFlags |= RULER_UPDATE_LINES;
+ if ( !mnUpdateEvtId )
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+ }
+ mbFormat = TRUE;
+
+ // Wenn sich die Hoehe bzw. Breite aendert, dann muessen besimmte Werte
+ // neu berechnet werden
+ if ( nNewHeight )
+ {
+ mbCalc = TRUE;
+ mnVirHeight = nNewHeight - mnBorderWidth - (RULER_OFF*2);
+ ImplInitExtraField( FALSE );
+ }
+ else
+ {
+ if ( mpData->bAutoPageWidth )
+ ImplUpdate( TRUE );
+ else if ( mbAutoWinWidth )
+ mbCalc = TRUE;
+ }
+
+ // Wenn Ruler eine Groesse hat, dann Groesse vom VirtualDevice setzen
+ if ( (mnVirWidth > RULER_MIN_SIZE) ||
+ ((aWinSize.Width() > RULER_MIN_SIZE) && (aWinSize.Height() > RULER_MIN_SIZE)) )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ mnVirWidth = aWinSize.Width()-mnVirOff;
+ else
+ mnVirWidth = aWinSize.Height()-mnVirOff;
+ if ( mnVirWidth < RULER_MIN_SIZE )
+ mnVirWidth = 0;
+ }
+
+ // Gegebenenfalls ein Teil vom Rand loeschen, da 3D-Effekt/Trennlinie am
+ // Fensterrand
+ if ( bVisible )
+ {
+ if ( nNewHeight )
+ Invalidate();
+ else if ( mpData->bAutoPageWidth )
+ {
+ // Nur bei AutoPageWidth haben wir rechts einen 3D-Effekt,
+ // der sich der Fensterbreite anpasst und deshalb neu gezeichnet
+ // werden muss
+ Rectangle aRect;
+
+ if ( mnWinStyle & WB_HORZ )
+ {
+ if ( mnWidth < aWinSize.Width() )
+ aRect.Left() = mnWidth-RULER_RESIZE_OFF;
+ else
+ aRect.Left() = aWinSize.Width()-RULER_RESIZE_OFF;
+ aRect.Right() = aRect.Left()+RULER_RESIZE_OFF;
+ aRect.Top() = RULER_OFF;
+ aRect.Bottom() = RULER_OFF+mnVirHeight;
+ }
+ else
+ {
+ if ( mnHeight < aWinSize.Height() )
+ aRect.Top() = mnHeight-RULER_RESIZE_OFF;
+ else
+ aRect.Top() = aWinSize.Height()-RULER_RESIZE_OFF;
+ aRect.Bottom() = aRect.Top()+RULER_RESIZE_OFF;
+ aRect.Left() = RULER_OFF;
+ aRect.Right() = RULER_OFF+mnVirHeight;
+ }
+
+ Invalidate( aRect );
+ }
+ }
+
+ // Neue Groesse merken
+ mnWidth = aWinSize.Width();
+ mnHeight = aWinSize.Height();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplFormat();
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDraw();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long Ruler::StartDrag()
+{
+ if ( maStartDragHdl.IsSet() )
+ return maStartDragHdl.Call( this );
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Drag()
+{
+ maDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::EndDrag()
+{
+ maEndDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Click()
+{
+ maClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::ExtraDown()
+{
+ maExtraDownHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Activate()
+{
+ mbActive = TRUE;
+
+ // Positionslinien wieder anzeigen (erst hinter mbActive=TRUE rufen, da
+ // von ImplInvertLines() ausgewertet wird). Das Zeichnen der Linien
+ // wird verzoegert, damit im vermutlich noch nicht gepainteten Zustand
+ // Linien gezeichnet werden.
+ mnUpdateFlags |= RULER_UPDATE_LINES;
+ if ( !mnUpdateEvtId )
+ mnUpdateEvtId = Application::PostUserEvent( LINK( this, Ruler, ImplUpdateHdl ), NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::Deactivate()
+{
+ // Positionslinien loeschen (schon vor mbActive=FALSE rufen, da
+ // von ImplInvertLines() ausgewertet wird)
+ ImplInvertLines();
+
+ mbActive = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Ruler::StartDocDrag( const MouseEvent& rMEvt, RulerType eDragType )
+{
+ if ( !mbDrag )
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ USHORT nMouseClicks = rMEvt.GetClicks();
+ USHORT nMouseModifier = rMEvt.GetModifier();
+ ImplRulerHitTest aHitTest;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( mbFormat )
+ {
+ ImplDraw();
+ mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ if ( nMouseClicks == 1 )
+ {
+ if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
+ {
+ Pointer aPtr;
+
+ if ( aHitTest.bSize )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPtr = Pointer( POINTER_ESIZE );
+ else
+ aPtr = Pointer( POINTER_SSIZE );
+ }
+ else if ( aHitTest.bSizeBar )
+ {
+ if ( mnWinStyle & WB_HORZ )
+ aPtr = Pointer( POINTER_HSIZEBAR );
+ else
+ aPtr = Pointer( POINTER_VSIZEBAR );
+ }
+ SetPointer( aPtr );
+ return ImplStartDrag( &aHitTest, nMouseModifier );
+ }
+ }
+ else if ( nMouseClicks == 2 )
+ {
+ if ( ImplDocHitTest( aMousePos, eDragType, &aHitTest ) )
+ {
+ mnDragPos = aHitTest.nPos;
+ mnDragAryPos = aHitTest.nAryPos;
+ }
+ eDragType = aHitTest.eType;
+
+ DoubleClick();
+
+ eDragType = RULER_TYPE_DONTKNOW;
+ mnDragPos = 0;
+ mnDragAryPos = 0;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+RulerType Ruler::GetDocType( const Point& rPos, RulerType eDragType,
+ USHORT* pAryPos ) const
+{
+ ImplRulerHitTest aHitTest;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( IsReallyVisible() && mbFormat )
+ {
+ ((Ruler*)this)->ImplDraw();
+ ((Ruler*)this)->mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ // HitTest durchfuehren
+ ImplDocHitTest( rPos, eDragType, &aHitTest );
+
+ // Werte zurueckgeben
+ if ( pAryPos )
+ *pAryPos = aHitTest.nAryPos;
+ return aHitTest.eType;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::CancelDrag()
+{
+ if ( mbDrag )
+ {
+ ImplDrag( Point( -1, -1 ) );
+ ImplEndDrag();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+RulerType Ruler::GetType( const Point& rPos, USHORT* pAryPos ) const
+{
+ ImplRulerHitTest aHitTest;
+
+ // Gegebenenfalls Lineal updaten (damit mit den richtigen Daten
+ // gearbeitet wird und die Anzeige auch zur Bearbeitung passt)
+ if ( IsReallyVisible() && mbFormat )
+ {
+ ((Ruler*)this)->ImplDraw();
+ ((Ruler*)this)->mnUpdateFlags &= ~RULER_UPDATE_DRAW;
+ }
+
+ // HitTest durchfuehren
+ ImplHitTest( rPos, &aHitTest );
+
+ // Werte zurueckgeben
+ if ( pAryPos )
+ *pAryPos = aHitTest.nAryPos;
+ return aHitTest.eType;
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetWinPos( long nNewOff, long nNewWidth )
+{
+ // Gegebenenfalls werden die Breiten automatisch berechnet
+ if ( !nNewWidth )
+ mbAutoWinWidth = TRUE;
+ else
+ mbAutoWinWidth = FALSE;
+
+ // Werte setzen (werden in ImplFormat gegebenenfalls mitberechnet)
+ mnWinOff = nNewOff;
+ mnWinWidth = nNewWidth;
+ ImplUpdate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetPagePos( long nNewOff, long nNewWidth )
+{
+ // Muessen wir ueberhaupt was machen
+ if ( (mpData->nPageOff == nNewOff) && (mpData->nPageWidth == nNewWidth) )
+ return;
+
+ // Gegebenenfalls werden die Breiten automatisch berechnet
+ if ( !nNewWidth )
+ mpData->bAutoPageWidth = TRUE;
+ else
+ mpData->bAutoPageWidth = FALSE;
+
+ // Werte setzen (werden in ImplFormat gegebenenfalls mitberechnet)
+ mpData->nPageOff = nNewOff;
+ mpData->nPageWidth = nNewWidth;
+ ImplUpdate( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetBorderPos( long nOff )
+{
+ if ( mnWinStyle & WB_BORDER )
+ {
+ if ( mnBorderOff != nOff )
+ {
+ mnBorderOff = nOff;
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetUnit( FieldUnit eNewUnit )
+{
+ if ( meUnit != eNewUnit )
+ {
+ meUnit = eNewUnit;
+ switch ( meUnit )
+ {
+ case FUNIT_MM:
+ mnUnitIndex = RULER_UNIT_MM;
+ break;
+ case FUNIT_CM:
+ mnUnitIndex = RULER_UNIT_CM;
+ break;
+ case FUNIT_M:
+ mnUnitIndex = RULER_UNIT_M;
+ break;
+ case FUNIT_KM:
+ mnUnitIndex = RULER_UNIT_KM;
+ break;
+ case FUNIT_INCH:
+ mnUnitIndex = RULER_UNIT_INCH;
+ break;
+ case FUNIT_FOOT:
+ mnUnitIndex = RULER_UNIT_FOOT;
+ break;
+ case FUNIT_MILE:
+ mnUnitIndex = RULER_UNIT_MILE;
+ break;
+ case FUNIT_POINT:
+ mnUnitIndex = RULER_UNIT_POINT;
+ break;
+ case FUNIT_PICA:
+ mnUnitIndex = RULER_UNIT_PICA;
+ break;
+
+#ifdef DBG_UTIL
+ default:
+ DBG_ERRORFILE( "Ruler::SetUnit() - Wrong Unit" );
+ break;
+#endif
+ }
+
+ maMapMode.SetMapUnit( aImplRulerUnitTab[mnUnitIndex].eMapUnit );
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetZoom( const Fraction& rNewZoom )
+{
+ DBG_ASSERT( rNewZoom.GetNumerator(), "Ruler::SetZoom() with scale 0 is not allowed" );
+
+ if ( maZoom != rNewZoom )
+ {
+ maZoom = rNewZoom;
+ maMapMode.SetScaleX( maZoom );
+ maMapMode.SetScaleY( maZoom );
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetExtraType( RulerExtra eNewExtraType, USHORT nStyle )
+{
+ if ( mnWinStyle & WB_EXTRAFIELD )
+ {
+ meExtraType = eNewExtraType;
+ mnExtraStyle = nStyle;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDrawExtra( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetNullOffset( long nPos )
+{
+ if ( mpData->nNullOff != nPos )
+ {
+ mpData->nNullOff = nPos;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetMargin1( long nPos, USHORT nMarginStyle )
+{
+ if ( (mpData->nMargin1 != nPos) || (mpData->nMargin1Style != nMarginStyle) )
+ {
+ mpData->nMargin1 = nPos;
+ mpData->nMargin1Style = nMarginStyle;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetMargin2( long nPos, USHORT nMarginStyle )
+{
+ DBG_ASSERT( (nPos >= mpData->nMargin1) ||
+ (mpData->nMargin1Style & RULER_STYLE_INVISIBLE) ||
+ (mpData->nMargin2Style & RULER_STYLE_INVISIBLE),
+ "Ruler::SetMargin2() - Margin2 < Margin1" );
+
+ if ( (mpData->nMargin2 != nPos) || (mpData->nMargin2Style != nMarginStyle) )
+ {
+ mpData->nMargin2 = nPos;
+ mpData->nMargin2Style = nMarginStyle;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetLines( USHORT n, const RulerLine* pLineAry )
+{
+ // Testen, ob sich was geaendert hat
+ if ( mpData->nLines == n )
+ {
+ USHORT i = n;
+ const RulerLine* pAry1 = mpData->pLines;
+ const RulerLine* pAry2 = pLineAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ // Neue Werte setzen und neu ausgeben
+ BOOL bMustUpdate;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ bMustUpdate = TRUE;
+ else
+ bMustUpdate = FALSE;
+
+ // Alte Linien loeschen
+ if ( bMustUpdate )
+ ImplInvertLines();
+
+ // Neue Daten setzen
+ if ( !n || !pLineAry )
+ {
+ if ( !mpData->pLines )
+ return;
+ delete mpData->pLines;
+ mpData->nLines = 0;
+ mpData->pLines = NULL;
+ }
+ else
+ {
+ if ( mpData->nLines != n )
+ {
+ if ( mpData->pLines )
+ delete mpData->pLines;
+ mpData->nLines = n;
+ mpData->pLines = new RulerLine[n];
+ }
+
+ memcpy( mpData->pLines, pLineAry, n*sizeof( RulerLine ) );
+
+ // Linien neu ausgeben
+ if ( bMustUpdate )
+ ImplInvertLines();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetArrows( USHORT n, const RulerArrow* pArrowAry )
+{
+ if ( !n || !pArrowAry )
+ {
+ if ( !mpData->pArrows )
+ return;
+ delete mpData->pArrows;
+ mpData->nArrows = 0;
+ mpData->pArrows = NULL;
+ }
+ else
+ {
+ if ( mpData->nArrows != n )
+ {
+ if ( mpData->pArrows )
+ delete mpData->pArrows;
+ mpData->nArrows = n;
+ mpData->pArrows = new RulerArrow[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerArrow* pAry1 = mpData->pArrows;
+ const RulerArrow* pAry2 = pArrowAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nWidth != pAry2->nWidth) ||
+ (pAry1->nLogWidth != pAry2->nLogWidth) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pArrows, pArrowAry, n*sizeof( RulerArrow ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetBorders( USHORT n, const RulerBorder* pBrdAry )
+{
+ if ( !n || !pBrdAry )
+ {
+ if ( !mpData->pBorders )
+ return;
+ delete mpData->pBorders;
+ mpData->nBorders = 0;
+ mpData->pBorders = NULL;
+ }
+ else
+ {
+ if ( mpData->nBorders != n )
+ {
+ if ( mpData->pBorders )
+ delete mpData->pBorders;
+ mpData->nBorders = n;
+ mpData->pBorders = new RulerBorder[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerBorder* pAry1 = mpData->pBorders;
+ const RulerBorder* pAry2 = pBrdAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nWidth != pAry2->nWidth) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pBorders, pBrdAry, n*sizeof( RulerBorder ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetIndents( USHORT n, const RulerIndent* pIndentAry )
+{
+ DBG_ASSERT( mnWinStyle & WB_HORZ,
+ "Ruler::SetIndents() not allowed when WB_VERT" );
+
+ if ( !n || !pIndentAry )
+ {
+ if ( !mpData->pIndents )
+ return;
+ delete mpData->pIndents;
+ mpData->nIndents = 0;
+ mpData->pIndents = NULL;
+ }
+ else
+ {
+ if ( mpData->nIndents != n )
+ {
+ if ( mpData->pIndents )
+ delete mpData->pIndents;
+ mpData->nIndents = n;
+ mpData->pIndents = new RulerIndent[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerIndent* pAry1 = mpData->pIndents;
+ const RulerIndent* pAry2 = pIndentAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pIndents, pIndentAry, n*sizeof( RulerIndent ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetTabs( USHORT n, const RulerTab* pTabAry )
+{
+ DBG_ASSERT( mnWinStyle & WB_HORZ,
+ "Ruler::SetTabs() not allowed when WB_VERT" );
+
+ if ( !n || !pTabAry )
+ {
+ if ( !mpData->pTabs )
+ return;
+ delete mpData->pTabs;
+ mpData->nTabs = 0;
+ mpData->pTabs = NULL;
+ }
+ else
+ {
+ if ( mpData->nTabs != n )
+ {
+ if ( mpData->pTabs )
+ delete mpData->pTabs;
+ mpData->nTabs = n;
+ mpData->pTabs = new RulerTab[n];
+ }
+ else
+ {
+ USHORT i = n;
+ const RulerTab* pAry1 = mpData->pTabs;
+ const RulerTab* pAry2 = pTabAry;
+ while ( i )
+ {
+ if ( (pAry1->nPos != pAry2->nPos) ||
+ (pAry1->nStyle != pAry2->nStyle) )
+ break;
+ pAry1++;
+ pAry2++;
+ i--;
+ }
+ if ( !i )
+ return;
+ }
+
+ memcpy( mpData->pTabs, pTabAry, n*sizeof( RulerTab ) );
+ }
+
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::SetStyle( WinBits nStyle )
+{
+ if ( mnWinStyle != nStyle )
+ {
+ mnWinStyle = nStyle;
+ ImplInitExtraField( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Ruler::DrawTab( OutputDevice* pDevice, const Point& rPos, USHORT nStyle )
+{
+ const StyleSettings& rStyleSettings = pDevice->GetSettings().GetStyleSettings();
+ Point aPos( rPos );
+ USHORT nTabStyle = nStyle & RULER_TAB_STYLE;
+
+ pDevice->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ pDevice->SetLineColor();
+ pDevice->SetFillColor( pDevice->GetSettings().GetStyleSettings().GetWindowTextColor() );
+ ImplCenterTabPos( aPos, nTabStyle );
+ ImplDrawRulerTab( pDevice, aPos, nTabStyle );
+ pDevice->Pop();
+}