summaryrefslogtreecommitdiff
path: root/svtools/source/control
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/control')
-rw-r--r--svtools/source/control/calendar.cxx2963
-rw-r--r--svtools/source/control/calendar.src166
-rw-r--r--svtools/source/control/ctrlbox.cxx1227
-rw-r--r--svtools/source/control/ctrlbox.src85
-rw-r--r--svtools/source/control/ctrldll.cxx112
-rw-r--r--svtools/source/control/ctrltool.cxx865
-rw-r--r--svtools/source/control/ctrltool.src425
-rw-r--r--svtools/source/control/filectrl.cxx307
-rw-r--r--svtools/source/control/filectrl.src85
-rw-r--r--svtools/source/control/fmtfield.cxx1017
-rw-r--r--svtools/source/control/headbar.cxx1673
-rw-r--r--svtools/source/control/makefile.mk141
-rw-r--r--svtools/source/control/prgsbar.cxx270
-rw-r--r--svtools/source/control/reginfo.cxx785
-rw-r--r--svtools/source/control/ruler.cxx3064
-rw-r--r--svtools/source/control/scrwin.cxx603
-rw-r--r--svtools/source/control/stdctrl.cxx77
-rw-r--r--svtools/source/control/stdmenu.cxx446
-rw-r--r--svtools/source/control/tabbar.cxx2588
-rw-r--r--svtools/source/control/taskbar.cxx645
-rw-r--r--svtools/source/control/taskbox.cxx406
-rw-r--r--svtools/source/control/taskmisc.cxx416
-rw-r--r--svtools/source/control/taskstat.cxx769
-rw-r--r--svtools/source/control/valueset.cxx2461
24 files changed, 21596 insertions, 0 deletions
diff --git a/svtools/source/control/calendar.cxx b/svtools/source/control/calendar.cxx
new file mode 100644
index 000000000000..bc85863fb7b3
--- /dev/null
+++ b/svtools/source/control/calendar.cxx
@@ -0,0 +1,2963 @@
+/*************************************************************************
+ *
+ * $RCSfile: calendar.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _TABLE_HXX
+#include <tools/table.hxx>
+#endif
+#ifndef _HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _MENU_HXX
+#include <vcl/menu.hxx>
+#endif
+#ifndef _DECOVIEW_HXX
+#include <vcl/decoview.hxx>
+#endif
+#ifndef _FLOATWIN_HXX
+#include <vcl/floatwin.hxx>
+#endif
+#ifndef _BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#ifndef _FIXED_HXX
+#include <vcl/fixed.hxx>
+#endif
+
+#define _SV_CALENDAR_CXX
+#include <svtools.hrc>
+#include <svtdata.hxx>
+#include <calendar.hxx>
+
+// =======================================================================
+
+#define DAY_OFFX 4
+#define DAY_OFFY 2
+#define MONTH_BORDERX 4
+#define MONTH_OFFY 3
+#define WEEKNUMBER_OFFX 4
+#define WEEKDAY_OFFY 3
+#define TITLE_OFFY 3
+#define TITLE_BORDERY 2
+#define SPIN_OFFX 4
+#define SPIN_OFFY TITLE_BORDERY
+
+#define WEEKNUMBER_HEIGHT 85
+
+#define CALENDAR_HITTEST_DAY ((USHORT)0x0001)
+#define CALENDAR_HITTEST_WEEK ((USHORT)0x0002)
+#define CALENDAR_HITTEST_MONTHTITLE ((USHORT)0x0004)
+#define CALENDAR_HITTEST_PREV ((USHORT)0x0008)
+#define CALENDAR_HITTEST_NEXT ((USHORT)0x0010)
+#define CALENDAR_HITTEST_OUTSIDE ((USHORT)0x1000)
+
+#define MENU_YEAR_COUNT 3
+
+#define TABLE_DATE_SELECTED ((void*)0x00000001)
+
+// =======================================================================
+
+struct ImplDateInfo
+{
+ XubString maText;
+ Color* mpTextColor;
+ Color* mpFrameColor;
+ USHORT mnFlags;
+
+ ImplDateInfo( const XubString& rText ) :
+ maText( rText )
+ { mpTextColor = mpFrameColor = NULL; mnFlags = 0; }
+ ~ImplDateInfo() { delete mpTextColor; delete mpFrameColor; }
+};
+
+DECLARE_TABLE( ImplDateTable, ImplDateInfo* );
+
+// =======================================================================
+
+static void ImplCalendarSelectDate( Table* pTable, const Date& rDate, BOOL bSelect )
+{
+ if ( bSelect )
+ pTable->Insert( rDate.GetDate(), TABLE_DATE_SELECTED );
+ else
+ pTable->Remove( rDate.GetDate() );
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalendarSelectDateRange( Table* pTable,
+ const Date& rStartDate,
+ const Date& rEndDate,
+ BOOL bSelect )
+{
+ Date aStartDate = rStartDate;
+ Date aEndDate = rEndDate;
+ if ( aStartDate > aEndDate )
+ {
+ Date aTempDate = aStartDate;
+ aStartDate = aEndDate;
+ aEndDate = aTempDate;
+ }
+
+ if ( bSelect )
+ {
+ while ( aStartDate <= aEndDate )
+ {
+ pTable->Insert( aStartDate.GetDate(), TABLE_DATE_SELECTED );
+ aStartDate++;
+ }
+ }
+ else
+ {
+ void* p = pTable->First();
+ while ( p )
+ {
+ Date aDate( pTable->GetCurKey() );
+ if ( aDate > aEndDate )
+ break;
+
+ if ( aDate >= aStartDate )
+ pTable->Remove( aDate.GetDate() );
+ else
+ p = pTable->Next();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplCalendarUnSelectDateRange( Table* pTable,
+ Table* pOldTable,
+ const Date& rStartDate,
+ const Date& rEndDate )
+{
+ Date aStartDate = rStartDate;
+ Date aEndDate = rEndDate;
+ if ( aStartDate > aEndDate )
+ {
+ Date aTempDate = aStartDate;
+ aStartDate = aEndDate;
+ aEndDate = aTempDate;
+ }
+
+ void* p = pTable->First();
+ while ( p )
+ {
+ Date aDate( pTable->GetCurKey() );
+ if ( aDate > aEndDate )
+ break;
+
+ if ( aDate >= aStartDate )
+ pTable->Remove( aDate.GetDate() );
+ else
+ p = pTable->Next();
+ }
+
+ p = pOldTable->First();
+ while ( p )
+ {
+ Date aDate( pOldTable->GetCurKey() );
+ if ( aDate > aEndDate )
+ break;
+ if ( aDate >= aStartDate )
+ pTable->Insert( aDate.GetDate(), TABLE_DATE_SELECTED );
+
+ p = pOldTable->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+inline void ImplCalendarClearSelectDate( Table* pTable )
+{
+ pTable->Clear();
+}
+
+// =======================================================================
+
+void Calendar::ImplInit( WinBits nWinStyle )
+{
+ mpDateTable = NULL;
+ mpSelectTable = new Table;
+ mpOldSelectTable = NULL;
+ mpRestoreSelectTable = NULL;
+ mpStandardColor = NULL;
+ mpSaturdayColor = NULL;
+ mpSundayColor = NULL;
+ mnDayCount = 0;
+ mnWinStyle = nWinStyle;
+ mnFirstYear = 0;
+ mnLastYear = 0;
+ mnRequestYear = 0;
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbMultiSelection = FALSE;
+ mbWeekSel = FALSE;
+ mbUnSel = FALSE;
+ mbMenuDown = FALSE;
+ mbSpinDown = FALSE;
+ mbPrevIn = FALSE;
+ mbNextIn = FALSE;
+ mbDirect = FALSE;
+ mbInSelChange = FALSE;
+ mbTravelSelect = FALSE;
+ mbScrollDateRange = FALSE;
+ mbSelLeft = FALSE;
+ mbAllSel = FALSE;
+ mbDropPos = FALSE;
+ SetFirstDate( maCurDate );
+ ImplCalendarSelectDate( mpSelectTable, maCurDate, TRUE );
+
+ // Sonstige Strings erzeugen
+ maDayText = XubString( SvtResId( STR_SVT_CALENDAR_DAY ) );
+ maWeekText = XubString( SvtResId( STR_SVT_CALENDAR_WEEK ) );
+
+ // Tagestexte anlegen
+ for ( USHORT i = 0; i < 31; i++ )
+ mpDayText[i] = new UniString( UniString::CreateFromInt32( i+1 ) );
+
+ maDragScrollTimer.SetTimeoutHdl( STATIC_LINK( this, Calendar, ScrollHdl ) );
+ maDragScrollTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
+ mnDragScrollHitTest = 0;
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ maSelColor = rStyleSettings.GetHighlightTextColor();
+ SetPointFont( rStyleSettings.GetToolFont() );
+ SetTextColor( rStyleSettings.GetFieldTextColor() );
+ SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar::Calendar( Window* pParent, WinBits nWinStyle ) :
+ Control( pParent, nWinStyle & (WB_TABSTOP | WB_GROUP | WB_BORDER | WB_3DLOOK | WB_RANGESELECT | WB_MULTISELECT) ),
+ maIntn( Application::GetAppInternational() ),
+ maOldFormatFirstDate( 0, 0, 1900 ),
+ maOldFormatLastDate( 0, 0, 1900 ),
+ maFirstDate( 0, 0, 1900 ),
+ maOldFirstDate( 0, 0, 1900 ),
+ maOldCurDate( 0, 0, 1900 ),
+ maAnchorDate( maCurDate ),
+ maDropDate( 0, 0, 1900 )
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar::Calendar( Window* pParent, const ResId& rResId ) :
+ Control( pParent, rResId ),
+ maIntn( Application::GetAppInternational() ),
+ maOldFormatFirstDate( 0, 0, 1900 ),
+ maOldFormatLastDate( 0, 0, 1900 ),
+ maFirstDate( 0, 0, 1900 ),
+ maOldFirstDate( 0, 0, 1900 ),
+ maOldCurDate( 0, 0, 1900 ),
+ maAnchorDate( maCurDate ),
+ maDropDate( 0, 0, 1900 )
+{
+ ImplInit( rResId.aWinBits );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar::~Calendar()
+{
+ delete mpStandardColor;
+ delete mpSaturdayColor;
+ delete mpSundayColor;
+
+ if ( mpDateTable )
+ {
+ ImplDateInfo* pDateInfo = mpDateTable->First();
+ while ( pDateInfo )
+ {
+ delete pDateInfo;
+ pDateInfo = mpDateTable->Next();
+ }
+
+ delete mpDateTable;
+ }
+
+ delete mpSelectTable;
+ if ( mpOldSelectTable )
+ delete mpOldSelectTable;
+ if ( mpRestoreSelectTable )
+ delete mpRestoreSelectTable;
+
+ for ( USHORT i = 0; i < 31; i++ )
+ delete mpDayText[i];
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplGetWeekFont( Font& rFont ) const
+{
+ // Wochennummer geben wir in WEEKNUMBER_HEIGHT%-Fonthoehe aus
+ Size aFontSize = rFont.GetSize();
+ aFontSize.Height() *= WEEKNUMBER_HEIGHT;
+ aFontSize.Height() /= 100;
+ rFont.SetSize( aFontSize );
+ rFont.SetWeight( WEIGHT_NORMAL );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplFormat()
+{
+ if ( !mbFormat )
+ return;
+
+ DayOfWeek eStartDay = maIntn.GetWeekStart();
+
+ if ( mbCalc )
+ {
+ Size aOutSize = GetOutputSizePixel();
+
+ if ( (aOutSize.Width() <= 1) || (aOutSize.Height() <= 1) )
+ return;
+
+ XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
+
+ Font aOldFont = GetFont();
+
+ // Wochenanzeige beruecksichtigen
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ {
+ Font aTempFont = aOldFont;
+ ImplGetWeekFont( aTempFont );
+ SetFont( aTempFont );
+ mnWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
+ SetFont( aOldFont );
+ }
+ else
+ mnWeekWidth = 0;
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ {
+ Font aFont = aOldFont;
+ if ( aFont.GetWeight() < WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ SetFont( aFont );
+ }
+
+ long n99TextWidth = GetTextWidth( a99Text );
+ long nTextHeight = GetTextHeight();
+
+ // Breiten und X-Positionen berechnen
+ mnDayWidth = n99TextWidth+DAY_OFFX;
+ mnMonthWidth = mnDayWidth*7;
+ mnMonthWidth += mnWeekWidth;
+ mnMonthWidth += MONTH_BORDERX*2;
+ mnMonthPerLine = aOutSize.Width() / mnMonthWidth;
+ if ( !mnMonthPerLine )
+ mnMonthPerLine = 1;
+ long nOver = ((aOutSize.Width()-(mnMonthPerLine*mnMonthWidth)) / mnMonthPerLine);
+ mnMonthWidth += nOver;
+ mnDaysOffX = MONTH_BORDERX;
+ mnDaysOffX += nOver/2;
+ mnDaysOffX += mnWeekWidth;
+
+ // Hoehen und Y-Positionen berechnen
+ mnDayHeight = nTextHeight + DAY_OFFY;
+ mnWeekDayOffY = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
+ mnDaysOffY = mnWeekDayOffY + nTextHeight + WEEKDAY_OFFY;
+ mnMonthHeight = (mnDayHeight*6) + mnDaysOffY;
+ mnMonthHeight += MONTH_OFFY;
+ mnLines = aOutSize.Height() / mnMonthHeight;
+ if ( !mnLines )
+ mnLines = 1;
+ mnMonthHeight += (aOutSize.Height()-(mnLines*mnMonthHeight)) / mnLines;
+
+ // Spinfelder berechnen
+ long nSpinSize = nTextHeight+TITLE_BORDERY-SPIN_OFFY;
+ maPrevRect.Left() = SPIN_OFFX;
+ maPrevRect.Top() = SPIN_OFFY;
+ maPrevRect.Right() = maPrevRect.Left()+nSpinSize;
+ maPrevRect.Bottom() = maPrevRect.Top()+nSpinSize;
+ maNextRect.Left() = aOutSize.Width()-SPIN_OFFX-nSpinSize-1;
+ maNextRect.Top() = SPIN_OFFY;
+ maNextRect.Right() = maNextRect.Left()+nSpinSize;
+ maNextRect.Bottom() = maNextRect.Top()+nSpinSize;
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ SetFont( aOldFont );
+
+ // DayOffWeekText berechnen (werden im schmalen Font ausgegeben)
+ maDayOfWeekText.Erase();
+ long nStartOffX = 0;
+ USHORT eDay = (USHORT)eStartDay;
+ for ( USHORT nDayOfWeek = 0; nDayOfWeek < 7; nDayOfWeek++ )
+ {
+ String aDayOfWeek( maIntn.GetAbbrevDayText( (DayOfWeek)eDay ).GetChar( 0 ) );
+ long nOffX = (mnDayWidth-GetTextWidth( aDayOfWeek ))/2;
+ if ( mnWinStyle & WB_BOLDTEXT )
+ nOffX++;
+ if ( !nDayOfWeek )
+ nStartOffX = nOffX;
+ else
+ nOffX -= nStartOffX;
+ nOffX += nDayOfWeek * mnDayWidth;
+ mnDayOfWeekAry[nDayOfWeek] = nOffX;
+ maDayOfWeekText += aDayOfWeek;
+ eDay++;
+ eDay %= 7;
+ }
+
+ mbCalc = FALSE;
+ }
+
+ // Anzahl Tage berechnen
+ USHORT nWeekDay;
+ Date aTempDate = GetFirstMonth();
+ maFirstDate = aTempDate;
+ nWeekDay = (USHORT)aTempDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ maFirstDate -= (ULONG)nWeekDay;
+ mnDayCount = nWeekDay;
+ USHORT nDaysInMonth;
+ USHORT nMonthCount = (USHORT)(mnMonthPerLine*mnLines);
+ for ( USHORT i = 0; i < nMonthCount; i++ )
+ {
+ nDaysInMonth = aTempDate.GetDaysInMonth();
+ mnDayCount += nDaysInMonth;
+ aTempDate += nDaysInMonth;
+ }
+ Date aTempDate2 = aTempDate;
+ aTempDate2--;
+ nDaysInMonth = aTempDate2.GetDaysInMonth();
+ aTempDate2 -= nDaysInMonth-1;
+ nWeekDay = (USHORT)aTempDate2.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ mnDayCount += 42-nDaysInMonth-nWeekDay;
+
+ // Farben festlegen
+ maOtherColor = Color( COL_LIGHTGRAY );
+ if ( maOtherColor.IsRGBEqual( GetBackground().GetColor() ) )
+ maOtherColor.SetColor( COL_GRAY );
+
+ Date aLastDate = GetLastDate();
+ if ( (maOldFormatLastDate != aLastDate) ||
+ (maOldFormatFirstDate != maFirstDate) )
+ {
+ maOldFormatFirstDate = maFirstDate;
+ maOldFormatLastDate = aLastDate;
+ DateRangeChanged();
+ }
+
+ // DateInfo besorgen
+ USHORT nNewFirstYear = maFirstDate.GetYear();
+ USHORT nNewLastYear = GetLastDate().GetYear();
+ if ( mnFirstYear )
+ {
+ if ( nNewFirstYear < mnFirstYear )
+ {
+ for ( mnRequestYear = nNewFirstYear; mnRequestYear < mnFirstYear; mnRequestYear++ )
+ RequestDateInfo();
+ mnFirstYear = nNewFirstYear;
+ }
+ if ( nNewLastYear > mnLastYear )
+ {
+ for ( mnRequestYear = mnLastYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
+ RequestDateInfo();
+ mnLastYear = nNewLastYear;
+ }
+ }
+ else
+ {
+ for ( mnRequestYear = nNewFirstYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
+ RequestDateInfo();
+ mnFirstYear = nNewFirstYear;
+ mnLastYear = nNewLastYear;
+ }
+ mnRequestYear = 0;
+
+ mbFormat = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Calendar::ImplHitTest( const Point& rPos, Date& rDate ) const
+{
+ if ( mbFormat )
+ return 0;
+
+ if ( maPrevRect.IsInside( rPos ) )
+ return CALENDAR_HITTEST_PREV;
+ else if ( maNextRect.IsInside( rPos ) )
+ return CALENDAR_HITTEST_NEXT;
+
+ long nX;
+ long nY;
+ long nOffX;
+ long nYMonth;
+ USHORT nDay;
+ DayOfWeek eStartDay = maIntn.GetWeekStart();
+
+ rDate = GetFirstMonth();
+ nY = 0;
+ for ( long i = 0; i < mnLines; i++ )
+ {
+ if ( rPos.Y() < nY )
+ return 0;
+
+ nX = 0;
+ nYMonth = nY+mnMonthHeight;
+ for ( long j = 0; j < mnMonthPerLine; j++ )
+ {
+ if ( (rPos.X() < nX) && (rPos.Y() < nYMonth) )
+ return 0;
+
+ USHORT nDaysInMonth = rDate.GetDaysInMonth();
+
+ // Entsprechender Monat gefunden
+ if ( (rPos.X() > nX) && (rPos.Y() < nYMonth) &&
+ (rPos.X() < nX+mnMonthWidth) )
+ {
+ if ( rPos.Y() < (nY+(TITLE_BORDERY*2)+mnDayHeight))
+ return CALENDAR_HITTEST_MONTHTITLE;
+ else
+ {
+ long nDayX = nX+mnDaysOffX;
+ long nDayY = nY+mnDaysOffY;
+ if ( rPos.Y() < nDayY )
+ return 0;
+ USHORT nDayIndex = (USHORT)rDate.GetDayOfWeek();
+ nDayIndex = (nDayIndex+(7-(USHORT)eStartDay)) % 7;
+ if ( (i == 0) && (j == 0) )
+ {
+ Date aTempDate = rDate;
+ aTempDate -= nDayIndex;
+ for ( nDay = 0; nDay < nDayIndex; nDay++ )
+ {
+ nOffX = nDayX + (nDay*mnDayWidth);
+ if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
+ (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
+ {
+ rDate = aTempDate;
+ rDate += nDay;
+ return CALENDAR_HITTEST_DAY;
+ }
+ }
+ }
+ for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
+ {
+ if ( rPos.Y() < nDayY )
+ {
+ rDate += nDayIndex;
+ return 0;
+ }
+ nOffX = nDayX + (nDayIndex*mnDayWidth);
+ if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
+ (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
+ {
+ rDate += nDay-1;
+ return CALENDAR_HITTEST_DAY;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
+ {
+ USHORT nWeekDay = (USHORT)rDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ USHORT nDayCount = 42-nDaysInMonth-nWeekDay;
+ Date aTempDate = rDate;
+ aTempDate += nDaysInMonth;
+ for ( nDay = 1; nDay <= nDayCount; nDay++ )
+ {
+ if ( rPos.Y() < nDayY )
+ {
+ rDate += nDayIndex;
+ return 0;
+ }
+ nOffX = nDayX + (nDayIndex*mnDayWidth);
+ if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
+ (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
+ {
+ rDate = aTempDate;
+ rDate += nDay-1;
+ return CALENDAR_HITTEST_DAY;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ }
+ }
+ }
+
+ rDate += nDaysInMonth;
+ nX += mnMonthWidth;
+ }
+
+ nY += mnMonthHeight;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplDrawSpinArrow( OutputDevice* pDev, const Rectangle& rRect,
+ BOOL bPrev )
+{
+ long i;
+ long n;
+ long nLines;
+ long nHeight = rRect.GetHeight();
+ long nWidth = rRect.GetWidth();
+ if ( nWidth < nHeight )
+ n = nWidth;
+ else
+ n = nHeight;
+ if ( !(n & 0x01) )
+ n--;
+ nLines = n/2;
+
+ Rectangle aRect( Point( rRect.Left()+(nWidth/2)-(nLines/2),
+ rRect.Top()+(nHeight/2) ),
+ Size( 1, 1 ) );
+ if ( !bPrev )
+ {
+ aRect.Left() += nLines;
+ aRect.Right() += nLines;
+ }
+
+ pDev->DrawRect( aRect );
+ for ( i = 0; i < nLines; i++ )
+ {
+ if ( bPrev )
+ {
+ aRect.Left()++;
+ aRect.Right()++;
+ }
+ else
+ {
+ aRect.Left()--;
+ aRect.Right()--;
+ }
+ aRect.Top()--;
+ aRect.Bottom()++;
+ pDev->DrawRect( aRect );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplDrawSpin( BOOL bDrawPrev, BOOL bDrawNext )
+{
+ if ( !bDrawPrev && !bDrawNext )
+ return;
+
+ SetLineColor();
+ SetFillColor( GetSettings().GetStyleSettings().GetButtonTextColor() );
+ if ( bDrawPrev )
+ {
+ Rectangle aOutRect = maPrevRect;
+ aOutRect.Left() += 3;
+ aOutRect.Top() += 3;
+ aOutRect.Right() -= 3;
+ aOutRect.Bottom() -= 3;
+ ImplDrawSpinArrow( this, aOutRect, TRUE );
+ }
+ if ( bDrawNext )
+ {
+ Rectangle aOutRect = maNextRect;
+ aOutRect.Left() += 3;
+ aOutRect.Top() += 3;
+ aOutRect.Right() -= 3;
+ aOutRect.Bottom() -= 3;
+ ImplDrawSpinArrow( this, aOutRect, FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplDrawDate( long nX, long nY,
+ USHORT nDay, USHORT nMonth, USHORT nYear,
+ DayOfWeek eDayOfWeek,
+ BOOL bBack, BOOL bOther, ULONG nToday )
+{
+ ImplDateInfo* pDateInfo;
+ Color* pTextColor = NULL;
+ const String& rDay = *(mpDayText[nDay-1]);
+ Rectangle aDateRect( nX, nY, nX+mnDayWidth-1, nY+mnDayHeight-1 );
+
+ BOOL bSel = FALSE;
+ BOOL bFocus = FALSE;
+ // Aktueller Tag
+ if ( (nDay == maCurDate.GetDay()) &&
+ (nMonth == maCurDate.GetMonth()) &&
+ (nYear == maCurDate.GetYear()) )
+ bFocus = TRUE;
+ if ( mpSelectTable )
+ {
+ if ( mpSelectTable->IsKeyValid( Date( nDay, nMonth, nYear ).GetDate() ) )
+ bSel = TRUE;
+ }
+
+ // Dateinfo ermitteln
+ if ( mpDateTable )
+ {
+ pDateInfo = mpDateTable->Get( Date( nDay, nMonth, nYear ).GetDate() );
+ if ( !pDateInfo )
+ pDateInfo = mpDateTable->Get( Date( nDay, nMonth, 0 ).GetDate() );
+ }
+ else
+ pDateInfo = NULL;
+
+ // Textfarbe ermitteln
+ if ( bSel )
+ pTextColor = &maSelColor;
+ else if ( bOther )
+ pTextColor = &maOtherColor;
+ else
+ {
+ if ( pDateInfo && pDateInfo->mpTextColor )
+ pTextColor = pDateInfo->mpTextColor;
+ else
+ {
+ if ( eDayOfWeek == SATURDAY )
+ pTextColor = mpSaturdayColor;
+ else if ( eDayOfWeek == SUNDAY )
+ pTextColor = mpSundayColor;
+ if ( !pTextColor )
+ pTextColor = mpStandardColor;
+ }
+ }
+
+ if ( bFocus )
+ HideFocus();
+
+ // Font ermitteln
+ Font aOldFont = GetFont();
+ BOOL bBoldFont = FALSE;
+ if ( (mnWinStyle & WB_BOLDTEXT) &&
+ pDateInfo && (pDateInfo->mnFlags & DIB_BOLD) )
+ {
+ bBoldFont = TRUE;
+ Font aFont = aOldFont;
+ if ( aFont.GetWeight() < WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ SetFont( aFont );
+ }
+
+ // Hintergrund ausgeben
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ if ( bSel || bBack )
+ {
+ if ( bSel )
+ {
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( aDateRect );
+ }
+ else
+ Erase( aDateRect );
+ }
+
+ // Text ausgeben
+ long nTextX = nX+(mnDayWidth-GetTextWidth( rDay ))-(DAY_OFFX/2);
+ long nTextY = nY+(mnDayHeight-GetTextHeight())/2;
+ if ( pTextColor )
+ {
+ Color aOldColor = GetTextColor();
+ SetTextColor( *pTextColor );
+ DrawText( Point( nTextX, nTextY ), rDay );
+ SetTextColor( aOldColor );
+ }
+ else
+ DrawText( Point( nTextX, nTextY ), rDay );
+
+ // Heute
+ Date aTodayDate( maCurDate );
+ if ( nToday )
+ aTodayDate.SetDate( nToday );
+ else
+ aTodayDate = Date();
+ if ( (nDay == aTodayDate.GetDay()) &&
+ (nMonth == aTodayDate.GetMonth()) &&
+ (nYear == aTodayDate.GetYear()) )
+ {
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ SetFillColor();
+ DrawRect( aDateRect );
+ }
+
+ // Evt. DateInfo ausgeben
+ if ( (mnWinStyle & WB_FRAMEINFO) && pDateInfo && pDateInfo->mpFrameColor )
+ {
+ SetLineColor( *(pDateInfo->mpFrameColor) );
+ SetFillColor();
+ Rectangle aFrameRect( aDateRect );
+ aFrameRect.Left()++;
+ aFrameRect.Top()++;
+ long nFrameWidth = aFrameRect.GetWidth();
+ long nFrameHeight = aFrameRect.GetHeight();
+ long nFrameOff;
+ if ( nFrameWidth < nFrameHeight )
+ {
+ nFrameOff = nFrameHeight-nFrameWidth;
+ aFrameRect.Top() += nFrameOff/2;
+ nFrameOff %= 2;
+ aFrameRect.Bottom() -= nFrameOff;
+ }
+ else if ( nFrameWidth > nFrameHeight )
+ {
+ nFrameOff = nFrameWidth-nFrameHeight;
+ aFrameRect.Left() += nFrameOff/2;
+ nFrameOff %= 2;
+ aFrameRect.Right() -= nFrameOff;
+ }
+ DrawEllipse( aFrameRect );
+ }
+
+ // Evt. noch FocusRect
+ if ( bFocus && HasFocus() )
+ ShowFocus( aDateRect );
+
+ if( mbDropPos && maDropDate == Date( nDay, nMonth, nYear ) )
+ ImplInvertDropPos();
+
+ if ( bBoldFont )
+ SetFont( aOldFont );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplDraw( BOOL bPaint )
+{
+ ImplFormat();
+
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Size aOutSize = GetOutputSizePixel();
+ long i;
+ long j;
+ long nX;
+ long nY;
+ long nOffX;
+ long nOffY;
+ long nDayX;
+ long nDayY;
+ ULONG nToday = Date().GetDate();
+ USHORT nDay;
+ USHORT nMonth;
+ USHORT nYear;
+ Date aDate = GetFirstMonth();
+ DayOfWeek eStartDay = maIntn.GetWeekStart();
+
+ HideFocus();
+
+ nY = 0;
+ for ( i = 0; i < mnLines; i++ )
+ {
+ // Titleleiste ausgeben
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ Rectangle aTitleRect( 0, nY, aOutSize.Width()-1, nY+mnDayHeight-DAY_OFFY+TITLE_BORDERY*2 );
+ if ( !bPaint )
+ {
+ Rectangle aTempRect( 1, aTitleRect.Top()+TITLE_BORDERY,
+ aOutSize.Width()-2,
+ aTitleRect.Bottom()-TITLE_BORDERY );
+ if ( !i )
+ {
+ aTempRect.Left() = maPrevRect.Right()+1;
+ aTempRect.Right() = maNextRect.Left()-1;
+ }
+ DrawRect( aTempRect );
+ }
+ else
+ {
+ DrawRect( aTitleRect );
+ Point aTopLeft1( aTitleRect.Left(), aTitleRect.Top() );
+ Point aTopLeft2( aTitleRect.Left(), aTitleRect.Top()+1 );
+ Point aBottomRight1( aTitleRect.Right(), aTitleRect.Bottom() );
+ Point aBottomRight2( aTitleRect.Right(), aTitleRect.Bottom()-1 );
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( aTopLeft1, Point( aBottomRight1.X(), aTopLeft1.Y() ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( aTopLeft2, Point( aBottomRight2.X(), aTopLeft2.Y() ) );
+ DrawLine( aTopLeft2, Point( aTopLeft2.X(), aBottomRight2.Y() ) );
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( aTopLeft2.X(), aBottomRight2.Y() ), aBottomRight2 );
+ DrawLine( Point( aBottomRight2.X(), aTopLeft2.Y() ), aBottomRight2 );
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( aTopLeft1.X(), aBottomRight1.Y() ), aBottomRight1 );
+ }
+ Point aSepPos1( 0, aTitleRect.Top()+TITLE_BORDERY );
+ Point aSepPos2( 0, aTitleRect.Bottom()-TITLE_BORDERY );
+ for ( j = 0; j < mnMonthPerLine-1; j++ )
+ {
+ aSepPos1.X() += mnMonthWidth-1;
+ aSepPos2.X() = aSepPos1.X();
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( aSepPos1, aSepPos2 );
+ aSepPos1.X()++;
+ aSepPos2.X() = aSepPos1.X();
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( aSepPos1, aSepPos2 );
+ }
+
+ nX = 0;
+ for ( j = 0; j < mnMonthPerLine; j++ )
+ {
+ nMonth = aDate.GetMonth();
+ nYear = aDate.GetYear();
+
+ // Monat in der Titleleiste ausgeben
+ nOffX = nX;
+ nOffY = nY+TITLE_BORDERY;
+ String aMonthText( maIntn.GetMonthText( nMonth ) );
+ aMonthText += ' ';
+ aMonthText += nYear;
+ long nMonthTextWidth = GetTextWidth( aMonthText );
+ long nMonthOffX1 = 0;
+ long nMonthOffX2 = 0;
+ if ( i == 0 )
+ {
+ if ( j == 0 )
+ nMonthOffX1 = maPrevRect.Right()+1;
+ if ( j == mnMonthPerLine-1 )
+ nMonthOffX2 = aOutSize.Width()-maNextRect.Left()+1;
+ }
+ long nMaxMonthWidth = mnMonthWidth-nMonthOffX1-nMonthOffX2-4;
+ if ( nMonthTextWidth > nMaxMonthWidth )
+ {
+ aMonthText = maIntn.GetAbbrevMonthText( nMonth );
+ aMonthText += ' ';
+ aMonthText += nYear;
+ nMonthTextWidth = GetTextWidth( aMonthText );
+ }
+ long nTempOff = (mnMonthWidth-nMonthTextWidth+1)/2;
+ if ( nTempOff < nMonthOffX1 )
+ nOffX += nMonthOffX1+1;
+ else
+ {
+ if ( nTempOff+nMonthTextWidth > mnMonthWidth-nMonthOffX2 )
+ nOffX += mnMonthWidth-nMonthOffX2-nMonthTextWidth;
+ else
+ nOffX += nTempOff;
+ }
+ SetTextColor( rStyleSettings.GetButtonTextColor() );
+ DrawText( Point( nOffX, nOffY ), aMonthText );
+ SetTextColor( rStyleSettings.GetWindowTextColor() );
+
+ // Weekleiste ausgeben
+ if ( bPaint )
+ {
+ nDayX = nX+mnDaysOffX;
+ nDayY = nY+mnWeekDayOffY;
+ nOffY = nDayY + mnDayHeight;
+ SetLineColor( rStyleSettings.GetWindowTextColor() );
+ Point aStartPos( nDayX, nOffY );
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ aStartPos.X() -= WEEKNUMBER_OFFX-2;
+ DrawLine( aStartPos, Point( nDayX+(7*mnDayWidth), nOffY ) );
+ DrawTextArray( Point( nDayX+mnDayOfWeekAry[0], nDayY ), maDayOfWeekText, &(mnDayOfWeekAry[1]) );
+ }
+
+ // Week-Numbers ausgeben
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ {
+ nDayX = nX+mnDaysOffX;
+ nDayY = nY+mnWeekDayOffY;
+ nOffY = nDayY + mnDayHeight;
+ long nMonthHeight = mnDayHeight*6;
+ if ( bPaint )
+ DrawLine( Point( nDayX-WEEKNUMBER_OFFX+2, nOffY ), Point( nDayX-WEEKNUMBER_OFFX+2, nOffY+nMonthHeight ) );
+ else
+ Erase( Rectangle( nDayX-mnWeekWidth-WEEKNUMBER_OFFX, nOffY, nDayX-WEEKNUMBER_OFFX-1, nOffY+nMonthHeight ) );
+
+ Font aOldFont = GetFont();
+ Font aTempFont = aOldFont;
+ ImplGetWeekFont( aTempFont );
+ SetFont( aTempFont );
+ nDayX -= mnWeekWidth;
+ nDayY = nY+mnDaysOffY;
+ Date aTempDate = aDate;
+ for ( USHORT nWeekCount = 0; nWeekCount < 6; nWeekCount++ )
+ {
+ String aWeekText( aTempDate.GetWeekOfYear( eStartDay, maIntn.GetWeekCountStart() ) );
+ long nOffX = (mnWeekWidth-WEEKNUMBER_OFFX)-GetTextWidth( aWeekText );
+ long nOffY = (mnDayHeight-GetTextHeight())/2;
+ DrawText( Point( nDayX+nOffX, nDayY+nOffY ), aWeekText );
+ nDayY += mnDayHeight;
+ aTempDate += 7;
+ }
+ SetFont( aOldFont );
+ }
+
+ // Tage ausgeben
+ USHORT nDaysInMonth = aDate.GetDaysInMonth();
+ nDayX = nX+mnDaysOffX;
+ nDayY = nY+mnDaysOffY;
+ if ( !bPaint )
+ {
+ Rectangle aClearRect( nDayX, nDayY,
+ nDayX+(7*mnDayWidth)-1, nDayY+(6*mnDayHeight)-1 );
+ Erase( aClearRect );
+ }
+ USHORT nDayIndex = (USHORT)aDate.GetDayOfWeek();
+ nDayIndex = (nDayIndex+(7-(USHORT)eStartDay)) % 7;
+ if ( (i == 0) && (j == 0) )
+ {
+ Date aTempDate = aDate;
+ aTempDate -= nDayIndex;
+ for ( nDay = 0; nDay < nDayIndex; nDay++ )
+ {
+ nOffX = nDayX + (nDay*mnDayWidth);
+ ImplDrawDate( nOffX, nDayY, nDay+aTempDate.GetDay(),
+ aTempDate.GetMonth(), aTempDate.GetYear(),
+ (DayOfWeek)((nDay+(USHORT)eStartDay)%7), FALSE, TRUE, nToday );
+ }
+ }
+ for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
+ {
+ nOffX = nDayX + (nDayIndex*mnDayWidth);
+ ImplDrawDate( nOffX, nDayY, nDay, nMonth, nYear,
+ (DayOfWeek)((nDayIndex+(USHORT)eStartDay)%7),
+ FALSE, FALSE, nToday );
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
+ {
+ USHORT nWeekDay = (USHORT)aDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)eStartDay)) % 7;
+ USHORT nDayCount = 42-nDaysInMonth-nWeekDay;
+ Date aTempDate = aDate;
+ aTempDate += nDaysInMonth;
+ for ( nDay = 1; nDay <= nDayCount; nDay++ )
+ {
+ nOffX = nDayX + (nDayIndex*mnDayWidth);
+ ImplDrawDate( nOffX, nDayY, nDay,
+ aTempDate.GetMonth(), aTempDate.GetYear(),
+ (DayOfWeek)((nDayIndex+(USHORT)eStartDay)%7),
+ FALSE, TRUE, nToday );
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ }
+
+ aDate += nDaysInMonth;
+ nX += mnMonthWidth;
+ }
+
+ nY += mnMonthHeight;
+ }
+
+ // Spin-Buttons zeichnen
+ if ( bPaint )
+ ImplDrawSpin();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplUpdateDate( const Date& rDate )
+{
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ Rectangle aDateRect( GetDateRect( rDate ) );
+ if ( !aDateRect.IsEmpty() )
+ {
+ BOOL bOther = (rDate < GetFirstMonth()) || (rDate > GetLastMonth());
+ ImplDrawDate( aDateRect.Left(), aDateRect.Top(),
+ rDate.GetDay(), rDate.GetMonth(), rDate.GetYear(),
+ rDate.GetDayOfWeek(), TRUE, bOther );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplUpdateSelection( Table* pOld )
+{
+ Table* pNew = mpSelectTable;
+ void* p;
+ ULONG nKey;
+
+ p = pOld->First();
+ while ( p )
+ {
+ nKey = pOld->GetCurKey();
+ if ( !pNew->Get( nKey ) )
+ {
+ Date aTempDate( nKey );
+ ImplUpdateDate( aTempDate );
+ }
+
+ p = pOld->Next();
+ }
+
+ p = pNew->First();
+ while ( p )
+ {
+ nKey = pNew->GetCurKey();
+ if ( !pOld->Get( nKey ) )
+ {
+ Date aTempDate( nKey );
+ ImplUpdateDate( aTempDate );
+ }
+
+ p = pNew->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplMouseSelect( const Date& rDate, USHORT nHitTest,
+ BOOL bMove, BOOL bExpand, BOOL bExtended )
+{
+ Table* pOldSel = new Table( *mpSelectTable );
+ Date aOldDate = maCurDate;
+ Date aTempDate = rDate;
+
+ if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
+ aTempDate--;
+
+ if ( mbMultiSelection )
+ {
+ maCurDate = aTempDate;
+ mbSelLeft = aTempDate < maAnchorDate;
+
+ if ( bMove )
+ {
+ if ( mbSelLeft )
+ {
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), aTempDate );
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, maAnchorDate, Date( 31, 12, 9999 ) );
+ }
+ else
+ {
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), maAnchorDate );
+ ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, aTempDate, Date( 31, 12, 9999 ) );
+ }
+ ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, !mbUnSel );
+ }
+ else
+ {
+ if ( bExpand )
+ {
+ if ( !bExtended )
+ {
+ if ( mbSelLeft )
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aTempDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ else
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, aTempDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ }
+ ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, TRUE );
+ }
+ else if ( bExtended && !(mnWinStyle & WB_RANGESELECT) )
+ {
+ maAnchorDate = aTempDate;
+ if ( IsDateSelected( aTempDate ) )
+ {
+ mbUnSel = TRUE;
+ ImplCalendarSelectDate( mpSelectTable, aTempDate, FALSE );
+ }
+ else
+ {
+ ImplCalendarSelectDate( mpSelectTable, aTempDate, TRUE );
+ }
+ }
+ else
+ {
+ maAnchorDate = aTempDate;
+ ImplCalendarClearSelectDate( mpSelectTable );
+ ImplCalendarSelectDate( mpSelectTable, aTempDate, TRUE );
+ }
+
+ mpRestoreSelectTable = new Table( *mpSelectTable );
+ }
+ }
+ else
+ {
+ if ( aTempDate < maCurDate )
+ mbSelLeft = TRUE;
+ else
+ mbSelLeft = FALSE;
+ if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
+ aTempDate = maOldCurDate;
+ if ( !bMove )
+ maAnchorDate = aTempDate;
+ if ( aTempDate != maCurDate )
+ {
+ maCurDate = aTempDate;
+ ImplCalendarSelectDate( mpSelectTable, aOldDate, FALSE );
+ ImplCalendarSelectDate( mpSelectTable, maCurDate, TRUE );
+ }
+ }
+
+ BOOL bNewSel = *pOldSel != *mpSelectTable;
+ if ( (maCurDate != aOldDate) || bNewSel )
+ {
+ if ( bNewSel )
+ {
+ mbInSelChange = TRUE;
+ SelectionChanging();
+ mbInSelChange = FALSE;
+ }
+ HideFocus();
+ if ( bNewSel )
+ ImplUpdateSelection( pOldSel );
+ if ( !bNewSel || !pOldSel->Get( aOldDate.GetDate() ) )
+ ImplUpdateDate( aOldDate );
+ // Damit Focus-Rechteck auch wieder neu ausgegeben wird
+ if ( HasFocus() || !bNewSel || !mpSelectTable->Get( maCurDate.GetDate() ) )
+ ImplUpdateDate( maCurDate );
+ }
+ delete pOldSel;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplUpdate( BOOL bCalcNew )
+{
+ if ( IsReallyVisible() && IsUpdateMode() )
+ {
+ if ( bCalcNew && !mbCalc )
+ Invalidate();
+ else if ( !mbFormat && !mbCalc )
+ {
+ if ( mbDirect )
+ {
+ mbFormat = TRUE;
+ ImplDraw( FALSE );
+ return;
+ }
+ else
+ Invalidate();
+ }
+ }
+
+ if ( bCalcNew )
+ mbCalc = TRUE;
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplInvertDropPos()
+{
+ Rectangle aRect = GetDateRect( maDropDate );//this is one Pixel to width and one to heigh
+ aRect.Bottom() = aRect.Top()+mnDayHeight-1;
+ aRect.Right() = aRect.Left()+mnDayWidth-1;
+ Invert( aRect );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplScroll( BOOL bPrev )
+{
+ Date aNewFirstMonth = GetFirstMonth();
+ if ( bPrev )
+ {
+ aNewFirstMonth--;
+ aNewFirstMonth -= aNewFirstMonth.GetDaysInMonth()-1;
+ }
+ else
+ aNewFirstMonth += aNewFirstMonth.GetDaysInMonth();
+ mbDirect = TRUE;
+ SetFirstDate( aNewFirstMonth );
+ mbDirect = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate )
+{
+ EndSelection();
+
+ Date aOldFirstDate = GetFirstMonth();
+ PopupMenu aPopupMenu;
+ PopupMenu* pYearPopupMenus[MENU_YEAR_COUNT];
+ USHORT nMonthOff;
+ USHORT nCurItemId;
+ USHORT nYear = rDate.GetYear()-1;
+ USHORT i;
+ USHORT j;
+ USHORT nYearIdCount = 1000;
+
+ nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12;
+ if ( aOldFirstDate.GetMonth() < rDate.GetMonth() )
+ nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth();
+ else
+ nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth();
+
+ // Menu aufbauen (Jahre mit verschiedenen Monaten aufnehmen)
+ for ( i = 0; i < MENU_YEAR_COUNT; i++ )
+ {
+ pYearPopupMenus[i] = new PopupMenu;
+ for ( j = 1; j <= 12; j++ )
+ pYearPopupMenus[i]->InsertItem( nYearIdCount+j, maIntn.GetMonthText( j ) );
+ aPopupMenu.InsertItem( 10+i, UniString::CreateFromInt32( nYear+i ) );
+ aPopupMenu.SetPopupMenu( 10+i, pYearPopupMenus[i] );
+ nYearIdCount += 1000;
+ }
+
+ mbMenuDown = TRUE;
+ nCurItemId = aPopupMenu.Execute( this, rPos );
+ mbMenuDown = FALSE;
+
+ // Menu zerstoeren
+ aPopupMenu.SetPopupMenu( 2, NULL );
+ for ( i = 0; i < MENU_YEAR_COUNT; i++ )
+ {
+ aPopupMenu.SetPopupMenu( 10+i, NULL );
+ delete pYearPopupMenus[i];
+ }
+
+ if ( nCurItemId )
+ {
+ USHORT nTempMonthOff = nMonthOff % 12;
+ USHORT nTempYearOff = nMonthOff / 12;
+ USHORT nNewMonth = nCurItemId % 1000;
+ USHORT nNewYear = nYear+((nCurItemId-1000)/1000);
+ if ( nTempMonthOff < nNewMonth )
+ nNewMonth -= nTempMonthOff;
+ else
+ {
+ nNewYear--;
+ nNewMonth = 12-(nTempMonthOff-nNewMonth);
+ }
+ nNewYear -= nTempYearOff;
+ SetFirstDate( Date( 1, nNewMonth, nNewYear ) );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplTracking( const Point& rPos, BOOL bRepeat )
+{
+ Date aTempDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rPos, aTempDate );
+
+ if ( mbSpinDown )
+ {
+ mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
+ mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
+
+ if ( bRepeat && (mbPrevIn || mbNextIn) )
+ {
+ mbScrollDateRange = TRUE;
+ ImplScroll( mbPrevIn );
+ mbScrollDateRange = FALSE;
+ }
+ }
+ else
+ ImplMouseSelect( aTempDate, nHitTest, TRUE, FALSE, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ImplEndTracking( const Point& rPos, BOOL bCancel )
+{
+ BOOL bSelection = mbSelection;
+ BOOL bSpinDown = mbSpinDown;
+
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbMultiSelection = FALSE;
+ mbUnSel = FALSE;
+ mbSpinDown = FALSE;
+ mbPrevIn = FALSE;
+ mbNextIn = FALSE;
+
+ if ( bCancel )
+ {
+ if ( maOldFirstDate != maFirstDate )
+ SetFirstDate( maOldFirstDate );
+
+ if ( !bSpinDown )
+ {
+ Table* pOldSel = new Table( *mpSelectTable );
+ Date aOldDate = maCurDate;
+ maCurDate = maOldCurDate;
+ *mpSelectTable = *mpOldSelectTable;
+ HideFocus();
+ ImplUpdateSelection( pOldSel );
+ if ( !pOldSel->Get( aOldDate.GetDate() ) )
+ ImplUpdateDate( aOldDate );
+ // Damit Focus-Rechteck auch wieder neu ausgegeben wird
+ if ( HasFocus() || !mpSelectTable->Get( maCurDate.GetDate() ) )
+ ImplUpdateDate( maCurDate );
+ delete pOldSel;
+ }
+ }
+
+ if ( !bSpinDown )
+ {
+ if ( !bCancel )
+ {
+ // Feststellen, ob wir sichtbaren Bereich scrollen sollen
+ ULONG nSelCount = mpSelectTable->Count();
+ if ( nSelCount )
+ {
+ Date aFirstSelDate( mpSelectTable->GetObjectKey( 0 ) );
+ Date aLastSelDate( mpSelectTable->GetObjectKey( nSelCount-1 ) );
+ if ( aLastSelDate < GetFirstMonth() )
+ ImplScroll( TRUE );
+ else if ( GetLastMonth() < aFirstSelDate )
+ ImplScroll( FALSE );
+ }
+ }
+
+ if ( mbAllSel ||
+ (!bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable))) )
+ Select();
+
+ if ( !bSelection && (mnWinStyle & WB_TABSTOP) && !bCancel )
+ GrabFocus();
+
+ delete mpOldSelectTable;
+ mpOldSelectTable = NULL;
+ delete mpRestoreSelectTable;
+ mpRestoreSelectTable = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_STATIC_LINK( Calendar, ScrollHdl, Timer*, pTimer )
+{
+ BOOL bPrevIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_PREV) != 0;
+ BOOL bNextIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_NEXT) != 0;
+ if( bNextIn || bPrevIn )
+ {
+ pThis->mbScrollDateRange = TRUE;
+ pThis->ImplScroll( bPrevIn );
+ pThis->mbScrollDateRange = FALSE;
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && !mbMenuDown )
+ {
+ Date aTempDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rMEvt.GetPosPixel(), aTempDate );
+ if ( nHitTest )
+ {
+ if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
+ ImplShowMenu( rMEvt.GetPosPixel(), aTempDate );
+ else
+ {
+ maOldFirstDate = maFirstDate;
+
+ mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
+ mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
+ if ( mbPrevIn || mbNextIn )
+ {
+ mbSpinDown = TRUE;
+ mbScrollDateRange = TRUE;
+ ImplScroll( mbPrevIn );
+ mbScrollDateRange = FALSE;
+ // Hier muss BUTTONREPEAT stehen, also nicht wieder
+ // auf SCROLLREPEAT aendern, sondern mit TH abklaeren,
+ // warum es evtl. anders sein sollte (71775)
+ StartTracking( STARTTRACK_BUTTONREPEAT );
+ }
+ else
+ {
+ if ( (rMEvt.GetClicks() == 2) && (nHitTest & CALENDAR_HITTEST_DAY) )
+ DoubleClick();
+ else
+ {
+ if ( mpOldSelectTable )
+ delete mpOldSelectTable;
+ maOldCurDate = maCurDate;
+ mpOldSelectTable = new Table( *mpSelectTable );
+
+ if ( !mbSelection )
+ {
+ mbDrag = TRUE;
+ StartTracking();
+ }
+
+ mbMultiSelection = (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT)) != 0;
+ if ( (nHitTest & CALENDAR_HITTEST_DAY) && mbMultiSelection )
+ mbWeekSel = TRUE;
+ else
+ mbWeekSel = FALSE;
+ ImplMouseSelect( aTempDate, nHitTest, FALSE, rMEvt.IsShift(), rMEvt.IsMod1() );
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ Control::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && mbSelection )
+ ImplEndTracking( rMEvt.GetPosPixel(), FALSE );
+ else
+ Control::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( mbSelection && rMEvt.GetButtons() )
+ ImplTracking( rMEvt.GetPosPixel(), FALSE );
+ else
+ Control::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( rTEvt.IsTrackingEnded() )
+ ImplEndTracking( aMousePos, rTEvt.IsTrackingCanceled() );
+ else
+ ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::KeyInput( const KeyEvent& rKEvt )
+{
+ Date aNewDate = maCurDate;
+ BOOL bMultiSel = (mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) != 0;
+ BOOL bExpand = rKEvt.GetKeyCode().IsShift();
+ BOOL bExtended = rKEvt.GetKeyCode().IsMod1();
+
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_HOME:
+ aNewDate.SetDay( 1 );
+ break;
+
+ case KEY_END:
+ aNewDate.SetDay( aNewDate.GetDaysInMonth() );
+ break;
+
+ case KEY_LEFT:
+ aNewDate--;
+ break;
+
+ case KEY_RIGHT:
+ aNewDate++;
+ break;
+
+ case KEY_UP:
+ aNewDate -= 7;
+ break;
+
+ case KEY_DOWN:
+ aNewDate += 7;
+ break;
+
+ case KEY_PAGEUP:
+ {
+ Date aTempDate = aNewDate;
+ aTempDate -= aNewDate.GetDay()+1;
+ aNewDate -= aTempDate.GetDaysInMonth();
+ }
+ break;
+
+ case KEY_PAGEDOWN:
+ aNewDate += aNewDate.GetDaysInMonth();
+ break;
+
+ case KEY_SPACE:
+ if ( bMultiSel && !(mnWinStyle & WB_RANGESELECT) )
+ {
+ if ( !bExpand )
+ {
+ BOOL bDateSel = IsDateSelected( maCurDate );
+ SelectDate( maCurDate, !bDateSel );
+ mbSelLeft = FALSE;
+ SelectionChanging();
+ mbTravelSelect = TRUE;
+ Select();
+ mbTravelSelect = FALSE;
+ }
+ }
+ else
+ Control::KeyInput( rKEvt );
+ break;
+
+ default:
+ Control::KeyInput( rKEvt );
+ break;
+ }
+
+ if ( aNewDate != maCurDate )
+ {
+ if ( bMultiSel && bExpand )
+ {
+ Table* pOldSel = new Table( *mpSelectTable );
+ Date aOldAnchorDate = maAnchorDate;
+ mbSelLeft = aNewDate < maAnchorDate;
+ if ( !bExtended )
+ {
+ if ( mbSelLeft )
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aNewDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ else
+ {
+ ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, FALSE );
+ ImplCalendarSelectDateRange( mpSelectTable, aNewDate, Date( 31, 12, 9999 ), FALSE );
+ }
+ }
+ ImplCalendarSelectDateRange( mpSelectTable, aNewDate, maAnchorDate, TRUE );
+ mbDirect = TRUE;
+ SetCurDate( aNewDate );
+ mbDirect = FALSE;
+ maAnchorDate = aOldAnchorDate;
+ mbInSelChange = TRUE;
+ SelectionChanging();
+ mbInSelChange = FALSE;
+ ImplUpdateSelection( pOldSel );
+ }
+ else
+ {
+ if ( mnWinStyle & WB_RANGESELECT )
+ {
+ SetNoSelection();
+ SelectDate( aNewDate, TRUE );
+ }
+ mbDirect = TRUE;
+ SetCurDate( aNewDate );
+ mbDirect = FALSE;
+ }
+ mbTravelSelect = TRUE;
+ Select();
+ mbTravelSelect = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Paint( const Rectangle& rRect )
+{
+ ImplDraw( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::GetFocus()
+{
+ ImplUpdateDate( maCurDate );
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::LoseFocus()
+{
+ HideFocus();
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Resize()
+{
+ ImplUpdate( TRUE );
+ Control::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ Date aDate = maCurDate;
+ if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) )
+ {
+ Rectangle aDateRect = GetDateRect( aDate );
+ Point aPt = OutputToScreenPixel( aDateRect.TopLeft() );
+ aDateRect.Left() = aPt.X();
+ aDateRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aDateRect.BottomRight() );
+ aDateRect.Right() = aPt.X();
+ aDateRect.Bottom() = aPt.Y();
+
+ if ( (rHEvt.GetMode() & HELPMODE_BALLOON) || (mnWinStyle & WB_QUICKHELPSHOWSDATEINFO) )
+ {
+ ImplDateInfo* pInfo;
+ if ( mpDateTable )
+ {
+ pInfo = mpDateTable->Get( aDate.GetDate() );
+ if ( !pInfo )
+ pInfo = mpDateTable->Get( Date( aDate.GetDay(), aDate.GetMonth(), 0 ).GetDate() );
+ }
+ else
+ pInfo = NULL;
+ if ( pInfo )
+ {
+ XubString aStr = pInfo->maText;
+ if ( aStr.Len() )
+ {
+ Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aDateRect, aStr );
+ return;
+ }
+ }
+ }
+
+ if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ {
+ USHORT nWeek = aDate.GetWeekOfYear( maIntn.GetWeekStart(), maIntn.GetWeekCountStart() );
+ USHORT nMonth = aDate.GetMonth();
+ XubString aStr( maDayText );
+ aStr.AppendAscii( ": " );
+ aStr.Append( XubString::CreateFromInt32( aDate.GetDayOfYear() ) );
+ aStr.AppendAscii( " / " );
+ aStr.Append( maWeekText );
+ aStr.AppendAscii( ": " );
+ aStr.Append( XubString::CreateFromInt32( nWeek ) );
+ // Evt. noch Jahr hinzufuegen, wenn es nicht das gleiche ist
+ if ( (nMonth == 12) && (nWeek == 1) )
+ {
+ aStr.AppendAscii( ", " );
+ aStr.Append( XubString::CreateFromInt32( aDate.GetYear()+1 ) );
+ }
+ else if ( (nMonth == 1) && (nWeek > 50) )
+ {
+ aStr.AppendAscii( ", " );
+ aStr.Append( XubString::CreateFromInt32( aDate.GetYear()-1 ) );
+ }
+ Help::ShowQuickHelp( this, aDateRect, aStr );
+ return;
+ }
+ }
+ }
+
+ Control::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ if ( !mbSelection && rCEvt.IsMouseEvent() )
+ {
+ Date aTempDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rCEvt.GetMousePosPixel(), aTempDate );
+ if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
+ {
+ ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate );
+ return;
+ }
+ }
+ }
+ else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
+ {
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
+ {
+ long nNotchDelta = pData->GetNotchDelta();
+ if ( nNotchDelta < 0 )
+ {
+ while ( nNotchDelta < 0 )
+ {
+ ImplScroll( TRUE );
+ nNotchDelta++;
+ }
+ }
+ else
+ {
+ while ( nNotchDelta > 0 )
+ {
+ ImplScroll( FALSE );
+ nNotchDelta--;
+ }
+ }
+
+ return;
+ }
+ }
+
+ Control::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ ImplFormat();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SelectionChanging()
+{
+ maSelectionChangingHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::DateRangeChanged()
+{
+ maDateRangeChangedHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::RequestDateInfo()
+{
+ maRequestDateInfoHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetInternational( const International& rIntn )
+{
+ ImplUpdate( TRUE );
+
+ maIntn = rIntn;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SelectDate( const Date& rDate, BOOL bSelect )
+{
+ if ( !rDate.IsValid() )
+ return;
+
+ Table* pOldSel;
+
+ if ( !mbInSelChange )
+ pOldSel = new Table( *mpSelectTable );
+ else
+ pOldSel = NULL;
+
+ ImplCalendarSelectDate( mpSelectTable, rDate, bSelect );
+
+ if ( pOldSel )
+ {
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SelectDateRange( const Date& rStartDate, const Date& rEndDate,
+ BOOL bSelect )
+{
+ if ( !rStartDate.IsValid() || !rEndDate.IsValid() )
+ return;
+
+ Table* pOldSel;
+
+ if ( !mbInSelChange )
+ pOldSel = new Table( *mpSelectTable );
+ else
+ pOldSel = NULL;
+
+ ImplCalendarSelectDateRange( mpSelectTable, rStartDate, rEndDate, bSelect );
+
+ if ( pOldSel )
+ {
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetNoSelection()
+{
+ Table* pOldSel;
+
+ if ( !mbInSelChange )
+ pOldSel = new Table( *mpSelectTable );
+ else
+ pOldSel = NULL;
+
+ ImplCalendarClearSelectDate( mpSelectTable );
+
+ if ( pOldSel )
+ {
+ ImplUpdateSelection( pOldSel );
+ delete pOldSel;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::IsDateSelected( const Date& rDate ) const
+{
+ return mpSelectTable->IsKeyValid( rDate.GetDate() );
+}
+
+// -----------------------------------------------------------------------
+
+ULONG Calendar::GetSelectDateCount() const
+{
+ return mpSelectTable->Count();
+}
+
+// -----------------------------------------------------------------------
+
+Date Calendar::GetSelectDate( ULONG nIndex ) const
+{
+ if ( nIndex < mpSelectTable->Count() )
+ return Date( mpSelectTable->GetObjectKey( nIndex ) );
+ else
+ {
+ Date aDate( 0, 0, 0 );
+ return aDate;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetCurDate( const Date& rNewDate )
+{
+ if ( !rNewDate.IsValid() )
+ return;
+
+ if ( maCurDate != rNewDate )
+ {
+ BOOL bUpdate = IsVisible() && IsUpdateMode();
+ Date aOldDate = maCurDate;
+ maCurDate = rNewDate;
+ maAnchorDate = maCurDate;
+
+ if ( !(mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) )
+ {
+ ImplCalendarSelectDate( mpSelectTable, aOldDate, FALSE );
+ ImplCalendarSelectDate( mpSelectTable, maCurDate, TRUE );
+ }
+ else if ( !HasFocus() )
+ bUpdate = FALSE;
+
+ // Aktuelles Datum noch in den sichtbaren Bereich verschieben
+ if ( mbFormat || (maCurDate < GetFirstMonth()) )
+ SetFirstDate( maCurDate );
+ else if ( maCurDate > GetLastMonth() )
+ {
+ Date aTempDate = GetLastMonth();
+ long nDateOff = maCurDate-aTempDate;
+ if ( nDateOff < 365 )
+ {
+ Date maFirstDate = GetFirstMonth();
+ maFirstDate += maFirstDate.GetDaysInMonth();
+ aTempDate++;
+ while ( nDateOff > aTempDate.GetDaysInMonth() )
+ {
+ maFirstDate += maFirstDate.GetDaysInMonth();
+ long nDaysInMonth = aTempDate.GetDaysInMonth();
+ aTempDate += nDaysInMonth;
+ nDateOff -= nDaysInMonth;
+ }
+ SetFirstDate( maFirstDate );
+ }
+ else
+ SetFirstDate( maCurDate );
+ }
+ else
+ {
+ if ( bUpdate )
+ {
+ HideFocus();
+ ImplUpdateDate( aOldDate );
+ ImplUpdateDate( maCurDate );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetFirstDate( const Date& rNewFirstDate )
+{
+ if ( maFirstDate != rNewFirstDate )
+ {
+ maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() );
+ mbDropPos = FALSE;
+ ImplUpdate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Date Calendar::GetFirstMonth() const
+{
+ if ( maFirstDate.GetDay() > 1 )
+ {
+ if ( maFirstDate.GetMonth() == 12 )
+ return Date( 1, 1, maFirstDate.GetYear()+1 );
+ else
+ return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() );
+ }
+ else
+ return maFirstDate;
+}
+
+// -----------------------------------------------------------------------
+
+Date Calendar::GetLastMonth() const
+{
+ Date aDate = GetFirstMonth();
+ USHORT nMonthCount = GetMonthCount();
+ for ( USHORT i = 0; i < nMonthCount; i++ )
+ aDate += aDate.GetDaysInMonth();
+ aDate--;
+ return aDate;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT Calendar::GetMonthCount() const
+{
+ if ( mbFormat )
+ return 1;
+ else
+ return (USHORT)(mnMonthPerLine*mnLines);
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::GetDropDate( Date& rDate ) const
+{
+ if( mbDropPos )
+ {
+ rDate = maDropDate;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::GetDate( const Point& rPos, Date& rDate ) const
+{
+ Date aDate = maCurDate;
+ USHORT nHitTest = ImplHitTest( rPos, aDate );
+ if ( nHitTest & CALENDAR_HITTEST_DAY )
+ {
+ rDate = aDate;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle Calendar::GetDateRect( const Date& rDate ) const
+{
+ Rectangle aRect;
+
+ if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) )
+ return aRect;
+
+ long nX;
+ long nY;
+ ULONG nDaysOff;
+ USHORT nDayIndex;
+ Date aDate = GetFirstMonth();
+
+ if ( rDate < aDate )
+ {
+ aRect = GetDateRect( aDate );
+ nDaysOff = aDate-rDate;
+ nX = (long)(nDaysOff*mnDayWidth);
+ aRect.Left() -= nX;
+ aRect.Right() -= nX;
+ return aRect;
+ }
+ else
+ {
+ Date aLastDate = GetLastMonth();
+ if ( rDate > aLastDate )
+ {
+ USHORT nWeekDay = (USHORT)aLastDate.GetDayOfWeek();
+ nWeekDay = (nWeekDay+(7-(USHORT)maIntn.GetWeekStart())) % 7;
+ aLastDate -= nWeekDay;
+ aRect = GetDateRect( aLastDate );
+ nDaysOff = rDate-aLastDate;
+ nDayIndex = 0;
+ for ( USHORT i = 0; i <= nDaysOff; i++ )
+ {
+ if ( aLastDate == rDate )
+ {
+ aRect.Left() += nDayIndex*mnDayWidth;
+ aRect.Right() = aRect.Left()+mnDayWidth;
+ return aRect;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ aRect.Top() += mnDayHeight;
+ aRect.Bottom() += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ aLastDate++;
+ }
+ }
+ }
+
+ nY = 0;
+ for ( long i = 0; i < mnLines; i++ )
+ {
+ nX = 0;
+ for ( long j = 0; j < mnMonthPerLine; j++ )
+ {
+ USHORT nDaysInMonth = aDate.GetDaysInMonth();
+
+ // Monat gerufen
+ if ( (aDate.GetMonth() == rDate.GetMonth()) &&
+ (aDate.GetYear() == rDate.GetYear()) )
+ {
+ long nDayX = nX+mnDaysOffX;
+ long nDayY = nY+mnDaysOffY;
+ nDayIndex = (USHORT)aDate.GetDayOfWeek();
+ nDayIndex = (nDayIndex+(7-(USHORT)maIntn.GetWeekStart())) % 7;
+ for ( USHORT nDay = 1; nDay <= nDaysInMonth; nDay++ )
+ {
+ if ( nDay == rDate.GetDay() )
+ {
+ aRect.Left() = nDayX + (nDayIndex*mnDayWidth);
+ aRect.Top() = nDayY;
+ aRect.Right() = aRect.Left()+mnDayWidth;
+ aRect.Bottom() = aRect.Top()+mnDayHeight;
+ break;
+ }
+ if ( nDayIndex == 6 )
+ {
+ nDayIndex = 0;
+ nDayY += mnDayHeight;
+ }
+ else
+ nDayIndex++;
+ }
+ }
+
+ aDate += nDaysInMonth;
+ nX += mnMonthWidth;
+ }
+
+ nY += mnMonthHeight;
+ }
+
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetStandardColor( const Color& rColor )
+{
+ if ( mpStandardColor )
+ *mpStandardColor = rColor;
+ else
+ mpStandardColor = new Color( rColor );
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetSaturdayColor( const Color& rColor )
+{
+ if ( mpSaturdayColor )
+ *mpSaturdayColor = rColor;
+ else
+ mpSaturdayColor = new Color( rColor );
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::SetSundayColor( const Color& rColor )
+{
+ if ( mpSundayColor )
+ *mpSundayColor = rColor;
+ else
+ mpSundayColor = new Color( rColor );
+ ImplUpdate();
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::AddDateInfo( const Date& rDate, const String& rText,
+ const Color* pTextColor, const Color* pFrameColor,
+ USHORT nFlags )
+{
+ if ( !mpDateTable )
+ mpDateTable = new ImplDateTable( 256, 256 );
+
+ BOOL bChanged = FALSE;
+ ULONG nKey = rDate.GetDate();
+ ImplDateInfo* pDateInfo = mpDateTable->Get( nKey );
+ if ( pDateInfo )
+ pDateInfo->maText = rText;
+ else
+ {
+ pDateInfo = new ImplDateInfo( rText );
+ mpDateTable->Insert( nKey, pDateInfo );
+ }
+ if ( pTextColor )
+ {
+ if ( pDateInfo->mpTextColor )
+ {
+ if ( *(pDateInfo->mpTextColor) != *pTextColor )
+ {
+ *(pDateInfo->mpTextColor) = *pTextColor;
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ pDateInfo->mpTextColor = new Color( *pTextColor );
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ if ( pDateInfo->mpTextColor )
+ {
+ delete pDateInfo->mpTextColor;
+ pDateInfo->mpTextColor = NULL;
+ bChanged = TRUE;
+ }
+ }
+ if ( pFrameColor )
+ {
+ if ( pDateInfo->mpFrameColor )
+ {
+ if ( *(pDateInfo->mpFrameColor) != *pFrameColor )
+ {
+ *(pDateInfo->mpFrameColor) = *pFrameColor;
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ pDateInfo->mpFrameColor = new Color( *pFrameColor );
+ bChanged = TRUE;
+ }
+ }
+ else
+ {
+ if ( pDateInfo->mpFrameColor )
+ {
+ delete pDateInfo->mpFrameColor;
+ pDateInfo->mpFrameColor = NULL;
+ bChanged = TRUE;
+ }
+ }
+ if ( pDateInfo->mnFlags != nFlags )
+ {
+ pDateInfo->mnFlags = nFlags;
+ bChanged = TRUE;
+ }
+
+ if ( bChanged )
+ ImplUpdateDate( rDate );
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::RemoveDateInfo( const Date& rDate )
+{
+ if ( mpDateTable )
+ {
+ ImplDateInfo* pDateInfo = mpDateTable->Remove( rDate.GetDate() );
+ if ( pDateInfo )
+ {
+ delete pDateInfo;
+ ImplUpdateDate( rDate );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::ClearDateInfo()
+{
+ if ( mpDateTable )
+ {
+ ImplDateInfo* pDateInfo = mpDateTable->First();
+ while ( pDateInfo )
+ {
+ ULONG nKey = mpDateTable->GetCurKey();
+ mpDateTable->Remove( nKey );
+ Date aDate( nKey );
+ ImplUpdateDate( aDate );
+ delete pDateInfo;
+ pDateInfo = mpDateTable->First();
+ }
+ delete mpDateTable;
+ mpDateTable = NULL;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString Calendar::GetDateInfoText( const Date& rDate )
+{
+ XubString aRet;
+ if ( mpDateTable )
+ {
+ ULONG nKey = rDate.GetDate();
+ ImplDateInfo* pDateInfo = mpDateTable->Get( nKey );
+ if ( pDateInfo )
+ aRet = pDateInfo->maText;
+ }
+ return aRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL Calendar::ShowDropPos( const Point& rPos, Date& rDate )
+{
+ Date aTempDate = maCurDate;
+ mnDragScrollHitTest = ImplHitTest( rPos, aTempDate );
+
+ if ( mnDragScrollHitTest )
+ {
+ if ( mnDragScrollHitTest & (CALENDAR_HITTEST_PREV | CALENDAR_HITTEST_NEXT) )
+ {
+ if ( !maDragScrollTimer.IsActive() )
+ maDragScrollTimer.Start();
+ }
+ else
+ {
+ maDragScrollTimer.Stop();
+ if ( mnDragScrollHitTest & CALENDAR_HITTEST_DAY )
+ {
+ if ( !mbDropPos || (aTempDate != maDropDate) )
+ {
+ if( mbDropPos )
+ ImplInvertDropPos();
+ maDropDate = aTempDate;
+ mbDropPos = TRUE;
+ ImplInvertDropPos();
+ }
+
+ rDate = maDropDate;
+ return TRUE;
+ }
+ }
+ }
+ else
+ maDragScrollTimer.Stop();
+
+ HideDropPos();
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::HideDropPos()
+{
+ if ( mbDropPos )
+ {
+ ImplInvertDropPos();
+ mbDropPos = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::StartSelection()
+{
+ if ( mpOldSelectTable )
+ delete mpOldSelectTable;
+ maOldCurDate = maCurDate;
+ mpOldSelectTable = new Table( *mpSelectTable );
+
+ mbSelection = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void Calendar::EndSelection()
+{
+ if ( mbDrag || mbSpinDown || mbSelection )
+ {
+ if ( !mbSelection )
+ ReleaseMouse();
+
+ mbDrag = FALSE;
+ mbSelection = FALSE;
+ mbMultiSelection = FALSE;
+ mbSpinDown = FALSE;
+ mbPrevIn = FALSE;
+ mbNextIn = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size Calendar::CalcWindowSizePixel( long nCalcMonthPerLine,
+ long nCalcLines ) const
+{
+ XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
+ Font aOldFont = GetFont();
+
+ // Wochenanzeige beruecksichtigen
+ long nWeekWidth;
+ if ( mnWinStyle & WB_WEEKNUMBER )
+ {
+ Font aTempFont = aOldFont;
+ ImplGetWeekFont( aTempFont );
+ ((Calendar*)this)->SetFont( aTempFont );
+ nWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
+ ((Calendar*)this)->SetFont( aOldFont );
+ }
+ else
+ nWeekWidth = 0;
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ {
+ Font aFont = aOldFont;
+ if ( aFont.GetWeight() < WEIGHT_BOLD )
+ aFont.SetWeight( WEIGHT_BOLD );
+ else
+ aFont.SetWeight( WEIGHT_NORMAL );
+ ((Calendar*)this)->SetFont( aFont );
+ }
+
+ Size aSize;
+ long n99TextWidth = GetTextWidth( a99Text );
+ long nTextHeight = GetTextHeight();
+
+ if ( mnWinStyle & WB_BOLDTEXT )
+ ((Calendar*)this)->SetFont( aOldFont );
+
+ aSize.Width() += ((n99TextWidth+DAY_OFFX)*7) + nWeekWidth;
+ aSize.Width() += MONTH_BORDERX*2;
+ aSize.Width() *= nCalcMonthPerLine;
+
+ aSize.Height() = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
+ aSize.Height() += nTextHeight + WEEKDAY_OFFY;
+ aSize.Height() += ((nTextHeight+DAY_OFFY)*6);
+ aSize.Height() += MONTH_OFFY;
+ aSize.Height() *= nCalcLines;
+
+ return aSize;
+}
+
+// =======================================================================
+
+#define CALFIELD_EXTRA_BUTTON_WIDTH 14
+#define CALFIELD_EXTRA_BUTTON_HEIGHT 8
+#define CALFIELD_SEP_X 6
+#define CALFIELD_BORDERLINE_X 5
+#define CALFIELD_BORDER_YTOP 4
+#define CALFIELD_BORDER_Y 5
+
+// =======================================================================
+
+class ImplCFieldFloatWin : public FloatingWindow
+{
+private:
+ Calendar* mpCalendar;
+ PushButton* mpTodayBtn;
+ PushButton* mpNoneBtn;
+ FixedLine* mpFixedLine;
+
+public:
+ ImplCFieldFloatWin( Window* pParent );
+ ~ImplCFieldFloatWin();
+
+ void SetCalendar( Calendar* pCalendar )
+ { mpCalendar = pCalendar; }
+
+ PushButton* EnableTodayBtn( BOOL bEnable );
+ PushButton* EnableNoneBtn( BOOL bEnable );
+ void ArrangeButtons();
+
+ long Notify( NotifyEvent& rNEvt );
+};
+
+// -----------------------------------------------------------------------
+
+ImplCFieldFloatWin::ImplCFieldFloatWin( Window* pParent ) :
+ FloatingWindow( pParent )
+{
+ mpCalendar = NULL;
+ mpTodayBtn = NULL;
+ mpNoneBtn = NULL;
+ mpFixedLine = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplCFieldFloatWin::~ImplCFieldFloatWin()
+{
+ delete mpTodayBtn;
+ delete mpNoneBtn;
+ delete mpFixedLine;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton* ImplCFieldFloatWin::EnableTodayBtn( BOOL bEnable )
+{
+ if ( bEnable )
+ {
+ if ( !mpTodayBtn )
+ {
+ mpTodayBtn = new PushButton( this, WB_NOPOINTERFOCUS );
+ XubString aTodayText( SvtResId( STR_SVT_CALENDAR_TODAY ) );
+ mpTodayBtn->SetText( aTodayText );
+ Size aSize;
+ aSize.Width() = mpTodayBtn->GetCtrlTextWidth( mpTodayBtn->GetText() );
+ aSize.Height() = mpTodayBtn->GetTextHeight();
+ aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH;
+ aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
+ mpTodayBtn->SetSizePixel( aSize );
+ mpTodayBtn->Show();
+ }
+ }
+ else
+ {
+ if ( mpTodayBtn )
+ {
+ delete mpTodayBtn;
+ mpTodayBtn = NULL;
+ }
+ }
+
+ return mpTodayBtn;
+}
+
+// -----------------------------------------------------------------------
+
+PushButton* ImplCFieldFloatWin::EnableNoneBtn( BOOL bEnable )
+{
+ if ( bEnable )
+ {
+ if ( !mpNoneBtn )
+ {
+ mpNoneBtn = new PushButton( this, WB_NOPOINTERFOCUS );
+ XubString aNoneText( SvtResId( STR_SVT_CALENDAR_NONE ) );
+ mpNoneBtn->SetText( aNoneText );
+ Size aSize;
+ aSize.Width() = mpNoneBtn->GetCtrlTextWidth( mpNoneBtn->GetText() );
+ aSize.Height() = mpNoneBtn->GetTextHeight();
+ aSize.Width() += CALFIELD_EXTRA_BUTTON_WIDTH;
+ aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
+ mpNoneBtn->SetSizePixel( aSize );
+ mpNoneBtn->Show();
+ }
+ }
+ else
+ {
+ if ( mpNoneBtn )
+ {
+ delete mpNoneBtn;
+ mpNoneBtn = NULL;
+ }
+ }
+
+ return mpNoneBtn;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplCFieldFloatWin::ArrangeButtons()
+{
+ long nBtnHeight = 0;
+ long nBtnWidth = 0;
+ Size aOutSize = GetOutputSizePixel();
+ if ( mpTodayBtn && mpNoneBtn )
+ {
+ Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
+ Size aNoneBtnSize = mpNoneBtn->GetSizePixel();
+ if ( aTodayBtnSize.Width() < aNoneBtnSize.Width() )
+ aTodayBtnSize.Width() = aNoneBtnSize.Width();
+ else
+ aNoneBtnSize.Width() = aTodayBtnSize.Width();
+ if ( aTodayBtnSize.Height() < aNoneBtnSize.Height() )
+ aTodayBtnSize.Height() = aNoneBtnSize.Height();
+ else
+ aNoneBtnSize.Height() = aTodayBtnSize.Height();
+
+ nBtnWidth = aTodayBtnSize.Width() + aNoneBtnSize.Width() + CALFIELD_SEP_X;
+ nBtnHeight = aTodayBtnSize.Height();
+ long nX = (aOutSize.Width()-nBtnWidth)/2;
+ long nY = aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP;
+ mpTodayBtn->SetPosSizePixel( Point( nX, nY ), aTodayBtnSize );
+ nX += aTodayBtnSize.Width() + CALFIELD_SEP_X;
+ mpNoneBtn->SetPosSizePixel( Point( nX, nY ), aNoneBtnSize );
+ }
+ else if ( mpTodayBtn )
+ {
+ Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
+ nBtnWidth = aTodayBtnSize.Width();
+ nBtnHeight = aTodayBtnSize.Height();
+ mpTodayBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
+ }
+ else if ( mpNoneBtn )
+ {
+ Size aNoneBtnSize = mpNoneBtn->GetSizePixel();
+ nBtnWidth = aNoneBtnSize.Width();
+ nBtnHeight = aNoneBtnSize.Height();
+ mpNoneBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
+ }
+
+ if ( nBtnHeight )
+ {
+ if ( !mpFixedLine )
+ {
+ mpFixedLine = new FixedLine( this );
+ mpFixedLine->Show();
+ }
+ long nLineWidth = aOutSize.Width()-(CALFIELD_BORDERLINE_X*2);
+ mpFixedLine->SetPosSizePixel( (aOutSize.Width()-nLineWidth)/2, aOutSize.Height()+((CALFIELD_BORDER_YTOP-2)/2),
+ nLineWidth, 2, WINDOW_POSSIZE_POSSIZE );
+ aOutSize.Height() += nBtnHeight + (CALFIELD_BORDER_Y*2) + CALFIELD_BORDER_YTOP;
+ SetOutputSizePixel( aOutSize );
+ }
+ else
+ {
+ if ( mpFixedLine )
+ {
+ delete mpFixedLine;
+ mpFixedLine = NULL;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long ImplCFieldFloatWin::Notify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
+ mpCalendar->Select();
+ }
+
+ return FloatingWindow::Notify( rNEvt );
+}
+
+// =======================================================================
+
+CalendarField::CalendarField( Window* pParent, WinBits nWinStyle ) :
+ DateField( pParent, nWinStyle ),
+ maDefaultDate( 0, 0, 0 )
+{
+ mpFloatWin = NULL;
+ mpCalendar = NULL;
+ mnCalendarStyle = 0;
+ mbToday = FALSE;
+ mbNone = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+CalendarField::CalendarField( Window* pParent, const ResId& rResId ) :
+ DateField( pParent, rResId ),
+ maDefaultDate( 0, 0, 0 )
+{
+ mpFloatWin = NULL;
+ mpCalendar = NULL;
+ mnCalendarStyle = 0;
+ mbToday = FALSE;
+ mbNone = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+CalendarField::~CalendarField()
+{
+ if ( mpFloatWin )
+ {
+ delete mpCalendar;
+ delete mpFloatWin;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( CalendarField, ImplSelectHdl, Calendar*, pCalendar )
+{
+ if ( !pCalendar->IsTravelSelect() )
+ {
+ mpFloatWin->EndPopupMode();
+ EndDropDown();
+ GrabFocus();
+ Date aNewDate = mpCalendar->GetSelectDate( 0 );
+ if ( IsEmptyDate() || ( aNewDate != GetDate() ) )
+ {
+ SetDate( aNewDate );
+ SetModifyFlag();
+ Modify();
+ }
+ Select();
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( CalendarField, ImplClickHdl, PushButton*, pBtn )
+{
+ mpFloatWin->EndPopupMode();
+ EndDropDown();
+ GrabFocus();
+
+ if ( pBtn == mpTodayBtn )
+ {
+ Date aToday;
+ if ( (aToday != GetDate()) || IsEmptyDate() )
+ {
+ SetDate( aToday );
+ SetModifyFlag();
+ Modify();
+ }
+ }
+ else if ( pBtn == mpNoneBtn )
+ {
+ if ( !IsEmptyDate() )
+ {
+ SetEmptyDate();
+ SetModifyFlag();
+ Modify();
+ }
+ }
+ Select();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( CalendarField, ImplPopupModeEndHdl, FloatingWindow*, EMPTYARG )
+{
+ EndDropDown();
+ GrabFocus();
+ mpCalendar->EndSelection();
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void CalendarField::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL CalendarField::ShowDropDown( BOOL bShow )
+{
+ if ( bShow )
+ {
+ Calendar* pCalendar = GetCalendar();
+
+ Date aDate = GetDate();
+ if ( IsEmptyDate() || !aDate.IsValid() )
+ {
+ if ( maDefaultDate.IsValid() )
+ aDate = maDefaultDate;
+ else
+ aDate = Date();
+ }
+ if ( pCalendar->GetStyle() & (WB_RANGESELECT | WB_MULTISELECT) )
+ {
+ pCalendar->SetNoSelection();
+ pCalendar->SelectDate( aDate );
+ }
+ pCalendar->SetCurDate( aDate );
+ Point aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
+ Rectangle aRect( aPos, GetSizePixel() );
+ aRect.Bottom() -= 1;
+ mpCalendar->SetOutputSizePixel( mpCalendar->CalcWindowSizePixel() );
+ mpFloatWin->SetOutputSizePixel( mpCalendar->GetSizePixel() );
+ mpFloatWin->SetCalendar( mpCalendar );
+ mpTodayBtn = mpFloatWin->EnableTodayBtn( mbToday );
+ mpNoneBtn = mpFloatWin->EnableNoneBtn( mbNone );
+ if ( mpTodayBtn )
+ mpTodayBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
+ if ( mpNoneBtn )
+ mpNoneBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
+ mpFloatWin->ArrangeButtons();
+ mpCalendar->EnableCallEverySelect();
+ mpCalendar->StartSelection();
+ mpCalendar->GrabFocus();
+ mpCalendar->Show();
+ mpFloatWin->StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );
+ }
+ else
+ {
+ mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
+ mpCalendar->EndSelection();
+ EndDropDown();
+ }
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Calendar* CalendarField::CreateCalendar( Window* pParent )
+{
+ return new Calendar( pParent, mnCalendarStyle | WB_TABSTOP );
+}
+
+// -----------------------------------------------------------------------
+
+Calendar* CalendarField::GetCalendar()
+{
+ if ( !mpFloatWin )
+ {
+ mpFloatWin = new ImplCFieldFloatWin( this );
+ mpFloatWin->SetPopupModeEndHdl( LINK( this, CalendarField, ImplPopupModeEndHdl ) );
+ mpCalendar = CreateCalendar( mpFloatWin );
+ mpCalendar->SetPosPixel( Point() );
+ mpCalendar->SetSelectHdl( LINK( this, CalendarField, ImplSelectHdl ) );
+ }
+
+ return mpCalendar;
+}
diff --git a/svtools/source/control/calendar.src b/svtools/source/control/calendar.src
new file mode 100644
index 000000000000..2919e3d55148
--- /dev/null
+++ b/svtools/source/control/calendar.src
@@ -0,0 +1,166 @@
+/*************************************************************************
+ *
+ * $RCSfile: calendar.src,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 "svtools.hrc"
+String STR_SVT_CALENDAR_DAY
+{
+ Text = "Tag" ;
+ Text [ ENGLISH ] = "Day" ;
+ Text [ english_us ] = "Day" ;
+ Text [ italian ] = "Giorno" ;
+ Text [ spanish ] = "Día" ;
+ Text [ french ] = "Jour" ;
+ Text [ dutch ] = "Dag" ;
+ Text [ swedish ] = "Dag" ;
+ Text [ danish ] = "Dag" ;
+ Text [ portuguese_brazilian ] = "Tag" ;
+ Text [ portuguese ] = "Dia" ;
+ Text[ chinese_simplified ] = "Ìì";
+ Text[ russian ] = "Äåíü";
+ Text[ polish ] = "dzieñ";
+ Text[ japanese ] = "“ú";
+ Text[ chinese_traditional ] = "¤Ñ";
+ Text[ arabic ] = "íæã";
+ Text[ dutch ] = "Dag";
+ Text[ chinese_simplified ] = "Ìì";
+ Text[ greek ] = "ÇìÝñá";
+ Text[ korean ] = "ÀÏÀÚ";
+ Text[ turkish ] = "Gün";
+ Text[ language_user1 ] = " ";
+};
+String STR_SVT_CALENDAR_WEEK
+{
+ Text = "Woche" ;
+ Text [ ENGLISH ] = "Week" ;
+ Text [ dutch ] = "Week" ;
+ Text [ english_us ] = "Week" ;
+ Text [ italian ] = "Settim." ;
+ Text [ spanish ] = "Semana" ;
+ Text [ french ] = "Semaine" ;
+ Text [ swedish ] = "Vecka" ;
+ Text [ danish ] = "Uge" ;
+ Text [ portuguese ] = "Semana" ;
+ Text [ portuguese_brazilian ] = "Woche" ;
+ Text[ chinese_simplified ] = "ÖÜ";
+ Text[ russian ] = "Íåäåëÿ";
+ Text[ polish ] = "tydzieñ";
+ Text[ japanese ] = "T";
+ Text[ chinese_traditional ] = "©P";
+ Text[ arabic ] = "ÃÓÈæÚ";
+ Text[ dutch ] = "Week";
+ Text[ chinese_simplified ] = "ÖÜ";
+ Text[ greek ] = "ÅâäïìÜäá";
+ Text[ korean ] = "ÁÖ";
+ Text[ turkish ] = "Hafta";
+ Text[ language_user1 ] = " ";
+};
+String STR_SVT_CALENDAR_TODAY
+{
+ Text = "Heute" ;
+ Text [ ENGLISH ] = "Today" ;
+ Text [ portuguese ] = "Hoje" ;
+ Text [ english_us ] = "Today" ;
+ Text [ portuguese_brazilian ] = "Heute" ;
+ Text [ swedish ] = "Idag" ;
+ Text [ danish ] = "I dag" ;
+ Text [ italian ] = "Oggi" ;
+ Text [ spanish ] = "Hoy" ;
+ Text [ french ] = "Aujourd'hui" ;
+ Text [ dutch ] = "Vandaag" ;
+ Text[ chinese_simplified ] = "½ñÌì";
+ Text[ russian ] = "Ñåãîäíÿ";
+ Text[ polish ] = "dzisiaj";
+ Text[ japanese ] = "¡“ú";
+ Text[ chinese_traditional ] = "¤µ¤Ñ";
+ Text[ arabic ] = "Çáíæã";
+ Text[ dutch ] = "Vandaag";
+ Text[ chinese_simplified ] = "½ñÌì";
+ Text[ greek ] = "ÓÞìåñá";
+ Text[ korean ] = "¿À´Ã";
+ Text[ turkish ] = "Bugün";
+ Text[ language_user1 ] = " ";
+};
+String STR_SVT_CALENDAR_NONE
+{
+ Text = "Keines" ;
+ Text [ ENGLISH ] = "None" ;
+ Text [ portuguese ] = "Nenhum" ;
+ Text [ english_us ] = "None" ;
+ Text [ portuguese_brazilian ] = "Keines" ;
+ Text [ swedish ] = "Ingen" ;
+ Text [ danish ] = "Ingen" ;
+ Text [ italian ] = "Senza" ;
+ Text [ spanish ] = "Ninguno" ;
+ Text [ french ] = "Aucun(e)" ;
+ Text [ dutch ] = "Geen" ;
+ Text[ chinese_simplified ] = "ÎÞ";
+ Text[ russian ] = "Áåç";
+ Text[ polish ] = "brak";
+ Text[ japanese ] = "‚È‚µ";
+ Text[ chinese_traditional ] = "µL";
+ Text[ arabic ] = "ÈÏæä";
+ Text[ dutch ] = "Geen";
+ Text[ chinese_simplified ] = "ÎÞ";
+ Text[ greek ] = "ÊáíÝíá";
+ Text[ korean ] = "¾øÀ½";
+ Text[ turkish ] = "Yok";
+ Text[ language_user1 ] = " ";
+};
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
new file mode 100644
index 000000000000..2af1f99aeadf
--- /dev/null
+++ b/svtools/source/control/ctrlbox.cxx
@@ -0,0 +1,1227 @@
+/*************************************************************************
+ *
+ * $RCSfile: ctrlbox.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _CTRLBOX_CXX
+
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _FIELD_HXX
+#include <vcl/field.hxx>
+#endif
+
+#include <svtdata.hxx>
+#include <svtools.hrc>
+#include <ctrlbox.hxx>
+#include <ctrltool.hxx>
+
+#define IMGTEXTSPACE 2
+#define SYMBOLFONTTEXT "AbCdEfGhIj"
+#define EXTRAFONTSIZE 5
+
+// ========================================================================
+// ColorListBox
+// ========================================================================
+
+// --------------------
+// - ImplColorListData -
+// --------------------
+
+struct ImplColorListData
+{
+ Color aColor;
+ BOOL bColor;
+
+ ImplColorListData() : aColor( COL_BLACK ) { bColor = FALSE; }
+ ImplColorListData( const Color& rColor ) : aColor( rColor ) { bColor = TRUE; }
+};
+
+DECLARE_LIST( ImpColorList, ImplColorListData* );
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::ImplInit()
+{
+ pColorList = new ImpColorList( 256, 64 );
+ aImageSize.Width() = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "xxx" ) ) );
+ aImageSize.Height() = GetTextHeight();
+ aImageSize.Height() -= 2;
+
+ EnableUserDraw( TRUE );
+ SetUserItemSize( aImageSize );
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::ImplDestroyColorEntries()
+{
+ for ( USHORT n = (USHORT) pColorList->Count(); n; )
+ {
+ ImplColorListData* pData = pColorList->GetObject( --n );
+ delete pData;
+ }
+ pColorList->Clear();
+}
+
+// -----------------------------------------------------------------------
+
+ColorListBox::ColorListBox( Window* pParent, WinBits nWinStyle ) :
+ ListBox( pParent, nWinStyle )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ColorListBox::ColorListBox( Window* pParent, const ResId& rResId ) :
+ ListBox( pParent, rResId )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ColorListBox::~ColorListBox()
+{
+ ImplDestroyColorEntries();
+ delete pColorList;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ColorListBox::InsertEntry( const XubString& rStr, USHORT nPos )
+{
+ nPos = ListBox::InsertEntry( rStr, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ {
+ ImplColorListData* pData = new ImplColorListData;
+ pColorList->Insert( pData, nPos );
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ColorListBox::InsertEntry( const Color& rColor, const XubString& rStr,
+ USHORT nPos )
+{
+ nPos = ListBox::InsertEntry( rStr, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ {
+ ImplColorListData* pData = new ImplColorListData( rColor );
+ pColorList->Insert( pData, nPos );
+ }
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::RemoveEntry( USHORT nPos )
+{
+ ListBox::RemoveEntry( nPos );
+ delete pColorList->Remove( nPos );
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::Clear()
+{
+ ImplDestroyColorEntries();
+ ListBox::Clear();
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::CopyEntries( const ColorListBox& rBox )
+{
+ // Liste leeren
+ ImplDestroyColorEntries();
+
+ // Daten kopieren
+ USHORT nCount = (USHORT) rBox.pColorList->Count();
+ for ( USHORT n = 0; n < nCount; n++ )
+ {
+ ImplColorListData* pData = rBox.pColorList->GetObject( n );
+ USHORT nPos = InsertEntry( rBox.GetEntry( n ), LISTBOX_APPEND );
+ if ( nPos != LISTBOX_ERROR )
+ pColorList->Insert( new ImplColorListData( *pData ), nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ColorListBox::GetEntryPos( const Color& rColor ) const
+{
+ for( USHORT n = (USHORT) pColorList->Count(); n; )
+ {
+ ImplColorListData* pData = pColorList->GetObject( --n );
+ if ( pData->bColor && ( pData->aColor == rColor ) )
+ {
+ return n;
+ }
+ }
+ return LISTBOX_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+Color ColorListBox::GetEntryColor( USHORT nPos ) const
+{
+ Color aColor;
+ ImplColorListData* pData = pColorList->GetObject( nPos );
+ if ( pData && pData->bColor )
+ aColor = pData->aColor;
+ return aColor;
+}
+
+// -----------------------------------------------------------------------
+
+void ColorListBox::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ ImplColorListData* pData = pColorList->GetObject( rUDEvt.GetItemId() );
+ if ( pData )
+ {
+ if ( pData->bColor )
+ {
+ Point aPos( rUDEvt.GetRect().TopLeft() );
+ aPos.X() += 2;
+ aPos.Y() += ( rUDEvt.GetRect().GetHeight() - aImageSize.Height() ) / 2;
+ rUDEvt.GetDevice()->Push();
+ rUDEvt.GetDevice()->SetFillColor( pData->aColor );
+ rUDEvt.GetDevice()->SetLineColor( COL_BLACK );
+ rUDEvt.GetDevice()->DrawRect( Rectangle( aPos, aImageSize ) );
+ rUDEvt.GetDevice()->Pop();
+ ListBox::DrawEntry( rUDEvt, FALSE, TRUE, FALSE );
+ }
+ else
+ {
+ ListBox::DrawEntry( rUDEvt, FALSE, TRUE, TRUE );
+ }
+ }
+ else
+ {
+ ListBox::DrawEntry( rUDEvt, TRUE, TRUE, FALSE );
+ }
+}
+
+// =======================================================================
+// LineListBox
+// =======================================================================
+
+// -------------------
+// - ImpListListData -
+// -------------------
+
+struct ImpLineListData
+{
+ long nLine1;
+ long nLine2;
+ long nDistance;
+};
+
+DECLARE_LIST( ImpLineList, ImpLineListData* );
+
+// -----------------------------------------------------------------------
+
+void LineListBox::ImpGetLine( long nLine1, long nLine2, long nDistance,
+ Bitmap& rBmp, XubString& rStr )
+{
+ Size aSize = GetOutputSizePixel();
+ aSize.Width() -= 20;
+ aSize.Width() -= aTxtSize.Width();
+ aSize.Height() = aTxtSize.Height();
+
+ // SourceUnit nach Twips
+ if ( eSourceUnit == FUNIT_POINT )
+ {
+ nLine1 *= 20;
+ nLine2 *= 20;
+ nDistance *= 20;
+ }
+ else if ( eSourceUnit == FUNIT_MM )
+ {
+ nLine1 *= 14440;
+ nLine1 /= 254;
+ nLine2 *= 14440;
+ nLine2 /= 254;
+ nDistance *= 14440;
+ nDistance /= 254;
+ }
+
+ // Linien malen
+ aSize = aVirDev.PixelToLogic( aSize );
+ long nPix = aVirDev.PixelToLogic( Size( 0, 1 ) ).Height();
+ long n1 = nLine1 / 100;
+ long n2 = nLine2 / 100;
+ long nDist = nDistance / 100;
+ n1 += nPix-1;
+ n1 -= n1%nPix;
+ if ( n2 )
+ {
+ nDist += nPix-1;
+ nDist -= nDist%nPix;
+ n2 += nPix-1;
+ n2 -= n2%nPix;
+ }
+ long nVirHeight = n1+nDist+n2;
+ if ( nVirHeight > aSize.Height() )
+ aSize.Height() = nVirHeight;
+ // negative Breiten muss und darf man nicht painten
+ if ( aSize.Width() > 0 )
+ {
+ Size aVirSize = aVirDev.LogicToPixel( aSize );
+ if ( aVirDev.GetOutputSizePixel() != aVirSize )
+ aVirDev.SetOutputSizePixel( aVirSize );
+ aVirDev.SetFillColor( GetSettings().GetStyleSettings().GetFieldColor() );
+ aVirDev.DrawRect( Rectangle( Point(), aSize ) );
+ aVirDev.SetFillColor( aColor );
+ aVirDev.DrawRect( Rectangle( 0, 0, aSize.Width(), n1-nPix ) );
+ if ( n2 )
+ {
+ aVirDev.DrawRect( Rectangle( 0, n1+nDist,
+ aSize.Width(), n1+nDist+n2-nPix ) );
+ }
+ rBmp = aVirDev.GetBitmap( Point(), Size( aSize.Width(), n1+nDist+n2 ) );
+ }
+ // Twips nach Unit
+ if ( eUnit == FUNIT_POINT )
+ {
+ nLine1 /= 20;
+ nLine2 /= 20;
+ nDistance /= 20;
+ rStr.AssignAscii( " pt" );
+ }
+ else if ( eUnit == FUNIT_MM )
+ {
+ nLine1 *= 254;
+ nLine1 /= 14400;
+ nLine2 *= 254;
+ nLine2 /= 14400;
+ nDistance *= 254;
+ nDistance /= 14400;
+ rStr.AssignAscii( " mm" );
+ }
+
+ rStr.Insert( aIntn.GetNum( nLine1+nLine2+nDistance, 2 ), 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::ImplInit()
+{
+ aTxtSize.Width() = GetTextWidth( XubString( RTL_CONSTASCII_USTRINGPARAM( "99,99 mm" ) ) );
+ aTxtSize.Height() = GetTextHeight();
+ pLineList = new ImpLineList;
+ eUnit = FUNIT_POINT;
+ eSourceUnit = FUNIT_POINT;
+
+ aVirDev.SetLineColor();
+ aVirDev.SetMapMode( MapMode( MAP_TWIP ) );
+}
+
+// -----------------------------------------------------------------------
+
+LineListBox::LineListBox( Window* pParent, WinBits nWinStyle ) :
+ ListBox( pParent, nWinStyle ),
+ aIntn( Application::GetAppInternational() ),
+ aColor( COL_BLACK )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+LineListBox::LineListBox( Window* pParent, const ResId& rResId ) :
+ ListBox( pParent, rResId ),
+ aIntn( Application::GetAppInternational() ),
+ aColor( COL_BLACK )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+LineListBox::~LineListBox()
+{
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ delete pData;
+ n++;
+ }
+ delete pLineList;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LineListBox::InsertEntry( const XubString& rStr, USHORT nPos )
+{
+ nPos = ListBox::InsertEntry( rStr, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ pLineList->Insert( NULL, nPos );
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LineListBox::InsertEntry( long nLine1, long nLine2, long nDistance,
+ USHORT nPos )
+{
+ XubString aStr;
+ Bitmap aBmp;
+ ImpGetLine( nLine1, nLine2, nDistance, aBmp, aStr );
+ nPos = ListBox::InsertEntry( aStr, aBmp, nPos );
+ if ( nPos != LISTBOX_ERROR )
+ {
+ ImpLineListData* pData = new ImpLineListData;
+ pData->nLine1 = nLine1;
+ pData->nLine2 = nLine2;
+ pData->nDistance = nDistance;
+ pLineList->Insert( pData, nPos );
+ }
+
+ return nPos;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::RemoveEntry( USHORT nPos )
+{
+ ListBox::RemoveEntry( nPos );
+ ImpLineListData* pData = pLineList->Remove( nPos );
+ if ( pData )
+ delete pData;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::Clear()
+{
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ delete pData;
+ n++;
+ }
+
+ pLineList->Clear();
+ ListBox::Clear();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT LineListBox::GetEntryPos( long nLine1, long nLine2,
+ long nDistance ) const
+{
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ {
+ if ( (pData->nLine1 == nLine1) &&
+ (pData->nLine2 == nLine2) &&
+ (pData->nDistance == nDistance) )
+ return (USHORT)n;
+ }
+
+ n++;
+ }
+
+ return LISTBOX_ENTRY_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+long LineListBox::GetEntryLine1( USHORT nPos ) const
+{
+ ImpLineListData* pData = pLineList->GetObject( nPos );
+ if ( pData )
+ return pData->nLine1;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long LineListBox::GetEntryLine2( USHORT nPos ) const
+{
+ ImpLineListData* pData = pLineList->GetObject( nPos );
+ if ( pData )
+ return pData->nLine2;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long LineListBox::GetEntryDistance( USHORT nPos ) const
+{
+ ImpLineListData* pData = pLineList->GetObject( nPos );
+ if ( pData )
+ return pData->nDistance;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void LineListBox::SetColor( const Color& rColor )
+{
+ // Farben austauschen
+ aColor = rColor;
+
+ // Variablen anlegen
+ ULONG n = 0;
+ ULONG nCount = pLineList->Count();
+ if ( !nCount )
+ return;
+
+ XubString aStr;
+ Bitmap aBmp;
+
+ // Eintrage mit Linien austauschen
+ SetUpdateMode( FALSE );
+ USHORT nSelEntry = GetSelectEntryPos();
+ while ( n < nCount )
+ {
+ ImpLineListData* pData = pLineList->GetObject( n );
+ if ( pData )
+ {
+ // ListBox-Daten austauschen
+ ListBox::RemoveEntry( (USHORT)n );
+ ImpGetLine( pData->nLine1, pData->nLine2, pData->nDistance,
+ aBmp, aStr );
+ ListBox::InsertEntry( aStr, aBmp, (USHORT)n );
+ }
+
+ n++;
+ }
+
+ if ( nSelEntry != LISTBOX_ENTRY_NOTFOUND )
+ SelectEntryPos( nSelEntry );
+
+ SetUpdateMode( TRUE );
+ Invalidate();
+}
+
+// ===================================================================
+// FontNameBox
+// ===================================================================
+
+struct ImplFontNameListData
+{
+ FontInfo maInfo;
+ USHORT mnType;
+
+ ImplFontNameListData( const FontInfo& rInfo,
+ USHORT nType ) :
+ maInfo( rInfo ),
+ mnType( nType )
+ {}
+};
+
+DECLARE_LIST( ImplFontList, ImplFontNameListData* );
+
+// -------------------------------------------------------------------
+
+FontNameBox::FontNameBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle ),
+ maImagePrinterFont( SvtResId( RID_IMG_PRINTERFONT ) ),
+ maImageBitmapFont( SvtResId( RID_IMG_BITMAPFONT ) ),
+ maImageScalableFont( SvtResId( RID_IMG_SCALABLEFONT ) )
+{
+ mpFontList = NULL;
+ mbWYSIWYG = FALSE;
+ mbSymbols = FALSE;
+}
+
+// -------------------------------------------------------------------
+
+FontNameBox::FontNameBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( pParent, rResId ),
+ maImagePrinterFont( SvtResId( RID_IMG_PRINTERFONT ) ),
+ maImageBitmapFont( SvtResId( RID_IMG_BITMAPFONT ) ),
+ maImageScalableFont( SvtResId( RID_IMG_SCALABLEFONT ) )
+{
+ mpFontList = NULL;
+ mbWYSIWYG = FALSE;
+ mbSymbols = FALSE;
+}
+
+// -------------------------------------------------------------------
+
+FontNameBox::~FontNameBox()
+{
+ ImplDestroyFontList();
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::ImplDestroyFontList()
+{
+ if ( mpFontList )
+ {
+ ImplFontNameListData* pInfo = mpFontList->First();
+ while ( pInfo )
+ {
+ delete pInfo;
+ pInfo = mpFontList->Next();
+ }
+ delete mpFontList;
+ }
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::Fill( const FontList* pList )
+{
+ // Vorherigen Namen merken und Box loeschen
+ XubString aOldText = GetText();
+ Clear();
+
+ ImplDestroyFontList();
+ mpFontList = new ImplFontList;
+
+ // Fonts eintragen
+ USHORT nFontCount = pList->GetFontNameCount();
+ for ( USHORT i = 0; i < nFontCount; i++ )
+ {
+ const FontInfo& rFontInfo = pList->GetFontName( i );
+ ULONG nIndex = InsertEntry( rFontInfo.GetName() );
+ if ( nIndex != LISTBOX_ERROR )
+ {
+ USHORT nType = pList->GetFontNameType( i );
+ ImplFontNameListData* pData = new ImplFontNameListData( rFontInfo, nType );
+ mpFontList->Insert( pData, nIndex );
+ }
+ }
+
+ ImplCalcUserItemSize();
+
+ // Text wieder setzen
+ if ( aOldText.Len() )
+ SetText( aOldText );
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::EnableWYSIWYG( BOOL bEnable )
+{
+ if ( bEnable != mbWYSIWYG )
+ {
+ mbWYSIWYG = bEnable;
+ EnableUserDraw( mbWYSIWYG | mbSymbols );
+ ImplCalcUserItemSize();
+ }
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::EnableSymbols( BOOL bEnable )
+{
+ if ( bEnable != mbSymbols )
+ {
+ mbSymbols = bEnable;
+ EnableUserDraw( mbWYSIWYG | mbSymbols );
+ ImplCalcUserItemSize();
+ }
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::ImplCalcUserItemSize()
+{
+ Size aUserItemSz;
+ if ( mbWYSIWYG && mpFontList )
+ {
+ USHORT nMaxLen = 0;
+ BOOL bSymbolFont = FALSE;
+ for ( USHORT n = GetEntryCount(); n; )
+ {
+ ImplFontNameListData* pData = mpFontList->GetObject( --n );
+ XubString aFontName = pData->maInfo.GetName();
+ if ( aFontName.Len() > nMaxLen )
+ nMaxLen = aFontName.Len();
+ if ( pData->maInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
+ bSymbolFont = TRUE;
+ }
+
+ // Maximale Breite schaetzen
+ Size aOneCharSz( GetTextWidth( XubString( 'X' ) ), GetTextHeight() );
+ Size aSz( aOneCharSz );
+ aSz.Width() *= nMaxLen;
+ // Nur XX% der Breite, weil die ListBox die normalen Breiten berechnet...
+ aSz.Width() *= 1;
+ aSz.Width() /= 10;
+ if ( bSymbolFont )
+ aSz.Width() += (sizeof( SYMBOLFONTTEXT )-1) * aOneCharSz.Width();
+ aSz.Height() *= 14;
+ aSz.Height() /= 10;
+ aUserItemSz = aSz;
+ }
+ if ( mbSymbols )
+ {
+ Size aSz = maImageScalableFont.GetSizePixel();
+ aUserItemSz.Width() += aSz.Width() + IMGTEXTSPACE;
+ if ( aSz.Height() > aUserItemSz.Height() )
+ aUserItemSz.Height() = aSz.Height();
+ }
+ SetUserItemSize( aUserItemSz );
+}
+
+// -------------------------------------------------------------------
+
+void FontNameBox::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ ImplFontNameListData* pData = mpFontList->GetObject( rUDEvt.GetItemId() );
+ const FontInfo& rInfo = pData->maInfo;
+ USHORT nType = pData->mnType;
+ Point aTopLeft = rUDEvt.GetRect().TopLeft();
+ long nX = aTopLeft.X();
+ long nH = rUDEvt.GetRect().GetHeight();
+
+ if ( mbSymbols )
+ {
+ nX += IMGTEXTSPACE;
+ Image* pImg = NULL;
+ if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
+ pImg = &maImagePrinterFont;
+ else if ( nType & FONTLIST_FONTNAMETYPE_SCALABLE )
+ pImg = &maImageScalableFont;
+ else
+ pImg = &maImageBitmapFont;
+
+ if ( pImg )
+ {
+ Point aPos( nX, aTopLeft.Y() + (nH-pImg->GetSizePixel().Height())/2 );
+ rUDEvt.GetDevice()->DrawImage( aPos, *pImg );
+ }
+
+ // X immer um gleiche Breite aendern, auch wenn kein Image ausgegeben.
+ nX += maImagePrinterFont.GetSizePixel().Width();
+ }
+
+ if ( mbWYSIWYG && mpFontList )
+ {
+ nX += IMGTEXTSPACE;
+ BOOL bSymbolFont = rInfo.GetCharSet() == RTL_TEXTENCODING_SYMBOL;
+ if ( bSymbolFont )
+ {
+ XubString aText( rInfo.GetName() );
+ aText.AppendAscii( " " );
+ Point aPos( nX, aTopLeft.Y() + (nH-rUDEvt.GetDevice()->GetTextHeight())/2 );
+ rUDEvt.GetDevice()->DrawText( aPos, aText );
+ nX += rUDEvt.GetDevice()->GetTextWidth( aText );
+ }
+
+ Color aTextColor = rUDEvt.GetDevice()->GetTextColor();
+ Font aOldFont( rUDEvt.GetDevice()->GetFont() );
+ Size aSz( aOldFont.GetSize() );
+ aSz.Height() += EXTRAFONTSIZE;
+ Font aFont( rInfo );
+ aFont.SetSize( aSz );
+ rUDEvt.GetDevice()->SetFont( aFont );
+ rUDEvt.GetDevice()->SetTextColor( aTextColor );
+ long nTextHeight = rUDEvt.GetDevice()->GetTextHeight();
+ Point aPos( nX, aTopLeft.Y() + (nH-nTextHeight)/2 );
+ if ( bSymbolFont )
+ rUDEvt.GetDevice()->DrawText( aPos, XubString( RTL_CONSTASCII_USTRINGPARAM( SYMBOLFONTTEXT ) ) );
+ else
+ rUDEvt.GetDevice()->DrawText( aPos, rInfo.GetName() );
+ rUDEvt.GetDevice()->SetFont( aOldFont );
+ DrawEntry( rUDEvt, FALSE, FALSE); // Separator
+ }
+ else
+ {
+ DrawEntry( rUDEvt, TRUE, TRUE );
+ }
+}
+
+// ===================================================================
+// FontStyleBox
+// ===================================================================
+
+FontStyleBox::FontStyleBox( Window* pParent, WinBits nWinStyle ) :
+ ComboBox( pParent, nWinStyle )
+{
+}
+
+// -------------------------------------------------------------------
+
+FontStyleBox::FontStyleBox( Window* pParent, const ResId& rResId ) :
+ ComboBox( pParent, rResId )
+{
+ aLastStyle = GetText();
+}
+
+// -------------------------------------------------------------------
+
+FontStyleBox::~FontStyleBox()
+{
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::Select()
+{
+ // Damit Text nach einem Fill erhalten bleibt
+ aLastStyle = GetText();
+ ComboBox::Select();
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::LoseFocus()
+{
+ // Damit Text nach einem Fill erhalten bleibt
+ aLastStyle = GetText();
+ ComboBox::LoseFocus();
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::Modify()
+{
+ International aIntn = Application::GetAppInternational();
+ XubString aStr = GetText();
+ USHORT nEntryCount = GetEntryCount();
+
+ if ( GetEntryPos( aStr ) == COMBOBOX_ENTRY_NOTFOUND )
+ {
+ aIntn.ToUpper( aStr );
+ for ( USHORT i = 0; i < nEntryCount; i++ )
+ {
+ XubString aEntryText = GetEntry( i );
+ aIntn.ToUpper( aEntryText );
+
+ if ( aStr == aEntryText )
+ {
+ SetText( GetEntry( i ) );
+ break;
+ }
+ }
+ }
+
+ ComboBox::Modify();
+}
+
+// -------------------------------------------------------------------
+
+void FontStyleBox::Fill( const XubString& rName, const FontList* pList )
+{
+ // Achtung: In dieser Methode muss ComboBox::SetText() aufgerufen werden,
+ // da sonst aLastStyle ueberschrieben wird
+ // Vorherige Position merken und Box loeschen
+ XubString aOldText = GetText();
+ USHORT nPos = GetEntryPos( aOldText );
+ Clear();
+
+ // Existiert ein Font mit diesem Namen
+ sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
+ if ( hFontInfo )
+ {
+ BOOL bFound = FALSE;
+ BOOL bNormal = FALSE;
+ BOOL bItalic = FALSE;
+ BOOL bBold = FALSE;
+ BOOL bBoldItalic = FALSE;
+ FontInfo aInfo;
+ while ( hFontInfo )
+ {
+ aInfo = pList->GetFontInfo( hFontInfo );
+
+ XubString aStyleText = pList->GetStyleName( aInfo );
+ FontWeight eWeight = aInfo.GetWeight();
+ FontItalic eItalic = aInfo.GetItalic();
+ if ( eWeight <= WEIGHT_NORMAL )
+ {
+ bNormal = TRUE;
+ if ( eItalic != ITALIC_NONE )
+ bItalic = TRUE;
+ }
+ else
+ {
+ if ( eItalic != ITALIC_NONE )
+ bBoldItalic = TRUE;
+ else
+ bBold = TRUE;
+ }
+ if ( aStyleText == pList->GetItalicStr() )
+ bItalic = TRUE;
+ else if ( aStyleText == pList->GetBoldStr() )
+ bBold = TRUE;
+ else if ( aStyleText == pList->GetBoldItalicStr() )
+ bBoldItalic = TRUE;
+ if ( !bFound && (aStyleText == aLastStyle) )
+ bFound = TRUE;
+
+ // Falls doch mal doppelte Strings kommen, dann
+ // nach Moeglichkeit abfangen
+ if ( GetEntryPos( aStyleText ) == LISTBOX_ENTRY_NOTFOUND )
+ InsertEntry( aStyleText );
+
+ hFontInfo = pList->GetNextFontInfo( hFontInfo );
+ }
+
+ // Bestimmte Styles als Nachbildung
+ if ( bNormal )
+ {
+ if ( !bItalic )
+ {
+ if ( !bFound && (aLastStyle == pList->GetItalicStr()) )
+ bFound = TRUE;
+ InsertEntry( pList->GetItalicStr() );
+ }
+ if ( !bBold )
+ {
+ if ( !bFound && (aLastStyle == pList->GetBoldStr()) )
+ bFound = TRUE;
+ InsertEntry( pList->GetBoldStr() );
+ }
+ }
+ if ( !bBoldItalic )
+ {
+ if ( bNormal || bItalic || bBold )
+ {
+ if ( !bFound && (aLastStyle == pList->GetBoldItalicStr()) )
+ bFound = TRUE;
+ InsertEntry( pList->GetBoldItalicStr() );
+ }
+ }
+ if ( aOldText.Len() )
+ {
+ if ( bFound )
+ ComboBox::SetText( aLastStyle );
+ else
+ {
+ if ( nPos >= GetEntryCount() )
+ ComboBox::SetText( GetEntry( 0 ) );
+ else
+ ComboBox::SetText( GetEntry( nPos ) );
+ }
+ }
+ }
+ else
+ {
+ // Wenn Font nicht, dann Standard-Styles einfuegen
+ InsertEntry( pList->GetNormalStr() );
+ InsertEntry( pList->GetItalicStr() );
+ InsertEntry( pList->GetBoldStr() );
+ InsertEntry( pList->GetBoldItalicStr() );
+ if ( aOldText.Len() )
+ {
+ if ( nPos > GetEntryCount() )
+ ComboBox::SetText( GetEntry( 0 ) );
+ else
+ ComboBox::SetText( GetEntry( nPos ) );
+ }
+ }
+}
+
+// ===================================================================
+// FontSizeBox
+// ===================================================================
+
+FontSizeBox::FontSizeBox( Window* pParent, WinBits nWinSize ) :
+ MetricBox( pParent, nWinSize )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+FontSizeBox::FontSizeBox( Window* pParent, const ResId& rResId ) :
+ MetricBox( pParent, rResId )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+FontSizeBox::~FontSizeBox()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::ImplInit()
+{
+ EnableAutocomplete( FALSE );
+
+ bRelativeMode = FALSE;
+ bPtRelative = FALSE;
+ bRelative = FALSE;
+ bStdSize = FALSE;
+ pFontList = NULL;
+
+ International aIntn = GetInternational();
+ aIntn.SetNumTrailingZeros( FALSE );
+ SetInternational( aIntn );
+
+ SetDecimalDigits( 1 );
+ SetMin( 20 );
+ SetMax( 9999 );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::Modify()
+{
+ MetricBox::Modify();
+
+ if ( bRelativeMode )
+ {
+ XubString aStr = GetText();
+ aStr.EraseLeadingChars();
+
+ BOOL bNewMode = bRelative;
+ BOOL bOldPtRelMode = bPtRelative;
+
+ if ( bRelative )
+ {
+ bPtRelative = FALSE;
+ const xub_Unicode* pStr = aStr.GetBuffer();
+ while ( *pStr )
+ {
+ if ( ((*pStr < '0') || (*pStr > '9')) && (*pStr != '%') )
+ {
+ if ( ('-' == *pStr || '+' == *pStr) && !bPtRelative )
+ bPtRelative = TRUE;
+ else if ( bPtRelative && 'p' == *pStr && 't' == *++pStr )
+ ;
+ else
+ {
+ bNewMode = FALSE;
+ break;
+ }
+ }
+ pStr++;
+ }
+ }
+ else
+ {
+ if ( STRING_NOTFOUND != aStr.Search( '%' ) )
+ {
+ bNewMode = TRUE;
+ bPtRelative = FALSE;
+ }
+
+ if ( '-' == aStr.GetChar( 0 ) || '+' == aStr.GetChar( 0 ) )
+ {
+ bNewMode = TRUE;
+ bPtRelative = TRUE;
+ }
+ }
+
+ if ( bNewMode != bRelative || bPtRelative != bOldPtRelMode )
+ SetRelative( bNewMode );
+
+ MetricBox::Modify();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::Fill( const FontInfo& rInfo, const FontList* pList )
+{
+ // Merken fuer Relative-Mode
+ aFontInfo = rInfo;
+ pFontList = pList;
+
+ // Im Relative-Mode, muessen keine Fontgroessen gesetzt werden
+ if ( bRelative )
+ return;
+
+ // Fontgroessen abfragen
+ const long* pAry = pList->GetSizeAry( rInfo );
+
+ // Wenn es das Array mit den Standardgroessen ist, muessen wir im
+ // Normalfall die ListBox nicht neu fuellen
+ if ( (pAry == pList->GetStdSizeAry()) && GetEntryCount() )
+ {
+ if ( bStdSize )
+ return;
+ bStdSize = TRUE;
+ }
+ else
+ bStdSize = FALSE;
+
+ Selection aSelection = GetSelection();
+ XubString aStr = GetText();
+
+ Clear();
+
+ while ( *pAry )
+ {
+ InsertValue( *pAry );
+ pAry++;
+ }
+
+ SetText( aStr );
+ SetSelection( aSelection );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::EnableRelativeMode( USHORT nMin, USHORT nMax, USHORT nStep )
+{
+ bRelativeMode = TRUE;
+ nRelMin = nMin;
+ nRelMax = nMax;
+ nRelStep = nStep;
+ SetUnit( FUNIT_POINT );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::EnablePtRelativeMode( short nMin, short nMax, short nStep )
+{
+ bRelativeMode = TRUE;
+ nPtRelMin = nMin;
+ nPtRelMax = nMax;
+ nPtRelStep = nStep;
+ SetUnit( FUNIT_POINT );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeBox::SetRelative( BOOL bNewRelative )
+{
+ if ( bRelativeMode )
+ {
+ Selection aSelection = GetSelection();
+ XubString aStr = GetText();
+ aStr.EraseLeadingChars();
+
+ if ( bNewRelative )
+ {
+ bRelative = TRUE;
+ bStdSize = FALSE;
+
+ if ( bPtRelative )
+ {
+ SetDecimalDigits( 1 );
+ SetMin( nPtRelMin );
+ SetMax( nPtRelMax );
+ SetUnit( FUNIT_POINT );
+
+ Clear();
+ short i = nPtRelMin, n = 0;
+ // JP 30.06.98: mehr als 100 Werte machen keinen Sinn
+ while ( i <= nPtRelMax && n++ < 100 )
+ {
+ InsertValue( i );
+ i += nPtRelStep;
+ }
+ }
+ else
+ {
+ SetDecimalDigits( 0 );
+ SetMin( nRelMin );
+ SetMax( nRelMax );
+ SetCustomUnitText( '%' );
+ SetUnit( FUNIT_CUSTOM );
+
+ Clear();
+ USHORT i = nRelMin;
+ while ( i <= nRelMax )
+ {
+ InsertValue( i );
+ i += nRelStep;
+ }
+ }
+ }
+ else
+ {
+ bRelative = bPtRelative = FALSE;
+ SetDecimalDigits( 1 );
+ SetMin( 20 );
+ SetMax( 9999 );
+ SetUnit( FUNIT_POINT );
+ if ( pFontList )
+ Fill( aFontInfo, pFontList );
+ }
+
+ SetText( aStr );
+ SetSelection( aSelection );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString FontSizeBox::CreateFieldText( long nValue ) const
+{
+ XubString sRet( MetricBox::CreateFieldText( nValue ) );
+ if ( bRelativeMode && bPtRelative && (0 <= nValue) && sRet.Len() )
+ sRet.Insert( '+', 0 );
+ return sRet;
+}
diff --git a/svtools/source/control/ctrlbox.src b/svtools/source/control/ctrlbox.src
new file mode 100644
index 000000000000..db8eb8810ec7
--- /dev/null
+++ b/svtools/source/control/ctrlbox.src
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * $RCSfile: ctrlbox.src,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 "svtools.hrc"
+
+#ifndef IMAGE_STDBTN_COLOR
+#define IMAGE_STDBTN_COLOR Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; }
+#endif
+
+
+IMAGE RID_IMG_SCALABLEFONT
+{
+ ImageBitmap = Bitmap { File = "scalfont.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_PRINTERFONT
+{
+ ImageBitmap = Bitmap { File = "prnfont.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
+IMAGE RID_IMG_BITMAPFONT
+{
+ ImageBitmap = Bitmap { File = "bmpfont.bmp" ; };
+ MaskColor = IMAGE_STDBTN_COLOR ;
+};
+
diff --git a/svtools/source/control/ctrldll.cxx b/svtools/source/control/ctrldll.cxx
new file mode 100644
index 000000000000..19c26d4e80cf
--- /dev/null
+++ b/svtools/source/control/ctrldll.cxx
@@ -0,0 +1,112 @@
+/*************************************************************************
+ *
+ * $RCSfile: ctrldll.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef WIN
+
+#ifndef _SVWIN_H
+#include <svwin.h>
+#endif
+
+#ifndef _SYSDEP_HXX
+#include <sysdep.hxx>
+#endif
+
+// Statische DLL-Verwaltungs-Variablen
+static HINSTANCE hDLLInst = 0; // HANDLE der DLL
+
+/***************************************************************************
+|*
+|* LibMain()
+|*
+|* Beschreibung Initialisierungsfunktion der DLL
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK LibMain( HINSTANCE hDLL, WORD, WORD nHeap, LPSTR )
+{
+#ifndef WNT
+ if ( nHeap )
+ UnlockData( 0 );
+#endif
+
+ hDLLInst = hDLL;
+
+ return TRUE;
+}
+
+/***************************************************************************
+|*
+|* WEP()
+|*
+|* Beschreibung DLL-Deinitialisierung
+|* Ersterstellung TH 05.05.93
+|* Letzte Aenderung TH 05.05.93
+|*
+***************************************************************************/
+
+extern "C" int CALLBACK WEP( int )
+{
+ return 1;
+}
+
+#endif
diff --git a/svtools/source/control/ctrltool.cxx b/svtools/source/control/ctrltool.cxx
new file mode 100644
index 000000000000..ed38c9cc7a93
--- /dev/null
+++ b/svtools/source/control/ctrltool.cxx
@@ -0,0 +1,865 @@
+/*************************************************************************
+ *
+ * $RCSfile: ctrltool.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define CTRLTOOL_CXX
+
+#include <string.h>
+
+#ifndef TOOLS_INTN_HXX
+#include <tools/intn.hxx>
+#endif
+#ifndef TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _VCL_WINDOW_HXX
+#include <vcl/window.hxx>
+#endif
+#ifndef _VCL_SYSTEM_HXX
+#include <vcl/system.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _SV_WRKWIN_HXX
+#include <vcl/wrkwin.hxx>
+#endif
+
+#define private public
+
+#include <svtools.hrc>
+#include <svtdata.hxx>
+#include <ctrltool.hxx>
+
+// =======================================================================
+
+// Standard Fontgroessen fuer scalierbare Fonts
+static long aStdSizeAry[] =
+{
+ 60,
+ 70,
+ 80,
+ 90,
+ 100,
+ 110,
+ 120,
+ 140,
+ 160,
+ 180,
+ 200,
+ 220,
+ 240,
+ 260,
+ 280,
+ 320,
+ 360,
+ 400,
+ 440,
+ 480,
+ 540,
+ 600,
+ 660,
+ 720,
+ 800,
+ 880,
+ 960,
+ 0
+};
+
+// =======================================================================
+
+// -----------------------------
+// - class ImplFontListFonInfo -
+// -----------------------------
+
+class ImplFontListFontInfo : public FontInfo
+{
+ friend class FontList;
+
+private:
+ OutputDevice* mpDevice;
+ ImplFontListFontInfo* mpNext;
+
+public:
+ ImplFontListFontInfo( const FontInfo& rInfo,
+ OutputDevice* pDev ) :
+ FontInfo( rInfo )
+ {
+ mpDevice = pDev;
+ }
+
+ OutputDevice* GetDevice() const { return mpDevice; }
+};
+
+// ------------------------------
+// - class ImplFontListNameInfo -
+// ------------------------------
+
+class ImplFontListNameInfo
+{
+ friend class FontList;
+
+private:
+ XubString maSearchName;
+ ImplFontListFontInfo* mpFirst;
+ USHORT mnType;
+
+ ImplFontListNameInfo( const XubString& rSearchName ) :
+ maSearchName( rSearchName )
+ {}
+
+ const XubString& GetSearchName() const { return maSearchName; }
+};
+
+// =======================================================================
+
+static StringCompare ImplCompareFontInfo( ImplFontListFontInfo* pInfo1,
+ ImplFontListFontInfo* pInfo2 )
+{
+ if ( pInfo1->GetWeight() < pInfo2->GetWeight() )
+ return COMPARE_LESS;
+ else if ( pInfo1->GetWeight() > pInfo2->GetWeight() )
+ return COMPARE_GREATER;
+
+ if ( pInfo1->GetItalic() < pInfo2->GetItalic() )
+ return COMPARE_LESS;
+ else if ( pInfo1->GetItalic() > pInfo2->GetItalic() )
+ return COMPARE_GREATER;
+
+ return pInfo1->GetStyleName().CompareTo( pInfo2->GetStyleName() );
+}
+
+// =======================================================================
+
+static void ImplMakeSearchString( XubString& rStr )
+{
+ rStr.ToLowerAscii();
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplMakeSearchStringFromName( XubString& rStr )
+{
+ rStr = rStr.GetToken( 0, ';' );
+ ImplMakeSearchString( rStr );
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontListNameInfo* FontList::ImplFind( const XubString& rSearchName, ULONG* pIndex ) const
+{
+ // Wenn kein Eintrag in der Liste oder der Eintrag groesser ist als
+ // der Letzte, dann hinten dranhaengen. Wir vergleichen erst mit dem
+ // letzten Eintrag, da die Liste von VCL auch sortiert zurueckkommt
+ // und somit die Wahrscheinlichkeit das hinten angehaengt werden muss
+ // sehr gross ist.
+ StringCompare eComp;
+ ULONG nCount = Count();
+ if ( !nCount )
+ {
+ if ( pIndex )
+ *pIndex = LIST_APPEND;
+ return NULL;
+ }
+ else
+ {
+ ImplFontListNameInfo* pCmpData = (ImplFontListNameInfo*)List::GetObject( nCount-1 );
+ eComp = rSearchName.CompareTo( pCmpData->maSearchName );
+ if ( eComp == COMPARE_GREATER )
+ {
+ if ( pIndex )
+ *pIndex = LIST_APPEND;
+ return NULL;
+ }
+ else if ( eComp == COMPARE_EQUAL )
+ return pCmpData;
+ }
+
+ // Fonts in der Liste suchen
+ ImplFontListNameInfo* pCompareData;
+ ImplFontListNameInfo* pFoundData = NULL;
+ ULONG nLow = 0;
+ ULONG nHigh = nCount-1;
+ ULONG nMid;
+
+ do
+ {
+ nMid = (nLow + nHigh) / 2;
+ pCompareData = (ImplFontListNameInfo*)List::GetObject( nMid );
+ eComp = rSearchName.CompareTo( pCompareData->maSearchName );
+ if ( eComp == COMPARE_LESS )
+ {
+ if ( !nMid )
+ break;
+ nHigh = nMid-1;
+ }
+ else
+ {
+ if ( eComp == COMPARE_GREATER )
+ nLow = nMid + 1;
+ else
+ {
+ pFoundData = pCompareData;
+ break;
+ }
+ }
+ }
+ while ( nLow <= nHigh );
+
+ if ( pIndex )
+ {
+ eComp = rSearchName.CompareTo( pCompareData->maSearchName );
+ if ( eComp == COMPARE_GREATER )
+ *pIndex = (nMid+1);
+ else
+ *pIndex = nMid;
+ }
+
+ return pFoundData;
+}
+
+// -----------------------------------------------------------------------
+
+ImplFontListNameInfo* FontList::ImplFindByName( const XubString& rStr ) const
+{
+ XubString aSearchName = rStr;
+ ImplMakeSearchStringFromName( aSearchName );
+ return ImplFind( aSearchName, NULL );
+}
+
+// -----------------------------------------------------------------------
+
+void FontList::ImplInsertFonts( OutputDevice* pDevice, BOOL bAll,
+ BOOL bInsertData )
+{
+ rtl_TextEncoding eSystemEncoding = gsl_getSystemTextEncoding();
+
+ USHORT nType;
+ if ( pDevice->GetOutDevType() != OUTDEV_PRINTER )
+ nType = FONTLIST_FONTNAMETYPE_SCREEN;
+ else
+ nType = FONTLIST_FONTNAMETYPE_PRINTER;
+
+ // Alle Fonts vom Device abfragen
+ USHORT n = pDevice->GetDevFontCount();
+ USHORT i;
+ for( i = 0; i < n; i++ )
+ {
+ FontInfo aFontInfo = pDevice->GetDevFont( i );
+
+ // Wenn keine Raster-Schriften angezeigt werden sollen,
+ // dann diese ignorieren
+ if ( !bAll && (aFontInfo.GetType() == TYPE_RASTER) )
+ continue;
+
+ XubString aSearchName = aFontInfo.GetName();
+ ImplFontListNameInfo* pData;
+ ULONG nIndex;
+ ImplMakeSearchString( aSearchName );
+ pData = ImplFind( aSearchName, &nIndex );
+
+ if ( !pData )
+ {
+ if ( bInsertData )
+ {
+ ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
+ pData = new ImplFontListNameInfo( aSearchName );
+ pData->mpFirst = pNewInfo;
+ pNewInfo->mpNext = NULL;
+ pData->mnType = 0;
+ Insert( (void*)pData, nIndex );
+ }
+ }
+ else
+ {
+ if ( bInsertData )
+ {
+ BOOL bInsert = TRUE;
+ ImplFontListFontInfo* pPrev = NULL;
+ ImplFontListFontInfo* pTemp = pData->mpFirst;
+ ImplFontListFontInfo* pNewInfo = new ImplFontListFontInfo( aFontInfo, pDevice );
+ while ( pTemp )
+ {
+ StringCompare eComp = ImplCompareFontInfo( pNewInfo, pTemp );
+ if ( (eComp == COMPARE_LESS) || (eComp == COMPARE_EQUAL) )
+ {
+ if ( eComp == COMPARE_EQUAL )
+ {
+ // Overwrite charset, because charset should match
+ // with the system charset
+ if ( (pTemp->GetCharSet() != eSystemEncoding) &&
+ (pNewInfo->GetCharSet() == eSystemEncoding) )
+ {
+ ImplFontListFontInfo* pTemp2 = pTemp->mpNext;
+ *((FontInfo*)pTemp) = *((FontInfo*)pNewInfo);
+ pTemp->mpNext = pTemp2;
+ }
+ delete pNewInfo;
+ bInsert = FALSE;
+ }
+
+ break;
+ }
+
+ pPrev = pTemp;
+ pTemp = pTemp->mpNext;
+ }
+
+ if ( bInsert )
+ {
+ pNewInfo->mpNext = pTemp;
+ if ( pPrev )
+ pPrev->mpNext = pNewInfo;
+ else
+ pData->mpFirst = pNewInfo;
+ }
+ }
+ }
+
+ if ( pData )
+ {
+ pData->mnType |= nType;
+ if ( aFontInfo.GetType() != TYPE_RASTER )
+ pData->mnType |= FONTLIST_FONTNAMETYPE_SCALABLE;
+ }
+ }
+}
+
+// =======================================================================
+
+FontList::FontList( OutputDevice* pDevice, OutputDevice* pDevice2, BOOL bAll ) :
+ List( 4096, pDevice->GetDevFontCount(), 32 )
+{
+ // Variablen initialisieren
+ mpDev = pDevice;
+ mpDev2 = pDevice2;
+ mpSizeAry = NULL;
+
+ // Stylenamen festlegen
+ maLight = XubString( SvtResId( STR_SVT_STYLE_LIGHT ) );
+ maLightItalic = XubString( SvtResId( STR_SVT_STYLE_LIGHT_ITALIC ) );
+ maNormal = XubString( SvtResId( STR_SVT_STYLE_NORMAL ) );
+ maNormalItalic = XubString( SvtResId( STR_SVT_STYLE_NORMAL_ITALIC ) );
+ maBold = XubString( SvtResId( STR_SVT_STYLE_BOLD ) );
+ maBoldItalic = XubString( SvtResId( STR_SVT_STYLE_BOLD_ITALIC ) );
+ maBlack = XubString( SvtResId( STR_SVT_STYLE_BLACK ) );
+ maBlackItalic = XubString( SvtResId( STR_SVT_STYLE_BLACK_ITALIC ) );
+
+ ImplInsertFonts( pDevice, bAll, TRUE );
+
+ // Gegebenenfalls muessen wir mit den Bildschirmfonts vergleichen,
+ // damit dort die eigentlich doppelten auf Equal mappen koennen
+ BOOL bCompareWindow = FALSE;
+ if ( !pDevice2 && (pDevice->GetOutDevType() == OUTDEV_PRINTER) )
+ {
+ bCompareWindow = TRUE;
+ pDevice2 = Application::GetDefaultDevice();
+ }
+
+ if ( pDevice2 &&
+ (pDevice2->GetOutDevType() != pDevice->GetOutDevType()) )
+ ImplInsertFonts( pDevice2, bAll, !bCompareWindow );
+}
+
+// -----------------------------------------------------------------------
+
+FontList::~FontList()
+{
+ // Gegebenenfalls SizeArray loeschen
+ if ( mpSizeAry )
+ delete mpSizeAry;
+
+ // FontInfos loeschen
+ ImplFontListNameInfo* pData = (ImplFontListNameInfo*)First();
+ while ( pData )
+ {
+ ImplFontListFontInfo* pTemp;
+ ImplFontListFontInfo* pInfo = pData->mpFirst;
+ while ( pInfo )
+ {
+ pTemp = pInfo->mpNext;
+ delete pInfo;
+ pInfo = pTemp;
+ }
+ ImplFontListNameInfo* pNext = (ImplFontListNameInfo*)Next();
+ delete pData;
+ pData = pNext;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString FontList::GetStyleName( const FontInfo& rInfo ) const
+{
+ XubString aStyleName = rInfo.GetStyleName();
+
+ // Nur wenn kein StyleName gesetzt ist, geben wir einen syntetischen
+ // Namen zurueck
+ if ( !aStyleName.Len() )
+ {
+ FontWeight eWeight = rInfo.GetWeight();
+ FontItalic eItalic = rInfo.GetItalic();
+ if ( eWeight > WEIGHT_BOLD )
+ {
+ if ( eItalic > ITALIC_NONE )
+ aStyleName = maBlackItalic;
+ else
+ aStyleName = maBlack;
+ }
+ else if ( eWeight > WEIGHT_MEDIUM )
+ {
+ if ( eItalic > ITALIC_NONE )
+ aStyleName = maBoldItalic;
+ else
+ aStyleName = maBold;
+ }
+ else if ( eWeight > WEIGHT_LIGHT )
+ {
+ if ( eItalic > ITALIC_NONE )
+ aStyleName = maNormalItalic;
+ else
+ aStyleName = maNormal;
+ }
+ else if ( eWeight != WEIGHT_DONTKNOW )
+ {
+ if ( eItalic > ITALIC_NONE )
+ aStyleName = maLightItalic;
+ else
+ aStyleName = maLight;
+ }
+ else
+ {
+ if ( eItalic > ITALIC_NONE )
+ aStyleName = maNormalItalic;
+ else
+ aStyleName = maNormal;
+ }
+ }
+
+ return aStyleName;
+}
+
+// -----------------------------------------------------------------------
+
+XubString FontList::GetFontMapText( const FontInfo& rInfo ) const
+{
+ if ( !rInfo.GetName().Len() )
+ {
+ XubString aEmptryStr;
+ return aEmptryStr;
+ }
+
+ ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
+ if ( !pData )
+ {
+ if ( !maMapNotAvailable.Len() )
+ ((FontList*)this)->maMapNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_NOTAVAILABLE ) );
+ return maMapNotAvailable;
+ }
+
+ USHORT nType = pData->mnType;
+ if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_PRINTER )
+ {
+ if ( !maMapPrinterOnly.Len() )
+ ((FontList*)this)->maMapPrinterOnly = XubString( SvtResId( STR_SVT_FONTMAP_PRINTERONLY ) );
+ return maMapPrinterOnly;
+ }
+ else if ( (nType & (FONTLIST_FONTNAMETYPE_PRINTER | FONTLIST_FONTNAMETYPE_SCREEN)) == FONTLIST_FONTNAMETYPE_SCREEN )
+ {
+ if ( !maMapScreenOnly.Len() )
+ ((FontList*)this)->maMapScreenOnly = XubString( SvtResId( STR_SVT_FONTMAP_SCREENONLY ) );
+ return maMapScreenOnly;
+ }
+ else
+ {
+ BOOL bNotSynthetic = FALSE;
+ BOOL bNoneAvailable = FALSE;
+ const XubString& rStyleName = rInfo.GetStyleName();
+ FontWeight eMinWeight = pData->mpFirst->GetWeight();
+ FontWeight eWeight = rInfo.GetWeight();
+ FontItalic eItalic = rInfo.GetItalic();
+ ImplFontListFontInfo* pFontInfo = pData->mpFirst;
+ if ( rStyleName.Len() )
+ {
+ while ( pFontInfo )
+ {
+ if ( (eWeight == pFontInfo->GetWeight()) &&
+ (eItalic == pFontInfo->GetItalic()) )
+ {
+ bNotSynthetic = TRUE;
+ break;
+ }
+
+ pFontInfo = pFontInfo->mpNext;
+ }
+
+ if ( !bNotSynthetic )
+ {
+ bNoneAvailable = TRUE;
+
+ // Testen, ob es ein syntetischer Style ist
+ if ( eMinWeight <= WEIGHT_NORMAL )
+ {
+ if ( (rStyleName == maNormal) || (rStyleName == maLight) ||
+ (rStyleName == maNormalItalic) || (rStyleName == maLightItalic) )
+ bNoneAvailable = FALSE;
+ }
+
+ if ( (rStyleName == maBold) || (rStyleName == maBlack) ||
+ (rStyleName == maBoldItalic) || (rStyleName == maBlackItalic) )
+ bNoneAvailable = FALSE;
+ }
+ }
+ else
+ bNotSynthetic = TRUE;
+
+ if ( bNoneAvailable )
+ {
+ XubString aEmptryStr;
+ return aEmptryStr;
+ }
+ else if ( !bNotSynthetic )
+ {
+ if ( !maMapStyleNotAvailable.Len() )
+ ((FontList*)this)->maMapStyleNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_STYLENOTAVAILABLE ) );
+ return maMapStyleNotAvailable;
+ }
+ else
+ {
+ /* Size not available not implemented yet
+ if ( !(nType & FONTLIST_FONTNAMETYPE_SCALABLE) )
+ {
+ ...
+ {
+ if ( !maMapSizeNotAvailable.Len() )
+ ((FontList*)this)->maMapSizeNotAvailable = XubString( SvtResId( STR_SVT_FONTMAP_SIZENOTAVAILABLE ) );
+ return maMapSizeNotAvailable;
+ }
+ }
+ */
+
+
+ if ( !maMapBoth.Len() )
+ ((FontList*)this)->maMapBoth = XubString( SvtResId( STR_SVT_FONTMAP_BOTH ) );
+ return maMapBoth;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+USHORT FontList::GetFontNameType( const XubString& rFontName ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rFontName );
+ if ( pData )
+ return pData->mnType;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo FontList::Get( const XubString& rName, const XubString& rStyleName ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rName );
+ ImplFontListFontInfo* pFontInfo = NULL;
+ ImplFontListFontInfo* pFontNameInfo = NULL;
+ if ( pData )
+ {
+ ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
+ pFontNameInfo = pSearchInfo;
+ while ( pSearchInfo )
+ {
+ if ( rStyleName == GetStyleName( *pSearchInfo ) )
+ {
+ pFontInfo = pSearchInfo;
+ break;
+ }
+
+ pSearchInfo = pSearchInfo->mpNext;
+ }
+ }
+
+ // Konnten die Daten nicht gefunden werden, dann muessen bestimmte
+ // Attribute nachgebildet werden
+ if ( !pFontInfo )
+ {
+ FontInfo aInfo;
+
+ // Falls der Fontname stimmt, uebernehmen wir soviel wie moeglich
+ if ( pFontNameInfo )
+ aInfo = *pFontNameInfo;
+ else
+ aInfo.SetName( rName );
+ aInfo.SetStyleName( rStyleName );
+
+ if ( rStyleName == maNormal )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_NORMAL );
+ }
+ else if ( rStyleName == maNormalItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_NORMAL );
+ }
+ else if ( rStyleName == maBold )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_BOLD );
+ }
+ else if ( rStyleName == maBoldItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_BOLD );
+ }
+ else if ( rStyleName == maLight )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_LIGHT );
+ }
+ else if ( rStyleName == maLightItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_LIGHT );
+ }
+ else if ( rStyleName == maBlack )
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_BLACK );
+ }
+ else if ( rStyleName == maBlackItalic )
+ {
+ aInfo.SetItalic( ITALIC_NORMAL );
+ aInfo.SetWeight( WEIGHT_BLACK );
+ }
+ else
+ {
+ aInfo.SetItalic( ITALIC_NONE );
+ aInfo.SetWeight( WEIGHT_DONTKNOW );
+ }
+
+ return aInfo;
+ }
+ else
+ return *pFontInfo;
+}
+
+// -----------------------------------------------------------------------
+
+FontInfo FontList::Get( const XubString& rName,
+ FontWeight eWeight, FontItalic eItalic ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rName );
+ ImplFontListFontInfo* pFontInfo = NULL;
+ ImplFontListFontInfo* pFontNameInfo = NULL;
+ if ( pData )
+ {
+ ImplFontListFontInfo* pSearchInfo = pData->mpFirst;
+ pFontNameInfo = pSearchInfo;
+ while ( pSearchInfo )
+ {
+ if ( (eWeight == pSearchInfo->GetWeight()) &&
+ (eItalic == pSearchInfo->GetItalic()) )
+ {
+ pFontInfo = pSearchInfo;
+ break;
+ }
+
+ pSearchInfo = pSearchInfo->mpNext;
+ }
+ }
+
+ // Konnten die Daten nicht gefunden werden, dann muessen bestimmte
+ // Attribute nachgebildet werden
+ if ( !pFontInfo )
+ {
+ FontInfo aInfo;
+
+ // Falls der Fontname stimmt, uebernehmen wir soviel wie moeglich
+ if ( pFontNameInfo )
+ {
+ aInfo = *pFontNameInfo;
+ aInfo.SetStyleName( XubString() );
+ }
+ else
+ aInfo.SetName( rName );
+
+ aInfo.SetWeight( eWeight );
+ aInfo.SetItalic( eItalic );
+ return aInfo;
+ }
+ else
+ return *pFontInfo;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL FontList::IsAvailable( const XubString& rName ) const
+{
+ return (ImplFindByName( rName ) != 0);
+}
+
+// -----------------------------------------------------------------------
+
+const FontInfo& FontList::GetFontName( USHORT nFont ) const
+{
+ DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontName(): nFont >= Count" );
+
+ ImplFontListNameInfo* pData = (ImplFontListNameInfo*)List::GetObject( nFont );
+ return *(pData->mpFirst);
+}
+
+// -----------------------------------------------------------------------
+
+USHORT FontList::GetFontNameType( USHORT nFont ) const
+{
+ DBG_ASSERT( nFont < GetFontNameCount(), "FontList::GetFontNameType(): nFont >= Count" );
+
+ ImplFontListNameInfo* pData = (ImplFontListNameInfo*)List::GetObject( nFont );
+ return pData->mnType;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Handle FontList::GetFirstFontInfo( const XubString& rName ) const
+{
+ ImplFontListNameInfo* pData = ImplFindByName( rName );
+ if ( !pData )
+ return (sal_Handle)NULL;
+ else
+ return (sal_Handle)pData->mpFirst;
+}
+
+// -----------------------------------------------------------------------
+
+sal_Handle FontList::GetNextFontInfo( sal_Handle hFontInfo ) const
+{
+ ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
+ return (sal_Handle)(pInfo->mpNext);
+}
+
+// -----------------------------------------------------------------------
+
+const FontInfo& FontList::GetFontInfo( sal_Handle hFontInfo ) const
+{
+ ImplFontListFontInfo* pInfo = (ImplFontListFontInfo*)(void*)hFontInfo;
+ return *pInfo;
+}
+
+// -----------------------------------------------------------------------
+
+const long* FontList::GetSizeAry( const FontInfo& rInfo ) const
+{
+ // Size-Array vorher loeschen
+ if ( mpSizeAry )
+ {
+ delete ((FontList*)this)->mpSizeAry;
+ ((FontList*)this)->mpSizeAry = NULL;
+ }
+
+ // Falls kein Name, dann Standardgroessen
+ if ( !rInfo.GetName().Len() )
+ return aStdSizeAry;
+
+ // Zuerst nach dem Fontnamen suchen um das Device dann von dem
+ // entsprechenden Font zu nehmen
+ OutputDevice* pDevice = mpDev;
+ ImplFontListNameInfo* pData = ImplFindByName( rInfo.GetName() );
+ if ( pData )
+ pDevice = pData->mpFirst->GetDevice();
+
+ USHORT nDevSizeCount = pDevice->GetDevFontSizeCount( rInfo );
+ if ( !nDevSizeCount ||
+ (pDevice->GetDevFontSize( rInfo, 0 ).Height() == 0) )
+ return aStdSizeAry;
+
+ MapMode aOldMapMode = pDevice->GetMapMode();
+ MapMode aMap( MAP_10TH_INCH, Point(), Fraction( 1, 72 ), Fraction( 1, 72 ) );
+ pDevice->SetMapMode( aMap );
+
+ USHORT i;
+ USHORT nRealCount = 0;
+ long nOldHeight = 0;
+ ((FontList*)this)->mpSizeAry = new long[nDevSizeCount+1];
+ for ( i = 0; i < nDevSizeCount; i++ )
+ {
+ Size aSize = pDevice->GetDevFontSize( rInfo, i );
+ if ( aSize.Height() != nOldHeight )
+ {
+ nOldHeight = aSize.Height();
+ ((FontList*)this)->mpSizeAry[nRealCount] = nOldHeight;
+ nRealCount++;
+ }
+ }
+ ((FontList*)this)->mpSizeAry[nRealCount] = 0;
+
+ pDevice->SetMapMode( aOldMapMode );
+ return mpSizeAry;
+}
+
+// -----------------------------------------------------------------------
+
+const long* FontList::GetStdSizeAry()
+{
+ return aStdSizeAry;
+}
+
+
diff --git a/svtools/source/control/ctrltool.src b/svtools/source/control/ctrltool.src
new file mode 100644
index 000000000000..2ae746c57295
--- /dev/null
+++ b/svtools/source/control/ctrltool.src
@@ -0,0 +1,425 @@
+/*************************************************************************
+ *
+ * $RCSfile: ctrltool.src,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 "svtools.hrc"
+
+String STR_SVT_STYLE_LIGHT
+{
+ Text = "Light" ;
+ Text [ ENGLISH ] = "Light" ;
+ Text [ english_us ] = "Light" ;
+ Text [ italian ] = "Light" ;
+ Text [ spanish ] = "Light" ;
+ Text [ french ] = "Estompé" ;
+ Text [ dutch ] = "Light" ;
+ Text [ swedish ] = "Ljus" ;
+ Text [ danish ] = "Light" ;
+ Text [ portuguese_brazilian ] = "Light" ;
+ Text [ portuguese ] = "Claro" ;
+ Text[ russian ] = "Òîíêèé";
+ Text[ polish ] = "Light";
+ Text[ japanese ] = "׎š";
+ Text[ chinese_simplified ] = "ϸ";
+ Text[ chinese_traditional ] = "²Ó";
+ Text[ arabic ] = "ÝÇÊÍ";
+ Text[ greek ] = "Áðáëü";
+ Text[ korean ] = "Light";
+ Text[ turkish ] = "Ýnce";
+ Text[ language_user1 ] = " ";
+};
+
+String STR_SVT_STYLE_LIGHT_ITALIC
+{
+ Text = "Light Kursiv" ;
+ Text [ ENGLISH ] = "Light Italic" ;
+ Text [ english_us ] = "Light Italic" ;
+ Text [ italian ] = "Corsivo Light" ;
+ Text [ spanish ] = "Cursiva light" ;
+ Text [ french ] = "Italique estompé" ;
+ Text [ dutch ] = "Light Cursief" ;
+ Text [ swedish ] = "Ljus kursiv" ;
+ Text [ danish ] = "Light kursiv" ;
+ Text [ portuguese_brazilian ] = "Light Italic" ;
+ Text [ portuguese ] = "Itálico claro" ;
+ Text[ russian ] = "Òîíêèé êóðñèâ";
+ Text[ polish ] = "Kursywa light";
+ Text[ japanese ] = "׎š ŽÎ‘Ì";
+ Text[ chinese_simplified ] = "ϸбÌå";
+ Text[ chinese_traditional ] = "²Ó±×Åé";
+ Text[ arabic ] = "ÝÇÊÍ ãÇÆá";
+ Text[ greek ] = "ÐëÜãéá ÁðáëÜ";
+ Text[ korean ] = "°¡º­¿î ÀÌÅŸ¯Ã¼";
+ Text[ turkish ] = "Ýnce italik";
+ Text[ language_user1 ] = " ";
+};
+
+String STR_SVT_STYLE_NORMAL
+{
+ Text = "Standard" ;
+ Text [ ENGLISH ] = "Regular" ;
+ Text [ english_us ] = "Regular" ;
+ Text [ italian ] = "Standard" ;
+ Text [ spanish ] = "Predeterminado" ;
+ Text [ french ] = "Normal" ;
+ Text [ dutch ] = "Normaal" ;
+ Text [ swedish ] = "Normal" ;
+ Text [ danish ] = "Normal" ;
+ Text [ portuguese_brazilian ] = "Normal" ;
+ Text [ portuguese ] = "Padrão" ;
+ Text[ russian ] = "Ñòàíäàðò";
+ Text[ polish ] = "Standard";
+ Text[ japanese ] = "•W€";
+ Text[ chinese_simplified ] = "±ê×¼";
+ Text[ chinese_traditional ] = "¼Ð·Ç";
+ Text[ arabic ] = "ÞíÇÓí";
+ Text[ greek ] = "ÐñïåðéëïãÞ";
+ Text[ korean ] = "º¸Åë";
+ Text[ turkish ] = "Normal";
+ Text[ language_user1 ] = " ";
+};
+
+String STR_SVT_STYLE_NORMAL_ITALIC
+{
+ Text = "Kursiv" ;
+ Text [ ENGLISH ] = "Italic" ;
+ Text [ english_us ] = "Italic" ;
+ Text [ italian ] = "Corsivo" ;
+ Text [ spanish ] = "Cursiva" ;
+ Text [ french ] = "Italique" ;
+ Text [ dutch ] = "Cursief" ;
+ Text [ swedish ] = "Kursiv" ;
+ Text [ danish ] = "Kursiv" ;
+ Text [ portuguese_brazilian ] = "Italic" ;
+ Text [ portuguese ] = "Itálico" ;
+ Text[ russian ] = "Êóðñèâ";
+ Text[ polish ] = "Kursywa";
+ Text[ japanese ] = "ŽÎ‘Ì";
+ Text[ chinese_simplified ] = "бÌå";
+ Text[ chinese_traditional ] = "±×Åé";
+ Text[ arabic ] = "ãÇÆá";
+ Text[ greek ] = "ÐëÜãéá";
+ Text[ korean ] = "±â¿ïÀÓ²Ã";
+ Text[ turkish ] = "Ýtalik";
+ Text[ language_user1 ] = " ";
+};
+
+String STR_SVT_STYLE_BOLD
+{
+ Text = "Fett" ;
+ Text [ ENGLISH ] = "Bold" ;
+ Text [ english_us ] = "Bold" ;
+ Text [ italian ] = "Grassetto" ;
+ Text [ spanish ] = "Negrita" ;
+ Text [ french ] = "Gras" ;
+ Text [ dutch ] = "Vet" ;
+ Text [ swedish ] = "Fet" ;
+ Text [ danish ] = "Fed" ;
+ Text [ portuguese_brazilian ] = "Bold" ;
+ Text [ portuguese ] = "Negrito" ;
+ Text[ russian ] = "Æèðíûé";
+ Text[ polish ] = "Pogrubienie";
+ Text[ japanese ] = "‘¾Žš";
+ Text[ chinese_simplified ] = "´ÖÌå";
+ Text[ chinese_traditional ] = "²ÊÅé";
+ Text[ arabic ] = "ÚÑíÖ";
+ Text[ greek ] = "¸íôïíï";
+ Text[ korean ] = "±½°Ô";
+ Text[ turkish ] = "Kalýn";
+ Text[ language_user1 ] = " ";
+};
+
+String STR_SVT_STYLE_BOLD_ITALIC
+{
+ Text = "Fett Kursiv" ;
+ Text [ ENGLISH ] = "Bold Italic" ;
+ Text [ english_us ] = "Bold Italic" ;
+ Text [ italian ] = "Corsivo Grassetto" ;
+ Text [ spanish ] = "Cursiva negrita" ;
+ Text [ french ] = "Italique gras" ;
+ Text [ dutch ] = "Vet Cursief" ;
+ Text [ swedish ] = "Fet kursiv" ;
+ Text [ danish ] = "Fed kursiv" ;
+ Text [ portuguese_brazilian ] = "Bold Italic" ;
+ Text [ portuguese ] = "Negrito itálico" ;
+ Text[ russian ] = "Æèðíûé êóðñèâ";
+ Text[ polish ] = "Pogrubiona kursywa";
+ Text[ japanese ] = "‘¾Žš‚̎ΑÌ";
+ Text[ chinese_simplified ] = "´ÖбÌå";
+ Text[ chinese_traditional ] = "²Ê±×Åé";
+ Text[ arabic ] = "ÚÑíÖ ãÇÆá";
+ Text[ greek ] = "ÐëÜãéá ¸íôïíá";
+ Text[ korean ] = "±½Àº ÀÌÅŸ¯Ã¼";
+ Text[ turkish ] = "Kalýn italik";
+ Text[ language_user1 ] = " ";
+};
+
+String STR_SVT_STYLE_BLACK
+{
+ Text = "Black" ;
+ Text [ ENGLISH ] = "Black" ;
+ Text [ english_us ] = "Black" ;
+ Text [ italian ] = "Black" ;
+ Text [ spanish ] = "Black" ;
+ Text [ french ] = "Extra gras" ;
+ Text [ dutch ] = "Black" ;
+ Text [ swedish ] = "Svart" ;
+ Text [ danish ] = "Black" ;
+ Text [ portuguese_brazilian ] = "Black" ;
+ Text [ portuguese ] = "Preto" ;
+ Text[ russian ] = "×åðíûé";
+ Text[ polish ] = "Czarny";
+ Text[ japanese ] = "•";
+ Text[ chinese_simplified ] = "ºÚÌå";
+ Text[ language_user1 ] = " ";
+ Text[ chinese_traditional ] = "¶ÂÅé";
+ Text[ arabic ] = "ÃÓæÏ";
+ Text[ greek ] = "Ìáýñï";
+ Text[ korean ] = "°Ë°Ô";
+ Text[ turkish ] = "Siyah";
+};
+
+String STR_SVT_STYLE_BLACK_ITALIC
+{
+ Text = "Black Kursiv" ;
+ Text [ ENGLISH ] = "Black Italic" ;
+ Text [ english_us ] = "Black Italic" ;
+ Text [ italian ] = "Corsivo Black" ;
+ Text [ spanish ] = "Cursiva black" ;
+ Text [ french ] = "Italique extra gras" ;
+ Text [ dutch ] = "Black Cursief" ;
+ Text [ swedish ] = "Svart kursiv" ;
+ Text [ danish ] = "Black kursiv" ;
+ Text [ portuguese_brazilian ] = "Black Italic" ;
+ Text [ portuguese ] = "Preto itálico" ;
+ Text[ russian ] = "×åðíûé êóðñèâ";
+ Text[ polish ] = "Czarna kursywa";
+ Text[ japanese ] = "•‚̎ΑÌ";
+ Text[ chinese_simplified ] = "ºÚбÌå";
+ Text[ language_user1 ] = " ";
+ Text[ chinese_traditional ] = "¶Â±×Åé";
+ Text[ arabic ] = "ÃÓæÏ ãÇÆá";
+ Text[ greek ] = "ÐëÜãéá Ìáýñï";
+ Text[ korean ] = "°ËÁ¤ ÀÌÅŸ¯Ã¼";
+ Text[ turkish ] = "Siyah italik";
+};
+
+/*
+Finnische Texte:
+ "Light",
+ "Light Kursivoitu",
+ "Normaali",
+ "Kursivoitu",
+ "Lihavoitu",
+ "Lihavoitu Kursivoitu",
+ "Black",
+ "Black Kursivoitu"
+*/
+
+String STR_SVT_FONTMAP_BOTH
+{
+ TEXT = "Für Ausdruck und Anzeige am Bildschirm wird die gleiche Schriftart verwendet." ;
+ TEXT [ English ] = "The same font will be used on both your printer and your screen." ;
+ TEXT [ norwegian ] = "The same font will be used on both your printer and your screen." ;
+ TEXT [ italian ] = "Questo tipo di carattere verrà utilizzato sia per lo schermo che per la stampante." ;
+ TEXT [ portuguese_brazilian ] = "Esta mesma fonte ser utilizada na impressora e na tela." ;
+ TEXT [ portuguese ] = "O tipo de letra utilizado para a impressora e para o ecrã é o mesmo." ;
+ TEXT [ finnish ] = "Tätä fonttia voidaan käyttää kirjoittimessa ja näytössä." ;
+ TEXT [ danish ] = "Denne skrifttype vil blive brugt både på skærmen og på printeren." ;
+ TEXT [ french ] = "La même police est utilisée pour l'impression et l'affichage à l'écran." ;
+ TEXT [ swedish ] = "Samma teckensnitt används för både skrivare och bildskärm." ;
+ TEXT [ dutch ] = "Dit lettertype wordt voor zowel de printer als het scherm gebruikt." ;
+ TEXT [ spanish ] = "Se usará la misma fuente en la impresora y en pantalla" ;
+ TEXT [ english_us ] = "The same font will be used on both your printer and your screen." ;
+ TEXT[ chinese_simplified ] = "ÆÁÄ»ÏÔʾºÍ´òӡʹÓÃͬһÖÖ×ÖÌå¡£";
+ TEXT[ russian ] = "Äëÿ ïå÷àòè è âûâîäà íà ýêðàí èñïîëüçóåòñÿ îäèí è òîò æå øðèôò";
+ TEXT[ polish ] = "U¿yj tej samej czcionki dla wydruku i ekranu";
+ TEXT[ japanese ] = "ˆóü‚Ɖæ–Ê•\\Ž¦‚É‚Í“¯‚¶Ì«ÝÄ‚ÌŽí—Þ‚ªŽg—p‚³‚ê‚Ä‚¢‚Ü‚·B";
+ TEXT[ chinese_traditional ] = "¿Ã¹õÅã¥Ü©M¦C¦L¨Ï¥Î²Î¤@ªº¦r«¬";
+ TEXT[ arabic ] = "ÓæÝ íÊã ÇÓÊÎÏÇã äÝÓ ÇáÎØ ááØÇÈÚÉ æÇáÔÇÔÉ.";
+ TEXT[ greek ] = "Ç ãñáììáôïóåéñÜ áõôÞ èá ÷ñçóéìïðïéçèåß ãéá ôçí ïèüíç êáé ãéá ôïí åêôõðùôÞ.";
+ TEXT[ korean ] = "´ç½ÅÀÇ ½Ã½ºÅÛ°ú È­¸é¿¡´Â °°Àº ±Û²ÃÀÌ »ç¿ëµÉ °Í ÀÔ´Ï´Ù.";
+ TEXT[ turkish ] = "Yazdýrma ve ekranda görüntüleme için ayný yazýtipi kullanýlacak.";
+ TEXT[ language_user1 ] = " ";
+};
+
+String STR_SVT_FONTMAP_PRINTERONLY
+{
+ TEXT = "Druckerschrift. Die Bildschirmanzeige kann etwas abweichen." ;
+ TEXT [ English ] = "This is a printer font. The screen image may not exactly match." ;
+ TEXT [ norwegian ] = "This is a printer font. The screen image may not exactly match." ;
+ TEXT [ italian ] = "Il tipo di carattere visualizzato differisce da quello stampato." ;
+ TEXT [ portuguese_brazilian ] = "Esta é uma fonte de impressora. A imagem na tela pode não corresponder exatamente." ;
+ TEXT [ portuguese ] = "Letra de impressora. A letra vista no ecrã pode apresentar um pequeno desvio." ;
+ TEXT [ finnish ] = "Tämä on kirjoitinfontti. Näytön sisältö ei ehkä ole aivan samanlainen." ;
+ TEXT [ danish ] = "Dette er en printerskrifttype. Skærmbilledet svarer muligvis ikke helt til printerskrifttypen." ;
+ TEXT [ french ] = "Police d'imprimante. L'affichage et l'impression ne seront pas toujours identiques." ;
+ TEXT [ swedish ] = "Detta är ett skrivarteckensnitt. Visningen på skärmbilden kan avvika något." ;
+ TEXT [ dutch ] = "Dit is een printerlettertype. De weergave op het scherm kan iets afwijken." ;
+ TEXT [ spanish ] = "Fuente de impresora. La imagen en pantalla podría ser diferente." ;
+ TEXT [ english_us ] = "This is a printer font. The screen image may differ." ;
+ TEXT[ chinese_simplified ] = "ÕâÊÇ´òÓ¡×ÖÌå¡£ÆÁÄ»ÏÔʾµÄ×ÖÌåÓëÆä¿ÉÄÜ»áÓÐЩƫ²î¡£";
+ TEXT[ russian ] = "Øðèôò ïå÷àòè. Íà ýêðàíå ìîæåò íåìíîãî îòëè÷àòüñÿ.";
+ TEXT[ polish ] = "Czcionka drukarkowa. Obraz czcionek na ekranie mo¿e siê trochê ró¿niæ.";
+ TEXT[ japanese ] = "ÌßØÝÀ—p‚ÌÌ«ÝÄ‚Å‚·B‰æ–Ê•\\Ž¦‚Æ‚Í­‚µˆÙ‚È‚è‚Ü‚·B";
+ TEXT[ chinese_traditional ] = "¦C¦L¦r«¬¡C¿Ã¹õÅã¥Ü¦r«¬¥i¯à²¤·L¦³¨Ç°¾®t¡C";
+ TEXT[ arabic ] = "åÐÇ ÎØ ÇáØÇÈÚÉ. ÞÏ íÎÊáÝ ÇáãÙåÑ Úáì ÇáÔÇÔÉ ÈÚÖ ÇáÔÆ.";
+ TEXT[ greek ] = "ÃñáììáôïóåéñÜ åêôõðùôÞ. Ç åìöÜíéóç ôçò óôçí ïèüíç åßíáé äõíáôüí íá äéáöÝñåé.";
+ TEXT[ korean ] = "ÀÌ°ÍÀº Àμ⠱۲ÃÀÔ´Ï´Ù. È­¸éÀÇ À̹ÌÁö¿Í´Â ´Ù¸¦°Í ÀÔ´Ï´Ù.";
+ TEXT[ turkish ] = "Yazýcý yazýtipi. Ekrandaki görüntü biraz farklý olabilir.";
+};
+
+String STR_SVT_FONTMAP_SCREENONLY
+{
+ TEXT = "Bildschirmschrift. Der Ausdruck kann etwas abweichen." ;
+ TEXT [ English ] = "This is a screen font. The printer image may not exactly match." ;
+ TEXT [ norwegian ] = "This is a screen font. The printer image may not exactly match." ;
+ TEXT [ italian ] = "Questo è un carattere per lo schermo. La stampa può essere leggermente diversa." ;
+ TEXT [ portuguese_brazilian ] = "Esta é uma fonte de tela. A imagem impressa pode não corresponder exatamente." ;
+ TEXT [ portuguese ] = "Letra de ecrã. A letra impressa pode apresentar um pequeno desvio." ;
+ TEXT [ finnish ] = "Tämä on näyttöfontti. Tulosteen sisältö ei ehkä ole aivan samanlainen." ;
+ TEXT [ danish ] = "Dette er en skærmskrifttype. Udskriften kan muligvis afvige lidt." ;
+ TEXT [ french ] = "Police d'écran. L'impression et l'affichage ne seront pas toujours identiques." ;
+ TEXT [ swedish ] = "Detta är ett skärmteckensnitt. Utskriften kan vara lätt avvikande." ;
+ TEXT [ dutch ] = "Dit is een schermlettertype. De afdruk kan iets afwijken." ;
+ TEXT [ spanish ] = "Fuente de pantalla. La imagen en la impresora podría ser diferente." ;
+ TEXT [ english_us ] = "This is a screen font. The printer image may differ." ;
+ TEXT[ chinese_simplified ] = "ÕâÊÇÆÁÄ»×ÖÌå¡£´òÓ¡³öÀ´µÄ×ÖÌåÓëÆä¿ÉÄÜ»áÓÐһЩƫ²î¡£";
+ TEXT[ russian ] = "Øðèôò ýêðàíà.  ïå÷àòè ìîãóò áûòü îòêëîíåíèÿ.";
+ TEXT[ polish ] = "To jest czcionka ekranowa. Wydruk bêdzie siê trochê ró¿ni³.";
+ TEXT[ japanese ] = "‰æ–Ê—p‚ÌÌ«ÝÄ‚Å‚·Bˆóü²Ò°¼Þ‚Æ‚Í­‚µˆÙ‚È‚è‚Ü‚·B";
+ TEXT[ chinese_traditional ] = "¿Ã¹õ¦r«¬¡C¦C¦L¥X¥i¯à·|¦³¤@¨Ç°¾®t¡C";
+ TEXT[ arabic ] = "åÐÇ ÎØ ÔÇÔÉ. ÞÏ íÎÊáÝ ÇáãÙåÑ Úáì ÇáæÑÞ ÇáãØÈæÚ ÈÚÖ ÇáÔÆ.";
+ TEXT[ greek ] = "ÃñáììáôïóåéñÜ ïèüíçò. Ç åìöÜíéóç ôçò óôçí åêôýðùóç åßíáé äõíáôüí íá äéáöÝñåé.";
+ TEXT[ korean ] = "ÀÌ°ÍÀº È­¸é ÆùÆ® ÀÔ´Ï´Ù. Àμâ À̹ÌÁö¿Í´Â ´Ù¸¦ °Í ÀÔ´Ï´Ù.";
+ TEXT[ turkish ] = "Ekran yazýtipi. Yazdýrma biraz farklý olabilir.";
+};
+
+String STR_SVT_FONTMAP_SIZENOTAVAILABLE
+{
+ TEXT = "Diese Schriftgröße ist nicht installiert. Die am besten passende vorhandene Größe wird benutzt." ;
+ TEXT [ English ] = "This font size is not installed. The closest available size will be used." ;
+ TEXT[ english_us ] = "This font size has not been installed. The closest available size will be used.";
+ TEXT[ portuguese ] = "Este tamanho de letra não está instalado. Será utilizado o tamanho disponível mais adequado.";
+ TEXT[ russian ] = "Òàêîé ðàçìåð øðèôòà íå èíñòàëëèðîâàí. Ïîýòîìó áóäåò èñïîëüçîâàí íàèáîëåå ïîäõîäÿùèé ðàçìåð.";
+ TEXT[ greek ] = "Ôï ìÝãåèïò ôçò ãñáììáôïóåéñÜò äåí Ý÷åé åãêáôáóôáèåß. ×ñçóéìïðïéåßôáé ôï ðëçóéÝóôåñï ìÝãåèïò.";
+ TEXT[ dutch ] = "Deze schriftgrootte is niet geïnstalleerd. De meest passende voorhanden zijnde grootte wordt toegepast.";
+ TEXT[ french ] = "Cette taille de police n'a pas été installée. La taille disponible la plus appropriée va être utilisée.";
+ TEXT[ spanish ] = "Este tamaño de fuente no está instalado. Se usará el tamaño disponible más adecuado.";
+ TEXT[ italian ] = "Il font delle dimensioni indicate non è installato. Il programma utilizzerà le dimensioni disponibili.";
+ TEXT[ danish ] = "Denne skriftstørrelse er ikke installeret. Den tilgængelige størrelse, som passer bedst, vil blive brugt i stedet.";
+ TEXT[ swedish ] = "Den här teckenstorleken är inte installerad. Den tillgängliga storlek som passar bäst används.";
+ TEXT[ polish ] = "Dany rozmiar czcionki nie jest zaistalowany. U¿yty zostanie najbardziej pasuj¹cy, ju¿ istniej¹ca rozmiar.";
+ TEXT[ portuguese_brazilian ] = "This font size is not installed. The closest available size will be used.";
+ TEXT[ japanese ] = "‚±‚ÌÌ«ÝÄ»²½Þ‚Ͳݽİق³‚ê‚Ä‚¢‚Ü‚¹‚ñBÅ‚à“KØ‚È»²½Þ‚ª‘I‚΂ê‚Ü‚·B";
+ TEXT[ korean ] = "ÀÌ ±Û²ÃÀÇ Å©±â´Â ¼³Ä¡µÇÁö ¾Ê¾Ò½À´Ï´Ù. À¯È¿ÇÑ °¡Àå À¯»çÇÑ Å©±â°¡ »ç¿ëµÉ°Í ÀÔ´Ï´Ù.";
+ TEXT[ chinese_simplified ] = "ûÓа²×°ÕâÖÖ×ÖÌå´óС¡£Ê¹ÓõÄÊÇÏÖÓеÄ×î½Ó½üµÄ×ÖÌå´óС¡£";
+ TEXT[ chinese_traditional ] = "¨S¦³¦w¸Ë³o­Ó¦r«¬¡C±Ä¥Î³Ìªñ¦üªº¦r«¬¡C";
+ TEXT[ arabic ] = "ÍÌã ÇáÎØ åÐÇ ÛíÑ ãËÈÊ. ÓæÝ íÊã ÇÓÊÎÏÇã ÃßËÑ ÇáÃÍÌÇã ÇáãæÌæÏÉ ÞÑÈÇð áå.";
+ TEXT[ turkish ] = "Bu yazýtipi boyu yüklenmedi. Mevcut boylardan en uygun olaný kullanýlacak.";
+};
+
+String STR_SVT_FONTMAP_STYLENOTAVAILABLE
+{
+ TEXT = "Dieser Schriftstil wird nachgebildet oder der am besten passende Stil wird verwendet." ;
+ TEXT [ English ] = "This font style will be generated or the closest matching style will be used." ;
+ TEXT[ english_us ] = "This font style will be simulated or the closest matching style will be used.";
+ TEXT[ portuguese ] = "Este estilo de letra será simulado ou será utilizado o estilo disponível mais adequado.";
+ TEXT[ russian ] = "Áóäåò ñîçäàí ëèáî òàêîé ñòèëü øðèôòà, ëèáî áóäåò èñïîëüçîâàí íàèáîëåå ïîõîæèé.";
+ TEXT[ greek ] = "Ôï óôõë áõôü ãñáììáôïóåéñÜò èá áíôéãñáöåß Þ èá ÷ñçóéìïðïéçèåß ôï ðëçóéÝóôåñï óôõë..";
+ TEXT[ dutch ] = "Dit lettertype wordt nagebootst of het meest overeenkomende voorhanden zijnde type wordt gebruikt.";
+ TEXT[ french ] = "Ce style de police sera imité ou le style le plus approprié sera utilisé.";
+ TEXT[ spanish ] = "Se imitará este estilo de fuente o se usará el más adecuado.";
+ TEXT[ italian ] = "Verrà riprodotto lo stile di questo font oppure verrà utilizzato quello che gli è più simile.";
+ TEXT[ danish ] = "Denne skrifttype bliver reproduceret eller den type, som passer bedst, vil blive brugt istedet.";
+ TEXT[ swedish ] = "Det här teckensnittet efterbildas eller närmast motsvarande teckensnitt används.";
+ TEXT[ polish ] = "Dany styl czcionki zostanie skopiowany lub zostanie u¿yty najlepiej pasuj¹cy styl.";
+ TEXT[ portuguese_brazilian ] = "This font style will be generated or the closest matching style will be used.";
+ TEXT[ japanese ] = "‚±‚ÌÌ«ÝĽÀ²Ù‚ÍC³‚³‚ê‚é‚©A‚Ü‚½‚ÍÅ‚à“K؂ȽÀ²Ù‚ªŽg—p‚³‚ê‚Ü‚·B";
+ TEXT[ korean ] = "ÀÌ ±Û²Ãü¿¡ °¡Àå À¯»çÇÑ ±Û²Ãü°¡ »ç¿ëµÉ°Í ÀÔ´Ï´Ù.";
+ TEXT[ chinese_simplified ] = "Éú³ÉÕâÖÖ×ÖÌå»òʹÓÃ×î½Ó½üµÄ×ÖÌå¡£";
+ TEXT[ chinese_traditional ] = "¼Ò¥é³o­Ó¦r«¬©Î±Ä¥Î³Ìªñ¦üªº¦r«¬¡C";
+ TEXT[ arabic ] = "ÓæÝ íÊã ÊÞáíÏ äãØ ÇáÎØ åÐÇ¡ Ãæ ÓæÝ íÊã ÇÓÊÎÏÇã ÃÞÑÈ äãØð áå.";
+ TEXT[ turkish ] = "Bu yazýtipi taklit edilecek ya da en uygun olan biçim kullanýlacak.";
+ TEXT[ language_user1 ] = " ";
+};
+
+String STR_SVT_FONTMAP_NOTAVAILABLE
+{
+ TEXT = "Diese Schriftart ist nicht installiert. Die am besten passende vorhandene Schriftart wird benutzt." ;
+ TEXT [ English ] = "This font is not installed. The closest available font will be used." ;
+ TEXT[ english_us ] = "This font has not been installed. The closest available font will be used.";
+ TEXT[ portuguese ] = "Este tipo de letra não está instalado. Será utilizado o tipo de letra disponível mais adequado.";
+ TEXT[ russian ] = "Ýòîò òèï øðèôòà íå èíñòàëëèðîâàí. Ïîýòîìó áóäåò èñïîëüçîâàí îäèí èç íàèáîëåå ïîäõîäÿùèõ.";
+ TEXT[ greek ] = "Ç ãñáììáôïóåéñÜ äåí Ý÷åé åãêáôáóôáèåß. ×ñçóéìïðïéåßôáé ç ðëçóéÝóôåñç (áðü Üðïøç ÷áñáêôçñéóôéêþí) ãñáììáôïóåéñÜ.";
+ TEXT[ dutch ] = "Dit lettertype is niet geïnstalleerd. Het meest overeenkomende voorhanden zijnde type wordt gebruikt.";
+ TEXT[ french ] = "Ce type de police n'a pas été installé. Le type de police le plus approprié va être utilisé.";
+ TEXT[ spanish ] = "Esta fuente no está instalada. Se usará la fuente existente más adecuada.";
+ TEXT[ italian ] = "Questo font non è installato. Il programma utilizzerà il font che gli è più simile.";
+ TEXT[ danish ] = "Denne skrifttype er ikke installeret. Den tilgængelige skrifttype, som passer bedst, vil blive brugt i stedet.";
+ TEXT[ swedish ] = "Det här teckensnittet är inte installerat. Det tillgängliga teckensnitt som passar bäst används.";
+ TEXT[ polish ] = "Dana czcionka nie jest zainstalowana.U¿yta zostanie najbardziej pasuj¹ca, ju¿ istniej¹ca czcionka.";
+ TEXT[ portuguese_brazilian ] = "This font is not installed. The closest available font will be used.";
+ TEXT[ japanese ] = "‚±‚ÌÌ«ÝĂͲݽİق³‚ê‚Ä‚¢‚Ü‚¹‚ñBÅ‚à“KØ‚ÈÌ«ÝÄ‚ª‘I‚΂ê‚Ü‚·B";
+ TEXT[ korean ] = "ÀÌ ±Û²ÃÀº ¼³Ä¡µÇÁö ¾Ê¾Ò½À´Ï´Ù. À¯È¿ÇÑ °¡Àå À¯»çÇÑ ±Û²ÃÀÌ »ç¿ëµÉ°Í ÀÔ´Ï´Ù.";
+ TEXT[ chinese_simplified ] = "ûÓа²×°ÕâÖÖ×ÖÌ塣ʹÓõÄÊÇÏÖÓеÄ×î½Ó½üµÄ×ÖÌå¡£";
+ TEXT[ chinese_traditional ] = "¨S¦³¦w¸Ë³o­Ó¦r«¬¡C±Ä¥Î³Ìªñ¦üªº¦r«¬¡C";
+ TEXT[ arabic ] = "åÐÇ ÇáÎØ ÛíÑ ãËÈÊ. ÓæÝ íÊã ÇÓÊÎÏÇã ÃßËÑ ÇáÎØæØ ÇáãæÌæÏÉ ÞÑÈÇð áå.";
+ TEXT[ turkish ] = "Bu yazýtipi yüklenmedi. Mevcut yazýtiplerinden en uygun olaný kullanýlacak.";
+};
diff --git a/svtools/source/control/filectrl.cxx b/svtools/source/control/filectrl.cxx
new file mode 100644
index 000000000000..e52b4107c3d4
--- /dev/null
+++ b/svtools/source/control/filectrl.cxx
@@ -0,0 +1,307 @@
+/*************************************************************************
+ *
+ * $RCSfile: filectrl.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_FIELCTRL_CXX
+
+#ifndef _URLOBJ_HXX //autogen wg. INetURLObject
+#include <tools/urlobj.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _VCL_FILEDLG_HXX
+#include <vcl/filedlg.hxx>
+#endif
+
+#include <filedlg.hxx>
+#include <svtdata.hxx>
+
+#include <filectrl.hxx>
+#include <filectrl.hrc>
+
+#pragma hdrstop
+
+// =======================================================================
+
+FileControl::FileControl( Window* pParent, WinBits nStyle, FileControlMode nFlags ) :
+ Window( pParent, nStyle|WB_DIALOGCONTROL ),
+ maEdit( this, (nStyle&(~WB_BORDER))|WB_NOTABSTOP ),
+ maButton( this, nStyle&(~WB_BORDER)|WB_NOLIGHTBORDER|WB_NOPOINTERFOCUS|WB_NOTABSTOP ),
+ maButtonText( SvtResId( STR_FILECTRL_BUTTONTEXT ) ),
+ mnFlags( nFlags ),
+ mnInternalFlags( FILECTRL_ORIGINALBUTTONTEXT ),
+ mpVclDlg( 0 ),
+ mpFDlg( 0 )
+{
+ maButton.SetClickHdl( LINK( this, FileControl, ButtonHdl ) );
+ mbOpenDlg = TRUE;
+
+ maButton.Show();
+ maEdit.Show();
+
+ SetCompoundControl( TRUE );
+
+ SetStyle( ImplInitStyle( GetStyle() ) );
+}
+
+// -----------------------------------------------------------------------
+
+WinBits FileControl::ImplInitStyle( WinBits nStyle )
+{
+ if ( !( nStyle & WB_NOTABSTOP ) )
+ {
+ maEdit.SetStyle( (maEdit.GetStyle()|WB_TABSTOP)&(~WB_NOTABSTOP) );
+ maButton.SetStyle( (maButton.GetStyle()|WB_TABSTOP)&(~WB_NOTABSTOP) );
+ }
+ else
+ {
+ maEdit.SetStyle( (maEdit.GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
+ maButton.SetStyle( (maButton.GetStyle()|WB_NOTABSTOP)&(~WB_TABSTOP) );
+ }
+
+ if ( !(nStyle & WB_NOGROUP) )
+ nStyle |= WB_GROUP;
+
+ if ( !(nStyle & WB_NOBORDER ) )
+ nStyle |= WB_BORDER;
+
+ nStyle &= ~WB_TABSTOP;
+
+ return nStyle;
+}
+
+// -----------------------------------------------------------------------
+
+FileControl::~FileControl()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::SetText( const XubString& rStr )
+{
+ maEdit.SetText( rStr );
+ if ( mnFlags & FILECTRL_RESIZEBUTTONBYPATHLEN )
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+XubString FileControl::GetText() const
+{
+ return maEdit.GetText();
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::StateChanged( StateChangedType nType )
+{
+ if ( nType == STATE_CHANGE_ENABLE )
+ {
+ maEdit.Enable( IsEnabled() );
+ maButton.Enable( IsEnabled() );
+ }
+ else if ( nType == STATE_CHANGE_ZOOM )
+ {
+ GetEdit().SetZoom( GetZoom() );
+ GetButton().SetZoom( GetZoom() );
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ SetStyle( ImplInitStyle( GetStyle() ) );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFONT )
+ {
+ GetEdit().SetControlFont( GetControlFont() );
+ // Fuer den Button nur die Hoehe uebernehmen, weil in
+ // HTML immer Courier eingestellt wird.
+ Font aFont = GetButton().GetControlFont();
+ aFont.SetSize( GetControlFont().GetSize() );
+ GetButton().SetControlFont( aFont );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ {
+ GetEdit().SetControlForeground( GetControlForeground() );
+ GetButton().SetControlForeground( GetControlForeground() );
+ }
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ GetEdit().SetControlBackground( GetControlBackground() );
+ GetButton().SetControlBackground( GetControlBackground() );
+ }
+ Window::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::Resize()
+{
+ static long ButtonBorder = 10;
+
+ if( mnInternalFlags & FILECTRL_INRESIZE )
+ return;
+ mnInternalFlags |= FILECTRL_INRESIZE;//InResize = TRUE
+
+ Size aOutSz = GetOutputSizePixel();
+ long nButtonTextWidth = maButton.GetTextWidth( maButtonText );
+ if ( (mnInternalFlags & FILECTRL_ORIGINALBUTTONTEXT == 0) ||
+ nButtonTextWidth < aOutSz.Width()/3 &&
+ ( mnFlags & FILECTRL_RESIZEBUTTONBYPATHLEN
+ ? ( maEdit.GetTextWidth( maEdit.GetText() )
+ <= aOutSz.Width() - nButtonTextWidth - ButtonBorder )
+ : TRUE )
+ )
+ {
+ maButton.SetText( maButtonText );
+ }
+ else
+ {
+ XubString aSmallText( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
+ maButton.SetText( aSmallText );
+ nButtonTextWidth = maButton.GetTextWidth( aSmallText );
+ }
+
+ long nButtonWidth = nButtonTextWidth+ButtonBorder;
+ maEdit.SetPosSizePixel( 0, 0, aOutSz.Width()-nButtonWidth, aOutSz.Height() );
+ maButton.SetPosSizePixel( aOutSz.Width()-nButtonWidth, 0, nButtonWidth, aOutSz.Height() );
+
+ mnInternalFlags &= ~FILECTRL_INRESIZE; //InResize = FALSE
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( FileControl, ButtonHdl, PushButton*, EMPTYARG )
+{
+ XubString aNewText;
+ mpVclDlg = GetpApp()->CreateFileDialog( this, mbOpenDlg ? WB_OPEN : WB_SAVEAS );
+
+ if ( mpVclDlg )
+ {
+ mpVclDlg->SetPath( maEdit.GetText() );
+
+ maDialogCreatedHdl.Call( this );
+
+ if ( mpVclDlg->Execute() )
+ aNewText = mpVclDlg->GetPath();
+ DELETEZ( mpVclDlg );
+ }
+ else
+ {
+ mpFDlg = new FileDialog( this, mbOpenDlg ? WB_OPEN : WB_SAVEAS );
+ mpFDlg->SetPath( maEdit.GetText() );
+
+ maDialogCreatedHdl.Call( this );
+
+ if ( mpFDlg->Execute() )
+ aNewText = mpFDlg->GetPath();
+ DELETEZ( mpFDlg );
+ }
+
+ if ( aNewText.Len() )
+ {
+ INetURLObject aObj( aNewText );
+ if ( aObj.GetProtocol() == INET_PROT_FILE )
+ aNewText = aObj.PathToFileName();
+ SetText( aNewText );
+ maEdit.GetModifyHdl().Call( &maEdit );
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::GetFocus()
+{
+ maEdit.GrabFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, ULONG nFlags )
+{
+ WinBits nOldEditStyle = GetEdit().GetStyle();
+ if ( GetStyle() & WB_BORDER )
+ GetEdit().SetStyle( nOldEditStyle|WB_BORDER );
+ GetEdit().Draw( pDev, rPos, rSize, nFlags );
+ if ( GetStyle() & WB_BORDER )
+ GetEdit().SetStyle( nOldEditStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::SetButtonText( const XubString& rStr )
+{
+ mnInternalFlags &= ~FILECTRL_ORIGINALBUTTONTEXT;
+ maButtonText = rStr;
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void FileControl::ResetButtonText()
+{
+ mnInternalFlags |= FILECTRL_ORIGINALBUTTONTEXT;
+ maButtonText = XubString( SvtResId( STR_FILECTRL_BUTTONTEXT ) );
+ Resize();
+}
+
+
diff --git a/svtools/source/control/filectrl.src b/svtools/source/control/filectrl.src
new file mode 100644
index 000000000000..2f56127d657d
--- /dev/null
+++ b/svtools/source/control/filectrl.src
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * $RCSfile: filectrl.src,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 "filectrl.hrc"
+String STR_FILECTRL_BUTTONTEXT
+{
+ Text = "Durchsuchen..." ;
+ Text [ ENGLISH ] = "Browse..." ;
+ Text [ english_us ] = "Browse..." ;
+ Text [ portuguese_brazilian ] = "Durchsuchen..." ;
+ Text [ swedish ] = "Genomsök..." ;
+ Text [ danish ] = "Gennemse..." ;
+ Text [ italian ] = "Sfoglia..." ;
+ Text [ spanish ] = "Examinar..." ;
+ Text [ french ] = "Parcourir..." ;
+ Text [ dutch ] = "Bladeren..." ;
+ Text [ portuguese ] = "Pesquisar..." ;
+ Text[ chinese_simplified ] = "ä¯ÀÀ...";
+ Text[ russian ] = "Îáçîð...";
+ Text[ polish ] = "Przegl¹daj...";
+ Text[ japanese ] = "ŒŸõ...";
+ Text[ chinese_traditional ] = "ÂsÄý...";
+ Text[ arabic ] = "ÇÓÊÚÑÇÖ...";
+ Text[ greek ] = "ÁíáæÞôçóç...";
+ Text[ korean ] = "ã¾Æº¸±â...";
+ Text[ turkish ] = "Tara...";
+};
diff --git a/svtools/source/control/fmtfield.cxx b/svtools/source/control/fmtfield.cxx
new file mode 100644
index 000000000000..6ddf7ee51eb6
--- /dev/null
+++ b/svtools/source/control/fmtfield.cxx
@@ -0,0 +1,1017 @@
+/*************************************************************************
+ *
+ * $RCSfile: fmtfield.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 <stdio.h>
+
+#ifndef _TOOLS_DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_SVAPP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+
+#ifndef _ZFORMAT_HXX //autogen
+#include "zformat.hxx"
+#endif
+
+#ifndef _FMTFIELD_HXX_
+#include "fmtfield.hxx"
+#endif // _FMTFIELD_HXX_
+
+//==============================================================================
+// regulaerer Ausdruck, um komplette Zahlen und alles, was waehrend der Eingabe einer kompletten Zahl als Fragment vorkommt,
+// abzudecken :
+// [+/-][{ziffer}*.]*{ziffer}*[,{ziffer}*][e[+/-]{ziffer}*]
+const char __FAR_DATA szNumericInput[] = "_[\\x2D\\x2B]?([0-9]*\\x++)*[0-9]*(\\x##[0-9]*)?(e[\\x2D\\x2B]?[0-9]*)?_";
+ // (die beiden _ sind fuer die Normierung, damit kann ich erzwingen, dass nie ein Teilstring gefunden wird)
+
+//==============================================================================
+SvNumberFormatter* FormattedField::StaticFormatter::s_cFormatter = NULL;
+ULONG FormattedField::StaticFormatter::s_nReferences = 0;
+
+//------------------------------------------------------------------------------
+SvNumberFormatter* FormattedField::StaticFormatter::GetFormatter()
+{
+ if (!s_cFormatter)
+ s_cFormatter = new SvNumberFormatter(Application::GetAppInternational().GetLanguage());
+ return s_cFormatter;
+}
+
+//------------------------------------------------------------------------------
+FormattedField::StaticFormatter::StaticFormatter()
+{
+ ++s_nReferences;
+}
+
+//------------------------------------------------------------------------------
+FormattedField::StaticFormatter::~StaticFormatter()
+{
+ if (--s_nReferences == 0)
+ {
+ delete s_cFormatter;
+ s_cFormatter = NULL;
+ }
+}
+
+//==============================================================================
+DBG_NAME(FormattedField);
+
+#define INIT_MEMBERS() \
+ m_aLastSelection(0,0) \
+ ,m_bStrictFormat(TRUE) \
+ ,m_nFormatKey(0) \
+ ,m_pFormatter(NULL) \
+ ,m_dMinValue(0) \
+ ,m_dMaxValue(0) \
+ ,m_bHasMin(FALSE) \
+ ,m_bHasMax(FALSE) \
+ ,m_dCurrentValue(0) \
+ ,m_bValueDirty(TRUE) \
+ ,m_bEnableEmptyField(TRUE) \
+ ,m_dDefaultValue(0) \
+ ,m_dSpinSize(1) \
+ ,m_dSpinFirst(-1000000) \
+ ,m_dSpinLast(1000000) \
+ ,m_bTreatAsNumber(TRUE) \
+ ,m_pLastOutputColor(NULL)
+
+//------------------------------------------------------------------------------
+FormattedField::FormattedField(Window* pParent, WinBits nStyle, SvNumberFormatter* pInitialFormatter, INT32 nFormatKey)
+ :SpinField(pParent, nStyle)
+ ,INIT_MEMBERS()
+{
+ DBG_CTOR(FormattedField, NULL);
+
+ if (pInitialFormatter)
+ {
+ m_pFormatter = pInitialFormatter;
+ m_nFormatKey = nFormatKey;
+ }
+}
+
+//------------------------------------------------------------------------------
+FormattedField::FormattedField(Window* pParent, const ResId& rResId, SvNumberFormatter* pInitialFormatter, INT32 nFormatKey)
+ :SpinField(pParent, rResId)
+ ,INIT_MEMBERS()
+{
+ DBG_CTOR(FormattedField, NULL);
+
+ if (pInitialFormatter)
+ {
+ m_pFormatter = pInitialFormatter;
+ m_nFormatKey = nFormatKey;
+ }
+}
+
+//------------------------------------------------------------------------------
+FormattedField::~FormattedField()
+{
+ DBG_DTOR(FormattedField, NULL);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetValidateText(const XubString& rText, const String* pErrorText)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (CheckText(rText))
+ SetText(rText);
+ else
+ if (pErrorText)
+ ImplSetText(*pErrorText, NULL);
+ else
+ ImplSetValue(m_dDefaultValue, TRUE);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetText(const XubString& rStr)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ SpinField::SetText(rStr);
+ m_bValueDirty = TRUE;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetTextFormatted(const XubString& rStr)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+#if DBG_UTIL
+ if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ DBG_WARNING("FormattedField::SetTextFormatted : valid only with text formats !");
+#endif
+
+ m_sCurrentTextValue = rStr;
+
+ String sFormatted;
+ ImplGetFormatter()->GetOutputString(m_sCurrentTextValue, m_nFormatKey, sFormatted, &m_pLastOutputColor);
+
+ // calculate the new selection
+ Selection aSel(GetSelection());
+ Selection aNewSel(aSel);
+ aNewSel.Justify();
+ USHORT nNewLen = sFormatted.Len();
+ USHORT nCurrentLen = GetText().Len();
+ if ((nNewLen > nCurrentLen) && (aNewSel.Max() == nCurrentLen))
+ { // the new text is longer and the cursor was behind the last char (of the old text)
+ if (aNewSel.Min() == 0)
+ { // the whole text was selected -> select the new text on the whole, too
+ aNewSel.Max() = nNewLen;
+ if (!nCurrentLen)
+ { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
+ ULONG nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
+ if (nSelOptions & SELECTION_OPTION_SHOWFIRST)
+ { // selection should be from right to left -> swap min and max
+ aNewSel.Min() = aNewSel.Max();
+ aNewSel.Max() = 0;
+ }
+ }
+ }
+ else if (aNewSel.Max() == aNewSel.Min())
+ { // there was no selection -> set the cursor behind the new last char
+ aNewSel.Max() = nNewLen;
+ aNewSel.Min() = nNewLen;
+ }
+ }
+ else if (aNewSel.Max() > nNewLen)
+ aNewSel.Max() = nNewLen;
+ else
+ aNewSel = aSel; // don't use the justified version
+ SpinField::SetText(sFormatted, aNewSel);
+ m_bValueDirty = FALSE;
+}
+
+//------------------------------------------------------------------------------
+String FormattedField::GetTextValue() const
+{
+ if (m_bValueDirty)
+ {
+ ((FormattedField*)this)->m_sCurrentTextValue = GetText();
+ ((FormattedField*)this)->m_bValueDirty = FALSE;
+ }
+ return m_sCurrentTextValue;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Modify()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (!IsStrictFormat())
+ {
+ m_bValueDirty = TRUE;
+ SpinField::Modify();
+ return;
+ }
+
+ String sCheck = GetText();
+ if (CheckText(sCheck))
+ {
+ m_sLastValidText = sCheck;
+ m_aLastSelection = GetSelection();
+ m_bValueDirty = TRUE;
+ }
+ else
+ {
+ ImplSetText(m_sLastValidText, &m_aLastSelection);
+ }
+
+ SpinField::Modify();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ImplSetText(const XubString& rNew, Selection* pNewSel)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (pNewSel)
+ SpinField::SetText(rNew, *pNewSel);
+ else
+ {
+ Selection aSel(GetSelection());
+ aSel.Justify();
+
+ USHORT nNewLen = rNew.Len();
+ USHORT nCurrentLen = GetText().Len();
+
+ if ((nNewLen > nCurrentLen) && (aSel.Max() == nCurrentLen))
+ { // new new text is longer and the cursor is behind the last char
+ if (aSel.Min() == 0)
+ { // the whole text was selected -> select the new text on the whole, too
+ aSel.Max() = nNewLen;
+ if (!nCurrentLen)
+ { // there wasn't really a previous selection (as there was no previous text), we're setting a new one -> check the selection options
+ ULONG nSelOptions = GetSettings().GetStyleSettings().GetSelectionOptions();
+ if (nSelOptions & SELECTION_OPTION_SHOWFIRST)
+ { // selection should be from right to left -> swap min and max
+ aSel.Min() = aSel.Max();
+ aSel.Max() = 0;
+ }
+ }
+ }
+ else if (aSel.Max() == aSel.Min())
+ { // there was no selection -> set the cursor behind the new last char
+ aSel.Max() = nNewLen;
+ aSel.Min() = nNewLen;
+ }
+ }
+ else if (aSel.Max() > nNewLen)
+ aSel.Max() = nNewLen;
+ SpinField::SetText(rNew, aSel);
+ }
+
+ m_bValueDirty = TRUE;
+ // muss nicht stimmen, aber sicherheitshalber ...
+}
+
+//------------------------------------------------------------------------------
+long FormattedField::PreNotify(NotifyEvent& rNEvt)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (rNEvt.GetType() == EVENT_KEYINPUT)
+ m_aLastSelection = GetSelection();
+ return SpinField::PreNotify(rNEvt);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ImplSetFormatKey(ULONG nFormatKey)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ m_nFormatKey = nFormatKey;
+ BOOL bNeedFormatter = (m_pFormatter == NULL) && (nFormatKey != 0);
+ if (bNeedFormatter)
+ {
+ ImplGetFormatter(); // damit wird ein Standard-Formatter angelegt
+
+ m_nFormatKey = nFormatKey;
+ // kann sein, dass das in dem Standard-Formatter keinen Sinn macht, aber der nimmt dann ein Default-Format an.
+ // Auf diese Weise kann ich einfach einen der - formatteruebergreifended gleichen - Standard-Keys setzen.
+ DBG_ASSERT(m_pFormatter->GetEntry(nFormatKey) != NULL, "FormattedField::ImplSetFormatKey : invalid format key !");
+ // Wenn SetFormatKey aufgerufen wird, ohne dass ein Formatter existiert, muss der Key einer der Standard-Werte
+ // sein, der in allen Formattern (also auch in meinem neu angelegten) vorhanden ist.
+ }
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetFormatKey(ULONG nFormatKey)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ BOOL bNoFormatter = (m_pFormatter == NULL);
+ ImplSetFormatKey(nFormatKey);
+ FormatChanged((bNoFormatter && (m_pFormatter != NULL)) ? FCT_FORMATTER : FCT_KEYONLY);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetFormatter(SvNumberFormatter* pFormatter, BOOL bResetFormat)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (bResetFormat)
+ {
+ m_pFormatter = pFormatter;
+ m_nFormatKey = 0;
+ }
+ else
+ {
+ XubString sOldFormat;
+ LanguageType aOldLang;
+ GetFormat(sOldFormat, aOldLang);
+
+ ULONG nDestKey = pFormatter->TestNewString(sOldFormat);
+ if (nDestKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ // die Sprache des neuen Formatters
+ const SvNumberformat* pDefaultEntry = pFormatter->GetEntry(0);
+ LanguageType aNewLang = pDefaultEntry ? pDefaultEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+
+ // den alten Format-String in die neue Sprache konvertieren
+ USHORT nCheckPos;
+ short nType;
+ pFormatter->PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang);
+ m_nFormatKey = nDestKey;
+ }
+ m_pFormatter = pFormatter;
+ }
+
+ FormatChanged(FCT_FORMATTER);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::GetFormat(XubString& rFormatString, LanguageType& eLang) const
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
+ DBG_ASSERT(pFormatEntry != NULL, "FormattedField::ResetConformanceTester : no number format for the given format key.");
+ rFormatString = pFormatEntry ? pFormatEntry->GetFormatstring() : XubString();
+ eLang = pFormatEntry ? pFormatEntry->GetLanguage() : LANGUAGE_DONTKNOW;
+}
+
+//------------------------------------------------------------------------------
+BOOL FormattedField::SetFormat(const XubString& rFormatString, LanguageType eLang)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ ULONG nNewKey = ImplGetFormatter()->TestNewString(rFormatString, eLang);
+ if (nNewKey == NUMBERFORMAT_ENTRY_NOT_FOUND)
+ {
+ USHORT nCheckPos;
+ short nType;
+ XubString rFormat(rFormatString);
+ if (!ImplGetFormatter()->PutEntry(rFormat, nCheckPos, nType, nNewKey))
+ return FALSE;
+ DBG_ASSERT(nNewKey != NUMBERFORMAT_ENTRY_NOT_FOUND, "FormattedField::SetFormatString : PutEntry returned an invalid key !");
+ }
+
+ if (nNewKey != m_nFormatKey)
+ SetFormatKey(nNewKey);
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+BOOL FormattedField::GetThousandsSep() const
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::GetThousandsSep : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+
+ return bThousand;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetThousandsSep(BOOL _bUseSeparator)
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::SetThousandsSep : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ // get the current settings
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+ if (bThousand == _bUseSeparator)
+ return;
+
+ // we need the language for the following
+ LanguageType eLang;
+ String sFmtDescription;
+ GetFormat(sFmtDescription, eLang);
+
+ // generate a new format ...
+ ImplGetFormatter()->GenerateFormat(sFmtDescription, m_nFormatKey, eLang, _bUseSeparator, IsRed, nPrecision, nAnzLeading);
+ // ... and introduce it to the formatter
+ USHORT nCheckPos;
+ ULONG nNewKey;
+ short nType;
+ ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
+
+ // set the new key
+ ImplSetFormatKey(nNewKey);
+ FormatChanged(FCT_THOUSANDSSEP);
+}
+
+//------------------------------------------------------------------------------
+USHORT FormattedField::GetDecimalDigits() const
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::GetDecimalDigits : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+
+ return nPrecision;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetDecimalDigits(USHORT _nPrecision)
+{
+ DBG_ASSERT(!ImplGetFormatter()->IsTextFormat(m_nFormatKey),
+ "FormattedField::SetDecimalDigits : your'e sure what your'e doing when setting the precision of a text format ?");
+
+ // get the current settings
+ BOOL bThousand, IsRed;
+ USHORT nPrecision, nAnzLeading;
+ ImplGetFormatter()->GetFormatSpecialInfo(m_nFormatKey, bThousand, IsRed, nPrecision, nAnzLeading);
+ if (nPrecision == _nPrecision)
+ return;
+
+ // we need the language for the following
+ LanguageType eLang;
+ String sFmtDescription;
+ GetFormat(sFmtDescription, eLang);
+
+ // generate a new format ...
+ ImplGetFormatter()->GenerateFormat(sFmtDescription, m_nFormatKey, eLang, bThousand, IsRed, _nPrecision, nAnzLeading);
+ // ... and introduce it to the formatter
+ USHORT nCheckPos;
+ ULONG nNewKey;
+ short nType;
+ ImplGetFormatter()->PutEntry(sFmtDescription, nCheckPos, nType, nNewKey, eLang);
+
+ // set the new key
+ ImplSetFormatKey(nNewKey);
+ FormatChanged(FCT_PRECISION);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::FormatChanged(FORMAT_CHANGE_TYPE /*nWhat*/)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ m_pLastOutputColor = NULL;
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ReFormat()
+{
+ if (!IsEmptyFieldEnabled() || GetText().Len())
+ if (TreatingAsNumber())
+ ImplSetValue(GetValue(), TRUE);
+ else
+ SetTextFormatted(GetTextValue());
+}
+
+//------------------------------------------------------------------------------
+long FormattedField::Notify(NotifyEvent& rNEvt)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if ((rNEvt.GetType() == EVENT_KEYINPUT) && !IsReadOnly())
+ {
+ const KeyEvent& rKEvt = *rNEvt.GetKeyEvent();
+ USHORT nMod = rKEvt.GetKeyCode().GetModifier();
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ if (!nMod && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ {
+ // the base class would translate this into calls to Up/Down/First/Last,
+ // but we don't want this if we are text-formatted
+ return 1;
+ }
+ }
+ }
+
+ if ((rNEvt.GetType() == EVENT_COMMAND) && !IsReadOnly())
+ {
+ const CommandEvent* pCommand = rNEvt.GetCommandEvent();
+ if (pCommand->GetCommand() == COMMAND_WHEEL)
+ {
+ const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData();
+ if ((pData->GetMode() == COMMAND_WHEEL_SCROLL) && ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ {
+ // same as above : prevent the base class from doing Up/Down-calls
+ // (normally I should put this test into the Up/Down methods itself, shouldn't I ?)
+ // FS - 71553 - 19.01.00
+ return 1;
+ }
+ }
+ }
+
+ if (rNEvt.GetType() == EVENT_LOSEFOCUS)
+ {
+ // Sonderbehandlung fuer leere Texte
+ if (GetText().Len() == 0)
+ {
+ if (!IsEmptyFieldEnabled())
+ {
+ if (TreatingAsNumber())
+ {
+ ImplSetValue(m_dCurrentValue, TRUE);
+ Modify();
+ }
+ else
+ {
+ String sNew = GetTextValue();
+ if (sNew.Len())
+ SetTextFormatted(sNew);
+ else
+ SetTextFormatted(m_sDefaultText);
+ }
+ m_bValueDirty = FALSE;
+ }
+ }
+ else
+ {
+ String sOld = GetText();
+ ReFormat();
+ if (GetText() != sOld)
+ Modify();
+ }
+ }
+
+ return SpinField::Notify( rNEvt );
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetMinValue(double dMin)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMinValue : only to be used in numeric mode !");
+
+ m_dMinValue = dMin;
+ m_bHasMin = TRUE;
+ // fuer die Ueberpruefung des aktuellen Wertes an der neuen Grenze -> ImplSetValue
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetMaxValue(double dMax)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ DBG_ASSERT(m_bTreatAsNumber, "FormattedField::SetMaxValue : only to be used in numeric mode !");
+
+ m_dMaxValue = dMax;
+ m_bHasMax = TRUE;
+ // fuer die Ueberpruefung des aktuellen Wertes an der neuen Grenze -> ImplSetValue
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetTextValue(const XubString& rText)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ SetText(rText);
+ ReFormat();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::EnableEmptyField(BOOL bEnable)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (bEnable == m_bEnableEmptyField)
+ return;
+
+ m_bEnableEmptyField = bEnable;
+ if (!m_bEnableEmptyField && GetText().Len()==0)
+ ImplSetValue(m_dCurrentValue, TRUE);
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::ImplSetValue(double dVal, BOOL bForce)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (m_bHasMin && (dVal<m_dMinValue))
+ dVal = m_dMinValue;
+ if (m_bHasMax && (dVal>m_dMaxValue))
+ dVal = m_dMaxValue;
+ if (!bForce && (dVal == GetValue()))
+ return;
+
+ DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplSetValue : can't set a value without a formatter !");
+
+ m_bValueDirty = FALSE;
+ m_dCurrentValue = dVal;
+
+ String sNewText;
+ if (ImplGetFormatter()->IsTextFormat(m_nFormatKey))
+ {
+ // zuerst die Zahl als String im Standard-Format
+ String sTemp;
+ ImplGetFormatter()->GetOutputString(dVal, 0, sTemp, &m_pLastOutputColor);
+ // dann den String entsprechend dem Text-Format
+ ImplGetFormatter()->GetOutputString(sTemp, m_nFormatKey, sNewText, &m_pLastOutputColor);
+ }
+ else
+ {
+ ImplGetFormatter()->GetOutputString(dVal, m_nFormatKey, sNewText, &m_pLastOutputColor);
+ }
+
+ ImplSetText(sNewText, NULL);
+ m_bValueDirty = FALSE;
+ DBG_ASSERT(CheckText(sNewText), "FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
+}
+
+//------------------------------------------------------------------------------
+BOOL FormattedField::ImplGetValue(double& dNewVal)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ dNewVal = m_dCurrentValue;
+ if (!m_bValueDirty)
+ return TRUE;
+
+ dNewVal = m_dDefaultValue;
+ String sText(GetText());
+ if (!sText.Len())
+ return TRUE;
+
+ DBG_ASSERT(ImplGetFormatter() != NULL, "FormattedField::ImplGetValue : can't give you a current value without a formatter !");
+
+ ULONG nFormatKey = m_nFormatKey; // IsNumberFormat veraendert den FormatKey ...
+
+ if (ImplGetFormatter()->IsTextFormat(nFormatKey) && m_bTreatAsNumber)
+ // damit wir in einem als Text formatierten Feld trotzdem eine Eingabe wie '1,1' erkennen ...
+ nFormatKey = 0;
+
+ // Sonderbehandlung fuer %-Formatierung
+ if (ImplGetFormatter()->GetType(m_nFormatKey) == NUMBERFORMAT_PERCENT)
+ {
+ ULONG nTempFormat = 0;
+ double dTemp;
+ if (m_pFormatter->IsNumberFormat(sText, nTempFormat, dTemp) &&
+ NUMBERFORMAT_NUMBER == m_pFormatter->GetType(nTempFormat))
+ // der String entspricht einer Number-Formatierung, hat also nur kein %
+ // -> dranhaengen
+ sText += '%';
+ // (damit wird aus einer Eingabe '3' ein '3%', und der Formatter macht dann daraus
+ // ein double 0.03. Ansonsten wuerden wir hier bei einer Eingabe von '3' ein double
+ // 3 zurueckliefern, was 300 Prozent entspricht ...
+ }
+ if (!ImplGetFormatter()->IsNumberFormat(sText, nFormatKey, dNewVal))
+ return FALSE;
+
+
+ if (m_bHasMin && (dNewVal<m_dMinValue))
+ dNewVal = m_dMinValue;
+ if (m_bHasMax && (dNewVal>m_dMaxValue))
+ dNewVal = m_dMaxValue;
+ return TRUE;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::SetValue(double dVal)
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ ImplSetValue(dVal, m_bValueDirty);
+}
+
+//------------------------------------------------------------------------------
+double FormattedField::GetValue()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+
+ if (!ImplGetValue(m_dCurrentValue))
+ m_dCurrentValue = m_dDefaultValue;
+
+ m_bValueDirty = FALSE;
+ return m_dCurrentValue;
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Up()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ SetValue(GetValue() + m_dSpinSize);
+ // das setValue handelt Bereichsueberschreitungen (min/max) automatisch
+ SetModifyFlag();
+ Modify();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Down()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ SetValue(GetValue() - m_dSpinSize);
+ SetModifyFlag();
+ Modify();
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::First()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (m_bHasMin)
+ {
+ SetValue(m_dMinValue);
+ SetModifyFlag();
+ Modify();
+ }
+}
+
+//------------------------------------------------------------------------------
+void FormattedField::Last()
+{
+ DBG_CHKTHIS(FormattedField, NULL);
+ if (m_bHasMax)
+ {
+ SetValue(m_dMaxValue);
+ SetModifyFlag();
+ Modify();
+ }
+}
+
+//==============================================================================
+//------------------------------------------------------------------------------
+DoubleNumericField::~DoubleNumericField()
+{
+ delete m_pConformanceTester;
+}
+
+//------------------------------------------------------------------------------
+void DoubleNumericField::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
+{
+ ResetConformanceTester();
+ FormattedField::FormatChanged(nWhat);
+}
+
+//------------------------------------------------------------------------------
+BOOL DoubleNumericField::CheckText(const XubString& sText) const
+{
+ // Ich wuerde das CheckText gern ueber den NumberFormatter laufen lassen (da gibt es schliesslich ein IsNumberFormat),
+ // aber der erkennt leider keine Fragmente (also zum Beispiel '1e', was waehrend der Eingabe zwangslaeufig irgendwann mal
+ // vorkommt), also dieser Umweg ueber einen SearchText.
+
+ if (!sText.Len())
+ return TRUE;
+
+ String sForceComplete = '_';
+ sForceComplete += sText;
+ sForceComplete += '_';
+
+ USHORT nStart = 0, nEnd = sForceComplete.Len();
+ BOOL bFound = m_pConformanceTester->SearchFrwrd(sForceComplete, &nStart, &nEnd);
+
+ if (bFound && (nStart == 0) && (nEnd == sForceComplete.Len() - 1))
+ return TRUE;
+
+ return FALSE;
+}
+
+//------------------------------------------------------------------------------
+void DoubleNumericField::ResetConformanceTester()
+{
+ String sDescription = String::CreateFromAscii(szNumericInput);
+ // the thousands and the decimal separator are language dependent
+ const SvNumberformat* pFormatEntry = ImplGetFormatter()->GetEntry(m_nFormatKey);
+ char cSepHexCode[3];
+
+ unsigned char cSeparator = pFormatEntry ? International(pFormatEntry->GetLanguage()).GetNumThousandSep() : ',';
+ sprintf(cSepHexCode, "%0X", cSeparator);
+ sDescription.SearchAndReplaceAscii("++", String::CreateFromAscii(cSepHexCode));
+
+ cSeparator = pFormatEntry ? International(pFormatEntry->GetLanguage()).GetNumDecimalSep() : '.';
+ sprintf(cSepHexCode, "%0X", cSeparator);
+ sDescription.SearchAndReplaceAscii("##", String::CreateFromAscii(cSepHexCode));
+
+ delete m_pConformanceTester;
+ m_pConformanceTester = new SearchText(SearchParam(sDescription, SearchParam::SRCH_REGEXP, FALSE), GetpApp()->GetAppInternational());
+}
+
+
+//==============================================================================
+
+//------------------------------------------------------------------------------
+DoubleCurrencyField::DoubleCurrencyField(Window* pParent, WinBits nStyle)
+ :FormattedField(pParent, nStyle)
+ ,m_bChangingFormat(FALSE)
+{
+ m_bPrependCurrSym = FALSE;
+
+ // initialize with a system currency format
+ SvNumberFormatter* pFormatter = StandardFormatter();
+ const NfCurrencyEntry* pSystemCurrency = pFormatter->MatchSystemCurrency();
+ if (!pSystemCurrency)
+ pSystemCurrency = &pFormatter->GetCurrencyEntry(LANGUAGE_SYSTEM);
+ if (pSystemCurrency)
+ m_sCurrencySymbol = pSystemCurrency->GetSymbol();
+ else
+ // no more options ...
+ m_sCurrencySymbol.AssignAscii("DM");
+ UpdateCurrencyFormat();
+}
+
+//------------------------------------------------------------------------------
+DoubleCurrencyField::DoubleCurrencyField(Window* pParent, const ResId& rResId)
+ :FormattedField(pParent, rResId)
+ ,m_bChangingFormat(FALSE)
+{
+ m_bPrependCurrSym = FALSE;
+
+ // initialize with a system currency format
+ SvNumberFormatter* pFormatter = StandardFormatter();
+ const NfCurrencyEntry* pSystemCurrency = pFormatter->MatchSystemCurrency();
+ if (!pSystemCurrency)
+ pSystemCurrency = &pFormatter->GetCurrencyEntry(LANGUAGE_SYSTEM);
+ if (pSystemCurrency)
+ m_sCurrencySymbol = pSystemCurrency->GetSymbol();
+ else
+ // no more options ...
+ m_sCurrencySymbol.AssignAscii("DM");
+ UpdateCurrencyFormat();
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::FormatChanged(FORMAT_CHANGE_TYPE nWhat)
+{
+ if (m_bChangingFormat)
+ {
+ FormattedField::FormatChanged(nWhat);
+ return;
+ }
+
+ switch (nWhat)
+ {
+ case FCT_FORMATTER:
+ case FCT_PRECISION:
+ case FCT_THOUSANDSSEP:
+ // the aspects which changed don't take our currency settings into account (in fact, they most probably
+ // destroyed them)
+ UpdateCurrencyFormat();
+ break;
+ case FCT_KEYONLY:
+ DBG_ERROR("DoubleCurrencyField::FormatChanged : somebody modified my key !");
+ // We always build our own format from the settings we get via special methods (setCurrencySymbol etc.).
+ // Nobody but ourself should modifiy the format key directly !
+ break;
+ }
+
+ FormattedField::FormatChanged(nWhat);
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::setCurrencySymbol(const String& _sSymbol)
+{
+ if (m_sCurrencySymbol == _sSymbol)
+ return;
+
+ m_sCurrencySymbol = _sSymbol;
+ UpdateCurrencyFormat();
+ FormatChanged(FCT_CURRENCY_SYMBOL);
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::setPrependCurrSym(BOOL _bPrepend)
+{
+ if (m_bPrependCurrSym == _bPrepend)
+ return;
+
+ m_bPrependCurrSym = _bPrepend;
+ UpdateCurrencyFormat();
+ FormatChanged(FCT_CURRSYM_POSITION);
+}
+
+//------------------------------------------------------------------------------
+void DoubleCurrencyField::UpdateCurrencyFormat()
+{
+ // the old settings
+ XubString sOldFormat;
+ LanguageType eLanguage;
+ GetFormat(sOldFormat, eLanguage);
+ BOOL bThSep = GetThousandsSep();
+ USHORT nDigits = GetDecimalDigits();
+
+ // build a new format string with the base class' and my own settings
+ International aIntl(eLanguage);
+ XubString sNewFormat;
+ if (bThSep)
+ {
+ sNewFormat = '#';
+ sNewFormat += aIntl.GetNumThousandSep();
+ sNewFormat.AppendAscii("##0");
+ }
+ else
+ sNewFormat = '0';
+
+ if (nDigits)
+ {
+ sNewFormat += aIntl.GetNumDecimalSep();
+
+ XubString sTemp;
+ sTemp.Fill(nDigits, '0');
+ sNewFormat += sTemp;
+ }
+
+ if (getPrependCurrSym())
+ {
+ XubString sSymbol = getCurrencySymbol();
+ sSymbol.EraseLeadingChars(' ');
+ sSymbol.EraseTrailingChars(' ');
+
+ XubString sTemp = sSymbol;
+ sTemp += ' ';
+ sTemp += sNewFormat;
+
+ // for negative values : $ -0.00, not -$ 0.00 ...
+ // (the real solution would be a possibility to choose a "positive currency format" and a "negative currency format" ...
+ // But not now ... (and hey, you could take a formatted field for this ....))
+ // FS - 31.03.00 74642
+ sTemp += ';';
+ sTemp += sSymbol;
+ sTemp.AppendAscii(" -");
+ sTemp += sNewFormat;
+
+ sNewFormat = sTemp;
+ }
+ else
+ {
+ XubString sTemp = getCurrencySymbol();
+ sTemp.EraseLeadingChars(' ');
+ sTemp.EraseTrailingChars(' ');
+
+ sNewFormat += ' ';
+ sNewFormat += sTemp;
+ }
+
+ // set this new basic format
+ m_bChangingFormat = TRUE;
+ SetFormat(sNewFormat, eLanguage);
+ m_bChangingFormat = FALSE;
+}
+
diff --git a/svtools/source/control/headbar.cxx b/svtools/source/control/headbar.cxx
new file mode 100644
index 000000000000..7bde8d02b60a
--- /dev/null
+++ b/svtools/source/control/headbar.cxx
@@ -0,0 +1,1673 @@
+/*************************************************************************
+ *
+ * $RCSfile: headbar.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_HEADBAR_CXX
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+
+#ifndef _VCL_APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _VCL_HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _VCL_IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+
+#ifndef _HEADBAR_HXX
+#include <headbar.hxx>
+#endif
+
+// =======================================================================
+
+struct ImplHeadItem
+{
+ USHORT mnId;
+ HeaderBarItemBits mnBits;
+ long mnSize;
+ ULONG mnHelpId;
+ Image maImage;
+ XubString maOutText;
+ XubString maText;
+ XubString maHelpText;
+ void* mpUserData;
+};
+
+DECLARE_LIST( ImplHeadItemList, ImplHeadItem* );
+
+// =======================================================================
+
+#define HEAD_ARROWSIZE1 4
+#define HEAD_ARROWSIZE2 7
+
+#define HEADERBAR_TEXTOFF 2
+#define HEADERBAR_ARROWOFF 5
+#define HEADERBAR_SPLITOFF 3
+
+#define HEADERBAR_DRAGOFF 4
+#define HEADERBAR_DRAGOUTOFF 15
+
+#define HEAD_HITTEST_ITEM ((USHORT)0x0001)
+#define HEAD_HITTEST_DIVIDER ((USHORT)0x0002)
+
+// =======================================================================
+
+void HeaderBar::ImplInit( WinBits nWinStyle )
+{
+ mpItemList = new ImplHeadItemList;
+ mnBorderOff1 = 0;
+ mnBorderOff2 = 0;
+ mnOffset = 0;
+ mnDX = 0;
+ mnDY = 0;
+ mnDragSize = 0;
+ mnStartPos = 0;
+ mnDragPos = 0;
+ mnMouseOff = 0;
+ mnCurItemId = 0;
+ mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
+ mbDrag = FALSE;
+ mbItemDrag = FALSE;
+ mbOutDrag = FALSE;
+ mbItemMode = FALSE;
+
+ // StyleBits auswerten
+ if ( nWinStyle & WB_DRAG )
+ mbDragable = TRUE;
+ else
+ mbDragable = FALSE;
+ if ( nWinStyle & WB_BUTTONSTYLE )
+ mbButtonStyle = TRUE;
+ else
+ mbButtonStyle = FALSE;
+ if ( nWinStyle & WB_BORDER )
+ {
+ mnBorderOff1 = 1;
+ mnBorderOff2 = 1;
+ }
+ else
+ {
+ if ( nWinStyle & WB_BOTTOMBORDER )
+ mnBorderOff2 = 1;
+ }
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBar::HeaderBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle & WB_3DLOOK )
+{
+ ImplInit( nWinStyle );
+ SetSizePixel( CalcWindowSizePixel() );
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBar::HeaderBar( Window* pParent, const ResId& rResId ) :
+ Window( pParent, rResId )
+{
+ ImplInit( rResId.aWinBits );
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBar::~HeaderBar()
+{
+ // Alle Items loeschen
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::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 );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long HeaderBar::ImplGetItemPos( USHORT nPos ) const
+{
+ long nX = -mnOffset;
+ for ( USHORT i = 0; i < nPos; i++ )
+ nX += mpItemList->GetObject( i )->mnSize;
+ return nX;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle HeaderBar::ImplGetItemRect( USHORT nPos ) const
+{
+ Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
+ aRect.Right() = aRect.Left() + mpItemList->GetObject( nPos )->mnSize - 1;
+ // Gegen Ueberlauf auf einigen Systemen testen
+ if ( aRect.Right() > 16000 )
+ aRect.Right() = 16000;
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::ImplHitTest( const Point& rPos,
+ long& nMouseOff, USHORT& nPos ) const
+{
+ ImplHeadItem* pItem;
+ USHORT nCount = (USHORT)mpItemList->Count();
+ BOOL bLastFixed = TRUE;
+ long nX = -mnOffset;
+
+ for ( USHORT i = 0; i < nCount; i++ )
+ {
+ pItem = mpItemList->GetObject( i );
+
+ if ( rPos.X() < (nX+pItem->mnSize) )
+ {
+ USHORT nMode;
+
+ if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
+ {
+ nMode = HEAD_HITTEST_DIVIDER;
+ nPos = i-1;
+ nMouseOff = rPos.X()-nX+1;
+ }
+ else
+ {
+ nPos = i;
+
+ if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) )
+ {
+ nMode = HEAD_HITTEST_DIVIDER;
+ nMouseOff = rPos.X()-(nX+pItem->mnSize);
+ }
+ else
+ {
+ nMode = HEAD_HITTEST_ITEM;
+ nMouseOff = rPos.X()-nX;
+ }
+ }
+
+ return nMode;
+ }
+
+ if ( pItem->mnBits & HIB_FIXED )
+ bLastFixed = TRUE;
+ else
+ bLastFixed = FALSE;
+
+ nX += pItem->mnSize;
+ }
+
+ if ( !bLastFixed )
+ {
+ pItem = mpItemList->GetObject( nCount-1 );
+ if ( (pItem->mnSize < 4) && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
+ {
+ nPos = nCount-1;
+ nMouseOff = rPos.X()-nX+1;
+ return HEAD_HITTEST_DIVIDER;
+ }
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplInvertDrag( USHORT nStartPos, USHORT nEndPos )
+{
+ Rectangle aRect1 = ImplGetItemRect( nStartPos );
+ Rectangle aRect2 = ImplGetItemRect( nEndPos );
+ Point aStartPos = aRect1.Center();
+ Point aEndPos = aStartPos;
+ Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
+ aStartPos.X()+2, aStartPos.Y()+2 );
+
+ if ( nEndPos > nStartPos )
+ {
+ aStartPos.X() += 3;
+ aEndPos.X() = aRect2.Right()-6;
+ }
+ else
+ {
+ aStartPos.X() -= 3;
+ aEndPos.X() = aRect2.Left()+6;
+ }
+
+ SetRasterOp( ROP_INVERT );
+ DrawRect( aStartRect );
+ DrawLine( aStartPos, aEndPos );
+ if ( nEndPos > nStartPos )
+ {
+ DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
+ Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
+ DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
+ Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
+ DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
+ Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
+ DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
+ }
+ else
+ {
+ DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
+ Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
+ DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
+ Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
+ DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
+ Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
+ DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
+ }
+ SetRasterOp( ROP_OVERPAINT );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplDrawItem( OutputDevice* pDev,
+ USHORT nPos, BOOL bHigh, BOOL bDrag,
+ const Rectangle& rItemRect,
+ const Rectangle* pRect,
+ ULONG nFlags )
+{
+ Rectangle aRect = rItemRect;
+
+ // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
+ if ( aRect.GetWidth() <= 1 )
+ return;
+
+ // Feststellen, ob Rectangle ueberhaupt sichtbar
+ if ( pRect )
+ {
+ if ( aRect.Right() < pRect->Left() )
+ return;
+ else if ( aRect.Left() > pRect->Right() )
+ return;
+ }
+ else
+ {
+ if ( aRect.Right() < 0 )
+ return;
+ else if ( aRect.Left() > mnDX )
+ return;
+ }
+
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ HeaderBarItemBits nBits = pItem->mnBits;
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ // Border muss nicht gemalt werden
+ aRect.Top() += mnBorderOff1;
+ aRect.Bottom() -= mnBorderOff2;
+
+ // Hintergrund loeschen
+ if ( !pRect || bDrag )
+ {
+ if ( bDrag )
+ {
+ pDev->SetLineColor();
+ pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
+ pDev->DrawRect( aRect );
+ }
+ else
+ pDev->DrawWallpaper( aRect, GetBackground() );
+ }
+
+ // Trennlinie malen
+ pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ pDev->DrawLine( Point( aRect.Right(), aRect.Top() ),
+ Point( aRect.Right(), aRect.Bottom() ) );
+
+ // ButtonStyle malen
+ if ( mbButtonStyle && !(nBits & HIB_FLAT) )
+ {
+ if ( aRect.GetWidth() >= 2 )
+ {
+ if ( bHigh )
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ else
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right()-1, aRect.Top() ) );
+ if ( !bHigh )
+ {
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( aRect.Right()-1, aRect.Top()+1 ),
+ Point( aRect.Right()-1, aRect.Bottom() ) );
+ pDev->DrawLine( Point( aRect.Left()+1, aRect.Bottom() ),
+ Point( aRect.Right()-1, aRect.Bottom() ) );
+ }
+ }
+
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+
+ // Wenn selektiert, verschiebt sich das Rechteck um 1 Pixel
+ if ( bHigh )
+ aRect.Move( 1, 1 );
+ }
+
+ // Wenn kein Platz, dann brauchen wir auch nichts ausgeben
+ if ( aRect.GetWidth() < 1 )
+ return;
+
+ // Positionen und Groessen berechnen und Inhalt ausgeben
+ pItem->maOutText = pItem->maText;
+ Size aImageSize = pItem->maImage.GetSizePixel();
+ Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0 );
+ if ( pItem->maOutText.Len() )
+ aTxtSize.Height() = pDev->GetTextHeight();
+ long nArrowWidth = 0;
+ if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
+ nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF;
+
+ // Wenn kein Platz fuer Image, dann nicht ausgeben
+ long nTestHeight = aImageSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTestHeight += aTxtSize.Height();
+ if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) )
+ {
+ aImageSize.Width() = 0;
+ aImageSize.Height() = 0;
+ }
+
+ // Text auf entsprechende Laenge kuerzen
+ BOOL bLeftText = FALSE;
+ long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth;
+ if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
+ nMaxTxtWidth -= aImageSize.Width();
+ long nTxtWidth = aTxtSize.Width();
+ if ( nTxtWidth > nMaxTxtWidth )
+ {
+ bLeftText = TRUE;
+ // 3 == Len of "..."
+ pItem->maOutText.AppendAscii( "..." );
+ do
+ {
+ pItem->maOutText.Erase( pItem->maOutText.Len()-3-1, 1 );
+ nTxtWidth = pDev->GetTextWidth( pItem->maOutText );
+ }
+ while ( (nTxtWidth > nMaxTxtWidth) && (pItem->maOutText.Len() > 3) );
+ if ( pItem->maOutText.Len() == 3 )
+ {
+ nTxtWidth = 0;
+ pItem->maOutText.Erase();
+ }
+ }
+
+ // Text/Imageposition berechnen
+ long nTxtPos;
+ if ( !bLeftText && (nBits & HIB_RIGHT) )
+ {
+ nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF;
+ if ( nBits & HIB_RIGHTIMAGE )
+ nTxtPos -= aImageSize.Width();
+ }
+ else if ( !bLeftText && (nBits & HIB_CENTER) )
+ {
+ long nTempWidth = nTxtWidth;
+ if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
+ nTempWidth += aImageSize.Width();
+ nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2;
+ if ( nBits & HIB_LEFTIMAGE )
+ nTxtPos += aImageSize.Width();
+ if ( nArrowWidth )
+ {
+ if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() )
+ {
+ nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
+ if ( nBits & HIB_LEFTIMAGE )
+ nTxtPos += aImageSize.Width();
+ }
+ }
+ }
+ else
+ {
+ nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
+ if ( nBits & HIB_LEFTIMAGE )
+ nTxtPos += aImageSize.Width();
+ if ( nBits & HIB_RIGHT )
+ nTxtPos += nArrowWidth;
+ }
+
+ // TextPosition berechnen
+ long nTxtPosY;
+ if ( pItem->maOutText.Len() || (nArrowWidth && aTxtSize.Height()) )
+ {
+ if ( nBits & HIB_TOP )
+ {
+ nTxtPosY = aRect.Top();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTxtPosY += aImageSize.Height();
+ }
+ else if ( nBits & HIB_BOTTOM )
+ nTxtPosY = aRect.Bottom()-aTxtSize.Height();
+ else
+ {
+ long nTempHeight = aTxtSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTempHeight += aImageSize.Height();
+ nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTxtPosY += aImageSize.Height();
+ }
+ }
+
+ // Text ausgebeben
+ if ( pItem->maOutText.Len() )
+ {
+ if ( IsEnabled() )
+ pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText );
+ else
+ pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, STRING_LEN, TEXT_DRAW_DISABLE );
+ }
+
+ // Wenn Image vorhanden, Position berechnen und ausgeben
+ long nImagePosY;
+ if ( aImageSize.Width() && aImageSize.Height() )
+ {
+ long nImagePos = nTxtPos;
+ if ( nBits & HIB_LEFTIMAGE )
+ {
+ nImagePos -= aImageSize.Width();
+ if ( nBits & HIB_RIGHT )
+ nImagePos -= nArrowWidth;
+ }
+ else if ( nBits & HIB_RIGHTIMAGE )
+ {
+ nImagePos += nTxtWidth;
+ if ( !(nBits & HIB_RIGHT) )
+ nImagePos += nArrowWidth;
+ }
+ else
+ {
+ if ( nBits & HIB_RIGHT )
+ nImagePos = aRect.Right()-aImageSize.Width();
+ else if ( nBits & HIB_CENTER )
+ nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2;
+ else
+ nImagePos = aRect.Left()+HEADERBAR_TEXTOFF;
+ }
+
+ if ( nBits & HIB_TOP )
+ nImagePosY = aRect.Top();
+ else if ( nBits & HIB_BOTTOM )
+ {
+ nImagePosY = aRect.Bottom()-aImageSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nImagePosY -= aTxtSize.Height();
+ }
+ else
+ {
+ long nTempHeight = aImageSize.Height();
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
+ nTempHeight += aTxtSize.Height();
+ nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
+ }
+ if ( nImagePos+aImageSize.Width() <= aRect.Right() )
+ {
+ USHORT nStyle = 0;
+ if ( !IsEnabled() )
+ nStyle |= IMAGE_DRAW_DISABLE;
+ pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle );
+ }
+ }
+
+ if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
+ {
+ long nArrowX = nTxtPos;
+ if ( nBits & HIB_RIGHT )
+ nArrowX -= nArrowWidth;
+ else
+ nArrowX += nTxtWidth+HEADERBAR_ARROWOFF;
+ if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.Len() )
+ {
+ if ( nBits & HIB_RIGHT )
+ nArrowX -= aImageSize.Width();
+ else
+ nArrowX += aImageSize.Width();
+ }
+
+ // Feststellen, ob Platz genug ist, das Item zu malen
+ BOOL bDraw = TRUE;
+ if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF )
+ bDraw = FALSE;
+ else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() )
+ bDraw = FALSE;
+
+ if ( bDraw )
+ {
+ long nArrowY;
+ if ( aTxtSize.Height() )
+ nArrowY = nTxtPosY+(aTxtSize.Height()/2);
+ else if ( aImageSize.Width() && aImageSize.Height() )
+ nArrowY = nImagePosY+(aImageSize.Height()/2);
+ else
+ {
+ if ( nBits & HIB_TOP )
+ nArrowY = aRect.Top()+1;
+ else if ( nBits & HIB_BOTTOM )
+ nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1;
+ else
+ nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);;
+ }
+ nArrowY -= HEAD_ARROWSIZE1-1;
+ if ( nBits & HIB_DOWNARROW )
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( nArrowX, nArrowY ),
+ Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
+ pDev->DrawLine( Point( nArrowX, nArrowY ),
+ Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
+ }
+ else
+ {
+ pDev->SetLineColor( rStyleSettings.GetLightColor() );
+ pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
+ pDev->SetLineColor( rStyleSettings.GetShadowColor() );
+ pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) );
+ pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ),
+ Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
+ }
+ }
+ }
+
+ // Gegebenenfalls auch UserDraw aufrufen
+ if ( nBits & HIB_USERDRAW )
+ {
+ Region aRegion( aRect );
+ if ( pRect )
+ aRegion.Intersect( *pRect );
+ pDev->SetClipRegion( aRegion );
+ UserDrawEvent aODEvt( pDev, aRect, pItem->mnId );
+ UserDraw( aODEvt );
+ pDev->SetClipRegion();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplDrawItem( USHORT nPos, BOOL bHigh, BOOL bDrag,
+ const Rectangle* pRect )
+{
+ Rectangle aRect = ImplGetItemRect( nPos );
+ ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplUpdate( USHORT nPos, BOOL bEnd, BOOL bDirect )
+{
+ if ( IsVisible() && IsUpdateMode() )
+ {
+ if ( !bDirect )
+ {
+ Rectangle aRect;
+ USHORT nItemCount = (USHORT)(mpItemList->Count());
+ if ( nPos < nItemCount )
+ aRect = ImplGetItemRect( nPos );
+ else
+ {
+ aRect.Bottom() = mnDY-1;
+ if ( nItemCount )
+ aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right();
+ }
+ if ( bEnd )
+ aRect.Right() = mnDX-1;
+ aRect.Top() += mnBorderOff1;
+ aRect.Bottom() -= mnBorderOff2;
+ Invalidate( aRect );
+ }
+ else
+ {
+ for ( USHORT i = nPos; i < mpItemList->Count(); i++ )
+ ImplDrawItem( i );
+ if ( bEnd )
+ {
+ Rectangle aRect = ImplGetItemRect( (USHORT)mpItemList->Count() );
+ aRect.Left() = aRect.Right();
+ aRect.Right() = mnDX-1;
+ if ( aRect.Left() < aRect.Right() )
+ {
+ aRect.Top() += mnBorderOff1;
+ aRect.Bottom() -= mnBorderOff2;
+ Erase( aRect );
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplStartDrag( const Point& rMousePos, BOOL bCommand )
+{
+ USHORT nPos;
+ USHORT nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
+ if ( nHitTest )
+ {
+ mbDrag = FALSE;
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( nHitTest & HEAD_HITTEST_DIVIDER )
+ mbDrag = TRUE;
+ else
+ {
+ if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) ||
+ (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) )
+ {
+ mbItemMode = TRUE;
+ mbDrag = TRUE;
+ if ( bCommand )
+ {
+ if ( mbDragable )
+ mbItemDrag = TRUE;
+ else
+ {
+ mbItemMode = FALSE;
+ mbDrag = FALSE;
+ }
+ }
+ }
+ else
+ {
+ if ( !bCommand )
+ {
+ mnCurItemId = pItem->mnId;
+ Select();
+ mnCurItemId = 0;
+ }
+ }
+ }
+
+ if ( mbDrag )
+ {
+ mbOutDrag = FALSE;
+ mnCurItemId = pItem->mnId;
+ mnItemDragPos = nPos;
+ StartTracking();
+ mnStartPos = rMousePos.X()-mnMouseOff;
+ mnDragPos = mnStartPos;
+ StartDrag();
+ if ( mbItemMode )
+ ImplDrawItem( nPos, TRUE, mbItemDrag );
+ else
+ {
+ Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
+ ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
+ }
+ }
+ else
+ mnMouseOff = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplDrag( const Point& rMousePos )
+{
+ BOOL bNewOutDrag;
+ USHORT nPos = GetItemPos( mnCurItemId );
+
+ mnDragPos = rMousePos.X()-mnMouseOff;
+ if ( mbItemMode )
+ {
+ Rectangle aItemRect = ImplGetItemRect( nPos );
+ if ( aItemRect.IsInside( rMousePos ) )
+ bNewOutDrag = FALSE;
+ else
+ bNewOutDrag = TRUE;
+
+ // Evt. ItemDrag anschalten
+ if ( bNewOutDrag && mbDragable && !mbItemDrag &&
+ !(mpItemList->GetObject(nPos)->mnBits & HIB_FIXEDPOS) )
+ {
+ if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
+ {
+ mbItemDrag = TRUE;
+ ImplDrawItem( nPos, TRUE, mbItemDrag );
+ }
+ }
+
+ USHORT nOldItemDragPos = mnItemDragPos;
+ if ( mbItemDrag )
+ {
+ if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) )
+ bNewOutDrag = TRUE;
+ else
+ bNewOutDrag = FALSE;
+
+ if ( bNewOutDrag )
+ mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
+ else
+ {
+ USHORT nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
+ if ( nTempId )
+ mnItemDragPos = GetItemPos( nTempId );
+ else
+ {
+ if ( rMousePos.X() <= 0 )
+ mnItemDragPos = 0;
+ else
+ mnItemDragPos = GetItemCount()-1;
+ }
+
+ // Nicht verschiebbare Items aussparen
+ if ( mnItemDragPos < nPos )
+ {
+ while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
+ (mnItemDragPos < nPos) )
+ mnItemDragPos++;
+ }
+ else if ( mnItemDragPos > nPos )
+ {
+ while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
+ (mnItemDragPos > nPos) )
+ mnItemDragPos--;
+ }
+ }
+
+ if ( (mnItemDragPos != nOldItemDragPos) &&
+ (nOldItemDragPos != nPos) &&
+ (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
+ {
+ ImplInvertDrag( nPos, nOldItemDragPos );
+ ImplDrawItem( nOldItemDragPos );
+ }
+ }
+
+ if ( bNewOutDrag != mbOutDrag )
+ ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag );
+
+ if ( mbItemDrag )
+ {
+ if ( (mnItemDragPos != nOldItemDragPos) &&
+ (mnItemDragPos != nPos) &&
+ (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
+ {
+ ImplDrawItem( mnItemDragPos, FALSE, TRUE );
+ ImplInvertDrag( nPos, mnItemDragPos );
+ }
+ }
+
+ mbOutDrag = bNewOutDrag;
+ }
+ else
+ {
+ Rectangle aItemRect = ImplGetItemRect( nPos );
+ if ( mnDragPos < aItemRect.Left() )
+ mnDragPos = aItemRect.Left();
+ if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
+ HideTracking();
+ else
+ {
+ Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
+ ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
+ }
+ }
+
+ Drag();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::ImplEndDrag( BOOL bCancel )
+{
+ HideTracking();
+
+ if ( bCancel || mbOutDrag )
+ {
+ if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
+ {
+ USHORT nPos = GetItemPos( mnCurItemId );
+ ImplDrawItem( nPos );
+ }
+
+ mnCurItemId = 0;
+ }
+ else
+ {
+ USHORT nPos = GetItemPos( mnCurItemId );
+ if ( mbItemMode )
+ {
+ if ( mbItemDrag )
+ {
+ Pointer aPointer( POINTER_ARROW );
+ SetPointer( aPointer );
+ if ( (mnItemDragPos != nPos) &&
+ (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
+ {
+ ImplInvertDrag( nPos, mnItemDragPos );
+ MoveItem( mnCurItemId, mnItemDragPos );
+ }
+ else
+ ImplDrawItem( nPos );
+ }
+ else
+ {
+ Select();
+ ImplUpdate( nPos );
+ }
+ }
+ else
+ {
+ long nDelta = mnDragPos - mnStartPos;
+ if ( nDelta )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ pItem->mnSize += nDelta;
+ ImplUpdate( nPos, TRUE );
+ }
+ }
+ }
+
+ mbDrag = FALSE;
+ EndDrag();
+ mnCurItemId = 0;
+ mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
+ mbOutDrag = FALSE;
+ mbItemMode = FALSE;
+ mbItemDrag = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ long nTemp;
+ USHORT nPos;
+ USHORT nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
+ if ( nHitTest )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( nHitTest & HEAD_HITTEST_DIVIDER )
+ mbItemMode = FALSE;
+ else
+ mbItemMode = TRUE;
+ mnCurItemId = pItem->mnId;
+ DoubleClick();
+ mbItemMode = FALSE;
+ mnCurItemId = 0;
+ }
+ }
+ else
+ ImplStartDrag( rMEvt.GetPosPixel(), FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::MouseMove( const MouseEvent& rMEvt )
+{
+ long nTemp1;
+ USHORT nTemp2;
+ PointerStyle eStyle = POINTER_ARROW;
+ USHORT nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );
+
+ if ( nHitTest & HEAD_HITTEST_DIVIDER )
+ eStyle = POINTER_HSIZEBAR;
+ Pointer aPtr( eStyle );
+ SetPointer( aPtr );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( rTEvt.IsTrackingEnded() )
+ ImplEndDrag( rTEvt.IsTrackingCanceled() );
+ else
+ ImplDrag( aMousePos );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Paint( const Rectangle& rRect )
+{
+ if ( mnBorderOff1 || mnBorderOff2 )
+ {
+ SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
+ if ( mnBorderOff1 )
+ DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
+ if ( mnBorderOff2 )
+ DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
+ }
+
+ USHORT nCurItemPos;
+ if ( mbDrag )
+ nCurItemPos = GetItemPos( mnCurItemId );
+ else
+ nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ ImplDrawItem( i, (i == nCurItemPos) ? TRUE : FALSE, FALSE, &rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
+ ULONG nFlags )
+{
+ Point aPos = pDev->LogicToPixel( rPos );
+ Size aSize = pDev->LogicToPixel( rSize );
+ Rectangle aRect( aPos, aSize );
+ Font aFont = GetDrawPixelFont( pDev );
+
+ pDev->Push();
+ pDev->SetMapMode();
+ pDev->SetFont( aFont );
+ if ( nFlags & WINDOW_DRAW_MONO )
+ pDev->SetTextColor( Color( COL_BLACK ) );
+ else
+ pDev->SetTextColor( GetTextColor() );
+ pDev->SetTextFillColor();
+
+ if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) )
+ {
+ pDev->DrawWallpaper( aRect, GetBackground() );
+ if ( mnBorderOff1 || mnBorderOff2 )
+ {
+ pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
+ if ( mnBorderOff1 )
+ pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
+ if ( mnBorderOff2 )
+ pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
+ }
+ }
+
+ Rectangle aItemRect( aRect );
+// aItemRect.Bottom()--;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ for ( USHORT i = 0; i < nItemCount; i++ )
+ {
+ aItemRect.Left() = aRect.Left()+ImplGetItemPos( i );
+ aItemRect.Right() = aItemRect.Left() + mpItemList->GetObject( i )->mnSize - 1;
+ // Gegen Ueberlauf auf einigen Systemen testen
+ if ( aItemRect.Right() > 16000 )
+ aItemRect.Right() = 16000;
+ Region aRegion( aRect );
+ pDev->SetClipRegion( aRegion );
+ ImplDrawItem( pDev, i, FALSE, FALSE, aItemRect, &aRect, nFlags );
+ pDev->SetClipRegion();
+ }
+
+ pDev->Pop();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Resize()
+{
+ Size aSize = GetOutputSizePixel();
+ if ( IsVisible() && (mnDY != aSize.Height()) )
+ Invalidate();
+ mnDX = aSize.Width();
+ mnDY = aSize.Height();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag )
+ {
+ ImplStartDrag( rCEvt.GetMousePosPixel(), TRUE );
+ return;
+ }
+
+ Window::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ Rectangle aItemRect = GetItemRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+
+ XubString aStr = GetHelpText( nItemId );
+ if ( !aStr.Len() || !(rHEvt.GetMode() & HELPMODE_BALLOON) )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( GetItemPos( nItemId ) );
+ // Wir zeigen die Quick-Hilfe nur an, wenn Text nicht
+ // vollstaendig sichtbar, ansonsten zeigen wir den Hilfetext
+ // an, wenn das Item keinen Text besitzt
+ if ( pItem->maOutText != pItem->maText )
+ aStr = pItem->maText;
+ else if ( pItem->maText.Len() )
+ aStr.Erase();
+ }
+
+ if ( aStr.Len() )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ return;
+ }
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId );
+ return;
+ }
+ }
+ }
+
+ Window::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_ENABLE )
+ Invalidate();
+ 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 HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::StartDrag()
+{
+ maStartDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Drag()
+{
+ maDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::EndDrag()
+{
+ maEndDragHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::InsertItem( USHORT nItemId, const Image& rImage,
+ long nSize, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
+ "HeaderBar::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplHeadItem* pItem = new ImplHeadItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnSize = nSize;
+ pItem->maImage = rImage;
+ pItem->mpUserData = 0;
+ mpItemList->Insert( pItem, nPos );
+
+ // Ausgabe updaten
+ ImplUpdate( nPos, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::InsertItem( USHORT nItemId, const XubString& rText,
+ long nSize, HeaderBarItemBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
+ "HeaderBar::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplHeadItem* pItem = new ImplHeadItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnSize = nSize;
+ pItem->mnHelpId = 0;
+ pItem->maText = rText;
+ pItem->mpUserData = 0;
+ mpItemList->Insert( pItem, nPos );
+
+ // Ausgabe updaten
+ ImplUpdate( nPos, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::InsertItem( USHORT nItemId,
+ const Image& rImage, const XubString& rText,
+ long nSize, HeaderBarItemBits nBits,
+ USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
+ "HeaderBar::InsertItem(): ItemId already exists" );
+
+ // Item anlegen und in die Liste einfuegen
+ ImplHeadItem* pItem = new ImplHeadItem;
+ pItem->mnId = nItemId;
+ pItem->mnBits = nBits;
+ pItem->mnSize = nSize;
+ pItem->mnHelpId = 0;
+ pItem->maImage = rImage;
+ pItem->maText = rText;
+ pItem->mpUserData = 0;
+ mpItemList->Insert( pItem, nPos );
+
+ // Ausgabe updaten
+ ImplUpdate( nPos, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::RemoveItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->Remove( nPos );
+ delete pItem;
+ ImplUpdate( nPos, TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::MoveItem( USHORT nItemId, USHORT nNewPos )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ if ( nPos != nNewPos )
+ {
+ ImplHeadItem* pItem = mpItemList->Remove( nPos );
+ if ( nNewPos < nPos )
+ nPos = nNewPos;
+ mpItemList->Insert( pItem, nNewPos );
+ ImplUpdate( nPos, TRUE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::Clear()
+{
+ // Alle Items loeschen
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+ mpItemList->Clear();
+
+ ImplUpdate( 0, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetOffset( long nNewOffset )
+{
+ // Hier erstmal neu zeichnen, damit mit alten Offset noch das
+ // richtige gemalt wird
+ //Update();
+
+ // Bereich verschieben
+ Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
+ long nDelta = mnOffset-nNewOffset;
+ mnOffset = nNewOffset;
+ Scroll( nDelta, 0, aRect );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemPos( USHORT nItemId ) const
+{
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return (USHORT)mpItemList->GetCurPos();
+ pItem = mpItemList->Next();
+ }
+
+ return HEADERBAR_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemId( USHORT nPos ) const
+{
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT HeaderBar::GetItemId( const Point& rPos ) const
+{
+ USHORT nPos = 0;
+ while ( nPos < mpItemList->Count() )
+ {
+ if ( ImplGetItemRect( nPos ).IsInside( rPos ) )
+ return GetItemId( nPos );
+
+ nPos++;
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle HeaderBar::GetItemRect( USHORT nItemId ) const
+{
+ Rectangle aRect;
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ aRect = ImplGetItemRect( nPos );
+ return aRect;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemSize( USHORT nItemId, long nNewSize )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mnSize != nNewSize )
+ {
+ pItem->mnSize = nNewSize;
+ ImplUpdate( nPos, TRUE );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+long HeaderBar::GetItemSize( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnSize;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemBits( USHORT nItemId, HeaderBarItemBits nNewBits )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mnBits != nNewBits )
+ {
+ pItem->mnBits = nNewBits;
+ ImplUpdate( nPos );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+HeaderBarItemBits HeaderBar::GetItemBits( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemData( USHORT nItemId, void* pNewData )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->mpUserData = pNewData;
+ ImplUpdate( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* HeaderBar::GetItemData( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mpUserData;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemImage( USHORT nItemId, const Image& rImage )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->maImage = rImage;
+ ImplUpdate( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Image HeaderBar::GetItemImage( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maImage;
+ else
+ return Image();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetItemText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->maText = rText;
+ ImplUpdate( nPos );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString HeaderBar::GetItemText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maText;
+ else
+ return String();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetHelpText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+XubString HeaderBar::GetHelpText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ {
+ ImplHeadItem* pItem = mpItemList->GetObject( nPos );
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void HeaderBar::SetHelpId( USHORT nItemId, ULONG nHelpId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG HeaderBar::GetHelpId( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+ if ( nPos != HEADERBAR_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnHelpId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Size HeaderBar::CalcWindowSizePixel() const
+{
+ long nMaxImageSize = 0;
+ Size aSize( 0, GetTextHeight() );
+
+ ImplHeadItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Image-Groessen beruecksichtigen
+ long nImageHeight = pItem->maImage.GetSizePixel().Height();
+ if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.Len() )
+ nImageHeight += aSize.Height();
+ if ( nImageHeight > nMaxImageSize )
+ nMaxImageSize = nImageHeight;
+
+ // Breite aufaddieren
+ aSize.Width() += pItem->mnSize;
+
+ pItem = mpItemList->Next();
+ }
+
+ if ( nMaxImageSize > aSize.Height() )
+ aSize.Height() = nMaxImageSize;
+
+ // Border aufaddieren
+ if ( mbButtonStyle )
+ aSize.Height() += 4;
+ else
+ aSize.Height() += 2;
+ aSize.Height() += mnBorderOff1+mnBorderOff2;
+
+ return aSize;
+}
diff --git a/svtools/source/control/makefile.mk b/svtools/source/control/makefile.mk
new file mode 100644
index 000000000000..f3f0e97e9b47
--- /dev/null
+++ b/svtools/source/control/makefile.mk
@@ -0,0 +1,141 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,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): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=SVTOOLS
+TARGET=ctrl
+TARGETSTAT=_ctrl
+LIBTARGET=NO
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= ctrltool.cxx \
+ ctrlbox.cxx \
+ stdctrl.cxx \
+ stdmenu.cxx \
+ valueset.cxx \
+ tabbar.cxx \
+ headbar.cxx \
+ prgsbar.cxx \
+ ruler.cxx \
+ taskbar.cxx \
+ taskbox.cxx \
+ taskstat.cxx \
+ taskmisc.cxx \
+ calendar.cxx \
+ filectrl.cxx \
+ scrwin.cxx \
+ reginfo.cxx \
+ groupset.cxx \
+ fmtfield.cxx
+
+.IF "$(GUI)"!="DOS"
+SRCFILES= ctrltool.src \
+ ctrlbox.src \
+ calendar.src \
+ filectrl.src
+.ENDIF
+
+SLOFILES= $(SLO)$/ctrltool.obj \
+ $(SLO)$/ctrlbox.obj \
+ $(SLO)$/stdctrl.obj \
+ $(SLO)$/stdmenu.obj \
+ $(SLO)$/valueset.obj \
+ $(SLO)$/tabbar.obj \
+ $(SLO)$/headbar.obj \
+ $(SLO)$/prgsbar.obj \
+ $(SLO)$/ruler.obj \
+ $(SLO)$/taskbar.obj \
+ $(SLO)$/taskbox.obj \
+ $(SLO)$/taskstat.obj \
+ $(SLO)$/taskmisc.obj \
+ $(SLO)$/calendar.obj \
+ $(SLO)$/filectrl.obj \
+ $(SLO)$/scrwin.obj \
+ $(SLO)$/reginfo.obj \
+ $(SLO)$/groupset.obj \
+ $(SLO)$/fmtfield.obj
+
+# statisch fuer setup
+
+OBJFILES= $(OBJ)$/prgsbar.obj \
+ $(OBJ)$/stdctrl.obj \
+ $(OBJ)$/reginfo.obj \
+ $(OBJ)$/tabbar.obj
+
+
+LIB1TARGET= $(SLB)$/$(TARGET).lib
+LIB1OBJFILES= $(SLOFILES)
+
+LIB2TARGET= $(LB)$/$(TARGETSTAT).lib
+LIB2OBJFILES= $(OBJFILES)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/control/prgsbar.cxx b/svtools/source/control/prgsbar.cxx
new file mode 100644
index 000000000000..e370d9d87c22
--- /dev/null
+++ b/svtools/source/control/prgsbar.cxx
@@ -0,0 +1,270 @@
+/*************************************************************************
+ *
+ * $RCSfile: prgsbar.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SV_PRGSBAR_CXX
+
+#ifndef _TOOLS_DEBUGS_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _VCL_STATUS_HXX
+#include <vcl/status.hxx>
+#endif
+#ifndef _PRGSBAR_HXX
+#include <prgsbar.hxx>
+#endif
+
+// =======================================================================
+
+#define PROGRESSBAR_OFFSET 3
+#define PROGRESSBAR_WIN_OFFSET 2
+
+// =======================================================================
+
+void ProgressBar::ImplInit()
+{
+ mnPercent = 0;
+ mbCalcNew = TRUE;
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+ProgressBar::ProgressBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle )
+{
+ SetOutputSizePixel( Size( 150, 20 ) );
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ProgressBar::ProgressBar( Window* pParent, const ResId& rResId ) :
+ Window( pParent, rResId )
+{
+ ImplInit();
+}
+
+// -----------------------------------------------------------------------
+
+ProgressBar::~ProgressBar()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+/* !!! Derzeit unterstuetzen wir keine Textausgaben
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetAppFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ SetZoomedPointFont( aFont );
+ }
+*/
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+
+ if ( bForeground || bFont )
+ {
+ Color aColor = rStyleSettings.GetHighlightColor();
+ if ( IsControlForeground() )
+ aColor = GetControlForeground();
+ if ( aColor.IsRGBEqual( GetBackground().GetColor() ) )
+ {
+ if ( aColor.GetLuminance() > 100 )
+ aColor.DecreaseLuminance( 64 );
+ else
+ aColor.IncreaseLuminance( 64 );
+ }
+ SetLineColor();
+ SetFillColor( aColor );
+/* !!! Derzeit unterstuetzen wir keine Textausgaben
+ SetTextColor( aColor );
+ SetTextFillColor();
+*/
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::ImplDrawProgress( USHORT nOldPerc, USHORT nNewPerc )
+{
+ if ( mbCalcNew )
+ {
+ mbCalcNew = FALSE;
+
+ Size aSize = GetOutputSizePixel();
+ mnPrgsHeight = aSize.Height()-(PROGRESSBAR_WIN_OFFSET*2);
+ mnPrgsWidth = (mnPrgsHeight*2)/3;
+ maPos.Y() = PROGRESSBAR_WIN_OFFSET;
+ long nMaxWidth = (aSize.Width()-(PROGRESSBAR_WIN_OFFSET*2)+PROGRESSBAR_OFFSET);
+ USHORT nMaxCount = (USHORT)(nMaxWidth / (mnPrgsWidth+PROGRESSBAR_OFFSET));
+ if ( nMaxCount <= 1 )
+ nMaxCount = 1;
+ else
+ {
+ while ( ((10000/(10000/nMaxCount))*(mnPrgsWidth+PROGRESSBAR_OFFSET)) > nMaxWidth )
+ nMaxCount--;
+ }
+ mnPercentCount = 10000/nMaxCount;
+ nMaxWidth = ((10000/(10000/nMaxCount))*(mnPrgsWidth+PROGRESSBAR_OFFSET))-PROGRESSBAR_OFFSET;
+ maPos.X() = (aSize.Width()-nMaxWidth)/2;
+ }
+
+ ::DrawProgress( this, maPos, PROGRESSBAR_OFFSET, mnPrgsWidth, mnPrgsHeight,
+ nOldPerc*100, nNewPerc*100, mnPercentCount );
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::Paint( const Rectangle& )
+{
+ ImplDrawProgress( 0, mnPercent );
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::Resize()
+{
+ mbCalcNew = TRUE;
+ if ( IsReallyVisible() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::SetValue( USHORT nNewPercent )
+{
+ DBG_ASSERTWARNING( nNewPercent <= 100, "StatusBar::SetProgressValue(): nPercent > 100" );
+
+ if ( nNewPercent < mnPercent )
+ {
+ mbCalcNew = TRUE;
+ mnPercent = nNewPercent;
+ if ( IsReallyVisible() )
+ {
+ Invalidate();
+ Update();
+ }
+ }
+ else
+ {
+ ImplDrawProgress( mnPercent, nNewPercent );
+ mnPercent = nNewPercent;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::StateChanged( StateChangedType nType )
+{
+/* !!! Derzeit unterstuetzen wir keine Textausgaben
+ 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();
+ }
+
+ Window::StateChanged( nType );
+}
+
+// -----------------------------------------------------------------------
+
+void ProgressBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ ImplInitSettings( TRUE, TRUE, TRUE );
+ Invalidate();
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
diff --git a/svtools/source/control/reginfo.cxx b/svtools/source/control/reginfo.cxx
new file mode 100644
index 000000000000..40c76ca1f9fe
--- /dev/null
+++ b/svtools/source/control/reginfo.cxx
@@ -0,0 +1,785 @@
+/*************************************************************************
+ *
+ * $RCSfile: reginfo.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifdef MAC
+#include "mac_start.h"
+
+#ifndef __TYPES__
+ #include <Types.h>
+#endif
+
+#ifndef __RESOURCES__
+ #include <Resources.h>
+#endif
+
+#ifndef __FILES__
+ #include <Files.h>
+#endif
+
+#ifndef __ERRORS__
+ #include <Errors.h>
+#endif
+
+#ifndef __FOLDERS__
+ #include <Folders.h>
+#endif
+
+#ifndef __SCRIPT__
+ #include <script.h>
+#endif
+
+#ifndef __FINDER__
+ #include <finder.h>
+#endif
+#include "mac_end.h"
+#endif
+
+#include "reginfo.hxx"
+
+#ifndef _DEBUG_HXX //autogen
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _OSL_THREAD_H_
+#include <osl/thread.h>
+#endif
+
+String aEmptyString;
+
+#define MAXREGVALUE 200
+
+#if defined(WIN) || defined(WNT)
+
+#include <tools/svwin.h>
+
+#define DBG_HDL DBG_ASSERT(pImp->bValidGroup, "Keine Gruppe gesetzt"); \
+ if( !pImp->bValidGroup ) return
+
+struct RegInfo_Impl
+{
+ HKEY aGroupHdl;
+ BOOL bValidGroup;
+};
+
+RegInfo::RegInfo()
+{
+ pImp=new RegInfo_Impl;
+ pImp->bValidGroup = FALSE;
+}
+
+RegInfo::~RegInfo()
+{
+ if(pImp->bValidGroup)
+ RegCloseKey( pImp->aGroupHdl );
+ delete pImp;
+}
+
+String RegInfo::GetKeyName( USHORT nKey ) const
+{
+ DBG_HDL aEmptyString;
+ char aBuffer[MAXREGVALUE];
+ RegEnumKey( pImp->aGroupHdl, nKey, aBuffer, MAXREGVALUE );
+ return String( UniString::CreateFromAscii(aBuffer) );
+}
+
+USHORT RegInfo::GetKeyCount() const
+{
+ DBG_HDL 0;
+#ifdef WNT
+ DWORD nKeys;
+ DWORD Dum1=10, Dum2, Dum3, Dum4, Dum5, Dum6, Dum7;
+ char s[10];
+ FILETIME aDumFileTime;
+ RegQueryInfoKey( pImp->aGroupHdl, s, &Dum1, 0, &nKeys, &Dum2, &Dum3,
+ &Dum4, &Dum5, &Dum6, &Dum7, &aDumFileTime );
+ return (USHORT) nKeys;
+#else
+ char aBuffer[MAXREGVALUE];
+ USHORT n=0;
+ while(RegEnumKey(
+ pImp->aGroupHdl, n, aBuffer, MAXREGVALUE) == ERROR_SUCCESS)
+ n++;
+ return n;
+#endif
+}
+
+inline String MakeAppGroupString_Impl( const String &rGroup )
+{
+ String aGroup( UniString::CreateFromAscii("SvAppGroups\\") );
+ aGroup+=rGroup;
+ return aGroup;
+}
+
+void RegInfo::SetAppGroup( const String& rGroup )
+{
+ aCurrentGroup = MakeAppGroupString_Impl(rGroup);
+ if( pImp->bValidGroup )
+ {
+ RegCloseKey( pImp->aGroupHdl );
+ pImp->bValidGroup = FALSE;
+ }
+ ByteString aBStr( aCurrentGroup, osl_getThreadTextEncoding() );
+ RegCreateKey( HKEY_CLASSES_ROOT, aBStr.GetBuffer(), &pImp->aGroupHdl );
+ pImp->bValidGroup = TRUE;
+}
+
+void RegInfo::DeleteAppGroup( const String &rGroup )
+{
+ String aOldGroup = aCurrentGroup;
+ SetAppGroup( rGroup );
+ DBG_HDL;
+ USHORT nMax = GetKeyCount();
+ for( USHORT n = nMax; n--; )
+ {
+ String aKey( GetKeyName( n ));
+ DeleteKey( aKey );
+ }
+ RegCloseKey( pImp->aGroupHdl );
+
+ ByteString aBStr( rGroup, osl_getThreadTextEncoding() );
+ RegDeleteKey( HKEY_CLASSES_ROOT, aBStr.GetBuffer() );
+ pImp->bValidGroup = FALSE;
+ if( rGroup != aOldGroup )
+ SetAppGroup( aOldGroup );
+}
+
+BOOL ReadKey_Impl( const String& rKey,
+ HKEY aHdl, String& rResult )
+{
+ char s[MAXREGVALUE];
+ LONG aLen=MAXREGVALUE;
+
+ ByteString aBStr( rKey, osl_getThreadTextEncoding() );
+ LONG nRes = RegQueryValue( aHdl, aBStr.GetBuffer(), s, &aLen);
+ if(nRes == ERROR_SUCCESS)
+ {
+ rResult = UniString::CreateFromAscii(s);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+String RegInfo::ReadKey( const String& rKey ) const
+{
+ DBG_HDL aEmptyString;
+ String aRes;
+ if(ReadKey_Impl( rKey, pImp->aGroupHdl, aRes))
+ return aRes;
+ else
+ return aEmptyString;
+}
+
+String RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
+{
+ DBG_HDL aEmptyString;
+ String aRes;
+ if(ReadKey_Impl( rKey, pImp->aGroupHdl, aRes))
+ return aRes;
+ else
+ return rDefault;
+}
+
+void RegInfo::WriteKey( const String& rKey, const String& rValue )
+{
+ DBG_HDL;
+ ByteString aBStr( rKey, osl_getThreadTextEncoding() );
+ ByteString aBStr1( rValue, osl_getThreadTextEncoding() );
+ RegSetValue( pImp->aGroupHdl, aBStr.GetBuffer(), REG_SZ, aBStr1.GetBuffer(), 0);
+}
+
+
+void RegInfo::DeleteKey( const String& rKey )
+{
+ DBG_HDL;
+ ByteString aBStr( rKey, osl_getThreadTextEncoding() );
+ RegDeleteKey( pImp->aGroupHdl, aBStr.GetBuffer() );
+}
+
+#elif defined(OS2)
+
+#define INCL_WINSHELLDATA
+#include <tools/svpm.h>
+
+struct RegInfo_Impl
+{
+ char *pKeyList;
+ String aCurrentApp;
+ void BuildKeyList( const String &rGroup );
+};
+
+void RegInfo_Impl::BuildKeyList( const String &rGroup )
+{
+ USHORT nLen = 0;
+ do
+ {
+ nLen+=1000;
+ delete[] pKeyList;
+ pKeyList = new char[nLen];
+ *(int *)pKeyList = 0;
+ }
+ while( PrfQueryProfileString(
+ HINI_USERPROFILE, rGroup,
+ 0, 0, pKeyList, nLen) == nLen);
+}
+
+
+RegInfo::RegInfo()
+{
+ pImp=new RegInfo_Impl;
+ pImp->pKeyList = 0;
+}
+
+RegInfo::~RegInfo()
+{
+ delete[] pImp->pKeyList;
+ delete pImp;
+}
+
+inline String MakeAppGroupString_Impl( const String &rGroup )
+{
+ String aGroup("SvAppGroups:");
+ aGroup+=rGroup;
+ return aGroup;
+}
+
+String RegInfo::GetKeyName( USHORT nKey ) const
+{
+ if( !pImp->pKeyList )
+ pImp->BuildKeyList(pImp->aCurrentApp);
+
+ const char *pc=pImp->pKeyList;
+ for( USHORT n=0; n<nKey; n++ )
+ while(*pc++);
+
+ return String(pc);
+}
+
+USHORT RegInfo::GetKeyCount() const
+{
+ if( !pImp->pKeyList )
+ pImp->BuildKeyList( pImp->aCurrentApp);
+
+ const char *pc=pImp->pKeyList;
+ USHORT nRet=0;
+ while(*pc)
+ {
+ while(*pc++);
+ nRet++;
+ }
+ return nRet;
+}
+
+void RegInfo::SetAppGroup( const String& rGroup )
+{
+ delete[] pImp->pKeyList;
+ pImp->pKeyList = 0;
+ aCurrentGroup = rGroup;
+ pImp->aCurrentApp = MakeAppGroupString_Impl( rGroup );
+}
+
+void RegInfo::DeleteAppGroup( const String &rGroup )
+{
+ PrfWriteProfileString(
+ HINI_USERPROFILE, MakeAppGroupString_Impl( rGroup ), 0, 0);
+}
+
+
+String RegInfo::ReadKey( const String& rKey ) const
+{
+ char *pBuffer= new char[MAXREGVALUE];
+ *pBuffer=0;
+ PrfQueryProfileString(
+ HINI_USERPROFILE, pImp->aCurrentApp, rKey, 0, pBuffer, MAXREGVALUE);
+ String aRet(pBuffer);
+ delete[] pBuffer;
+ return aRet;
+}
+
+
+String RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
+{
+ char *pBuffer= new char[MAXREGVALUE];
+ *pBuffer=0;
+ PrfQueryProfileString(
+ HINI_USERPROFILE, pImp->aCurrentApp, rKey, rDefault, pBuffer, MAXREGVALUE);
+ String aRet(pBuffer);
+ delete[] pBuffer;
+ return aRet;
+}
+
+
+void RegInfo::WriteKey( const String& rKey, const String& rValue )
+{
+ PrfWriteProfileString(
+ HINI_USERPROFILE, pImp->aCurrentApp, rKey, rValue);
+}
+
+void RegInfo::DeleteKey( const String& rKey )
+{
+ PrfWriteProfileString(
+ HINI_USERPROFILE, pImp->aCurrentApp, rKey, 0);
+}
+
+#elif defined(MAC)
+
+/* Idee:
+
+ In eine Resource SVðð (SV<Apfel><Apfel>) sind die Resource IDs
+ der Gruppen Ÿber den Namen der Resource zugŠnglich.
+
+ †ber die aktuelle Gruppe sind die Values Ÿber den Namen der Resource
+ als Key zugŠnglich ...
+*/
+
+// Wir tuen so, als wŠren es "normale" SV-Resourcen
+
+#define kAPPInfo 'SVðð'
+
+//****************************************************
+
+#pragma options align=mac68k
+
+typedef struct
+{
+ OSType nResType; // kAPPInfo + k
+}
+ SVGroupInfo, *SVGroupInfoPtr, **SVGroupInfoHdl;
+
+//****************************************************
+
+typedef struct
+{
+ USHORT nValueLen;
+ char aValue[1]; // LŠnge wie in nLen
+}
+ SVKeyInfo, *SVKeyInfoPtr, **SVKeyInfoHdl;
+
+//****************************************************
+
+#pragma options align=reset
+
+//****************************************************
+
+struct RegInfo_Impl
+{
+ short nResFile;
+ OSType nCurrentGroup;
+ String aCurrentName;
+
+ SVGroupInfoHdl GetNamedInfo(const String& rName);
+
+ BOOL FindInfoFile( const String& rName, FSSpec *pResult );
+};
+
+//****************************************************
+
+SVGroupInfoHdl RegInfo_Impl::GetNamedInfo(const String& rName)
+{
+ String aName(rName);
+ short nOldRes = CurResFile();
+ UseResFile(nResFile);
+
+ SVGroupInfoHdl hResult = (SVGroupInfoHdl) Get1NamedResource(kAPPInfo,rName.GetPascalStr());
+
+ UseResFile(nOldRes);
+
+ return hResult;
+}
+
+//****************************************************
+
+BOOL RegInfo_Impl::FindInfoFile( const String& rName, FSSpec *pResult )
+{
+ OSErr nErr;
+ long nDirID;
+ short nVRefNum;
+ BOOL bResult = FALSE;
+
+ nErr = FindFolder( kOnSystemDisk, kPreferencesFolderType,
+ kCreateFolder, &nVRefNum, &nDirID );
+
+ if ( nErr == noErr )
+ {
+ nErr = FSMakeFSSpec( nVRefNum, nDirID, rName.GetPascalStr(), pResult );
+ if ( nErr == fnfErr )
+ {
+ FSpCreateResFile( pResult, 'SDsv', 'DATA', smRoman );
+ nErr = FSMakeFSSpec( nVRefNum, nDirID, rName.GetPascalStr(), pResult );
+ }
+ if ( nErr == noErr )
+ {
+ FInfo aInfo;
+ nErr = FSpGetFInfo( pResult, &aInfo );
+ if ( ( nErr == noErr ) && ! ( aInfo.fdFlags & kIsInvisible ) )
+ {
+ aInfo.fdFlags |= kIsInvisible;
+ nErr = FSpSetFInfo( pResult, &aInfo );
+ }
+ bResult = TRUE;
+ }
+ }
+
+ return bResult;
+}
+
+//****************************************************
+
+RegInfo::RegInfo()
+{
+ FSSpec aFile;
+
+ if ( !pImp->FindInfoFile( "svdbt.dll", &aFile ) )
+ {
+ pImp = NULL;
+ return;
+ }
+
+ pImp=new RegInfo_Impl;
+
+ short nOldRes = CurResFile();
+ pImp->nResFile = FSpOpenResFile( &aFile, fsRdWrPerm );
+ pImp->nCurrentGroup = 0L;
+ UseResFile( nOldRes );
+
+ if ( pImp->nResFile < 0 )
+ {
+ delete pImp;
+ pImp = NULL;
+ }
+}
+
+//****************************************************
+
+RegInfo::~RegInfo()
+{
+ if (pImp)
+ {
+ CloseResFile( pImp->nResFile );
+ delete pImp;
+ }
+}
+
+//****************************************************
+
+String RegInfo::GetKeyName( USHORT nKey ) const
+{
+ String aResult;
+
+ if (!pImp || !pImp -> nCurrentGroup)
+ return aResult;
+
+ short nOldRes = CurResFile();
+ UseResFile(pImp -> nResFile);
+
+ SVKeyInfoHdl hKeyInfo = (SVKeyInfoHdl) Get1IndResource(pImp -> nCurrentGroup,nKey + 1);
+
+ if (hKeyInfo)
+ {
+ Str255 aName;
+ ResType nType;
+ short nMacKey;
+
+ GetResInfo((Handle) hKeyInfo,&nMacKey,&nType,aName);
+ if (ResError() == noErr)
+ aResult = String((char*) &aName[1], aName[0]);
+ }
+
+ UseResFile(nOldRes);
+ return aResult;
+}
+
+//****************************************************
+
+USHORT RegInfo::GetKeyCount() const
+{
+ USHORT nResult = 0;
+
+ if (pImp -> nCurrentGroup)
+ {
+ short nOldRes = CurResFile();
+ UseResFile(pImp -> nResFile);
+
+ nResult = Count1Resources(pImp -> nCurrentGroup);
+ UseResFile(nOldRes);
+ }
+ return nResult;
+}
+
+//****************************************************
+
+void RegInfo::SetAppGroup( const String& rGroup )
+{
+ if (!pImp)
+ return;
+
+ pImp->aCurrentName = rGroup;
+ SVGroupInfoHdl hGroup = pImp -> GetNamedInfo(rGroup);
+ if (hGroup)
+ {
+ pImp->nCurrentGroup = (*hGroup)-> nResType;
+ ReleaseResource((Handle) hGroup);
+ }
+ else
+ pImp->nCurrentGroup = 0L;
+}
+
+//****************************************************
+
+void RegInfo::DeleteAppGroup( const String &rGroup )
+{
+ SVGroupInfoHdl hToDelete = pImp -> GetNamedInfo(rGroup);
+ if (hToDelete)
+ {
+ if ((*hToDelete)-> nResType == pImp->nCurrentGroup)
+ {
+ pImp->nCurrentGroup = 0L;
+ pImp->aCurrentName.Erase();
+ }
+ RemoveResource((Handle) hToDelete);
+ }
+}
+
+//****************************************************
+
+String RegInfo::ReadKey( const String& rKey ) const
+{
+ String aResult;
+
+ if (!pImp || !pImp -> nCurrentGroup)
+ return aResult;
+
+ short nOldRes = CurResFile();
+ UseResFile(pImp -> nResFile);
+
+ SVKeyInfoHdl hKeyInfo = (SVKeyInfoHdl) Get1NamedResource(pImp->nCurrentGroup,rKey.GetPascalStr());
+
+ if (hKeyInfo)
+ {
+ HLock((Handle) hKeyInfo);
+ aResult = String((*hKeyInfo)->aValue, (*hKeyInfo)->nValueLen);
+ HUnlock((Handle) hKeyInfo);
+
+ ReleaseResource((Handle) hKeyInfo);
+ }
+
+ UseResFile(nOldRes);
+ return aResult;
+}
+
+//****************************************************
+
+String RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
+{
+ String aResult = ReadKey(rKey);
+ if (!aResult.Len())
+ return rDefault;
+ else
+ return aResult;
+}
+
+//****************************************************
+
+void RegInfo::WriteKey( const String& rKey, const String& rValue )
+{
+ if (!pImp)
+ return;
+
+ short nOldRes = CurResFile();
+ UseResFile(pImp -> nResFile);
+
+ // Wenn wir noch keine Resource zur aktuellen Gruppe haben ...
+ if (!pImp -> nCurrentGroup)
+ {
+ // ... dann muessen wir hier eine Anlegen
+
+ if (!pImp -> aCurrentName.Len())
+ return; // Kein aktueller Name ???
+
+ short nNewId = Unique1ID(kAPPInfo);
+
+ SVGroupInfoHdl hNewInfo = (SVGroupInfoHdl) NewHandle(sizeof(SVGroupInfo));
+
+ // Die Neue Resource liegt im Bereich Ÿber "SVðð"
+ pImp -> nCurrentGroup = kAPPInfo + nNewId;
+
+ (*(hNewInfo))-> nResType = pImp -> nCurrentGroup;
+ DBG_ASSERT(CurResFile() == pImp -> nResFile,"wrong ResFile");
+ AddResource((Handle) hNewInfo ,kAPPInfo, nNewId, pImp -> aCurrentName.GetPascalStr());
+ ReleaseResource((Handle) hNewInfo);
+ }
+
+ SVKeyInfoHdl hKeyInfo = (SVKeyInfoHdl) Get1NamedResource(pImp -> nCurrentGroup,rKey.GetPascalStr());
+ int nNewSize = rValue.Len() + sizeof(USHORT);
+
+ // Haben wir zu diesem Key schon eine Resource ?
+ if (hKeyInfo)
+ {
+ int nSize = GetHandleSize((Handle) hKeyInfo);
+ OSErr nMemErr = noErr;
+ if (nSize < nNewSize)
+ {
+ SetHandleSize((Handle) hKeyInfo,nNewSize);
+ nMemErr = MemError();
+ }
+
+ if (nMemErr == noErr)
+ {
+ (*hKeyInfo)->nValueLen = rValue.Len();
+ BlockMoveData(rValue.GetStr(), (*hKeyInfo)->aValue, rValue.Len());
+ ChangedResource((Handle) hKeyInfo);
+ }
+ else // Handle konnte nicht groesser werden
+ RemoveResource((Handle) hKeyInfo);
+ }
+ else
+ {
+ // Resource zu diesemm Key neu anlegen
+
+ hKeyInfo = (SVKeyInfoHdl) NewHandle(nNewSize);
+ if (hKeyInfo)
+ {
+ short nNewId = Unique1ID(pImp -> nCurrentGroup);
+
+ (*hKeyInfo)->nValueLen = rValue.Len();
+ BlockMoveData(rValue.GetStr(), (*hKeyInfo)->aValue, rValue.Len());
+
+ AddResource((Handle) hKeyInfo ,pImp -> nCurrentGroup, nNewId, rKey.GetPascalStr());
+ }
+ }
+
+ UseResFile(nOldRes);
+}
+
+//****************************************************
+
+void RegInfo::DeleteKey( const String& rKey )
+{
+ // Wenn wir noch keine aktuellen Gruppe haben ...
+ if (!pImp -> nCurrentGroup)
+ return;
+
+ String aKey(rKey);
+
+ short nOldRes = CurResFile();
+ UseResFile(pImp -> nResFile);
+
+ SVKeyInfoHdl hKeyInfo = (SVKeyInfoHdl) Get1NamedResource(pImp -> nCurrentGroup,rKey.GetPascalStr());
+
+ if (hKeyInfo)
+ RemoveResource((Handle) hKeyInfo);
+
+ UseResFile(nOldRes);
+}
+
+//****************************************************
+
+#else
+
+RegInfo::RegInfo()
+{
+}
+
+
+RegInfo::~RegInfo()
+{
+}
+
+String RegInfo::GetKeyName( USHORT nKey ) const
+{
+ return aEmptyString;
+}
+
+USHORT RegInfo::GetKeyCount() const
+{
+ return 0;
+}
+
+void RegInfo::SetAppGroup( const String& rGroup )
+{
+ return ;
+}
+
+void RegInfo::DeleteAppGroup( const String &rGroup )
+{
+ return;
+}
+
+String RegInfo::ReadKey( const String& rKey ) const
+{
+ return aEmptyString;
+}
+
+String RegInfo::ReadKey( const String& rKey, const String &rDefault ) const
+{
+ return aEmptyString;
+}
+
+void RegInfo::WriteKey( const String& rKey, const String& rValue )
+{
+ return;
+}
+
+void RegInfo::DeleteKey( const String& rKey )
+{
+ return;
+}
+
+#endif
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();
+}
diff --git a/svtools/source/control/scrwin.cxx b/svtools/source/control/scrwin.cxx
new file mode 100644
index 000000000000..10ef086ed9fd
--- /dev/null
+++ b/svtools/source/control/scrwin.cxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * $RCSfile: scrwin.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _SVT_SCRWIN_CXX
+#include <scrwin.hxx>
+
+//===================================================================
+
+void ScrollableWindow::ImpInitialize( ScrollableWindowFlags nFlags )
+{
+ bHandleDragging = (BOOL) ( nFlags & SCRWIN_THUMBDRAGGING );
+ bVCenter = (nFlags & SCRWIN_VCENTER) == SCRWIN_VCENTER;
+ bHCenter = (nFlags & SCRWIN_HCENTER) == SCRWIN_HCENTER;
+ bScrolling = FALSE;
+
+ // set the handlers for the scrollbars
+ aVScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
+ aHScroll.SetScrollHdl( LINK(this, ScrollableWindow, ScrollHdl) );
+ aVScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
+ aHScroll.SetEndScrollHdl( LINK(this, ScrollableWindow, EndScrollHdl) );
+
+ nColumnPixW = nLinePixH = GetSettings().GetStyleSettings().GetScrollBarSize();
+}
+
+//-------------------------------------------------------------------
+
+ScrollableWindow::ScrollableWindow( Window* pParent, WinBits nBits,
+ ScrollableWindowFlags nFlags ) :
+ Window( pParent, WinBits(nBits|WB_CLIPCHILDREN) ),
+ aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
+ aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
+ aCornerWin( this )
+{
+ ImpInitialize( nFlags );
+}
+
+//-------------------------------------------------------------------
+
+ScrollableWindow::ScrollableWindow( Window* pParent, const ResId& rId,
+ ScrollableWindowFlags nFlags ) :
+ Window( pParent, rId ),
+ aVScroll( this, WinBits(WB_VSCROLL | WB_DRAG) ),
+ aHScroll( this, WinBits(WB_HSCROLL | WB_DRAG) ),
+ aCornerWin( this )
+{
+ ImpInitialize( nFlags );
+}
+
+// -----------------------------------------------------------------------
+
+void ScrollableWindow::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
+ {
+ ScrollBar* pHScrBar;
+ ScrollBar* pVScrBar;
+ if ( aHScroll.IsVisible() )
+ pHScrBar = &aHScroll;
+ else
+ pHScrBar = NULL;
+ if ( aVScroll.IsVisible() )
+ pVScrBar = &aVScroll;
+ else
+ pVScrBar = NULL;
+ if ( HandleScrollCommand( rCEvt, pHScrBar, pVScrBar ) )
+ return;
+ }
+
+ Window::Command( rCEvt );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE) )
+ {
+ Resize();
+ Invalidate();
+ }
+
+ Window::DataChanged( rDCEvt );
+}
+
+//-------------------------------------------------------------------
+
+Size __EXPORT ScrollableWindow::GetOutputSizePixel() const
+{
+ Size aSz( Window::GetOutputSizePixel() );
+
+ long nTmp = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aHScroll.IsVisible() )
+ aSz.Height() -= nTmp;
+ if ( aVScroll.IsVisible() )
+ aSz.Width() -= nTmp;
+ return aSz;
+}
+
+//-------------------------------------------------------------------
+
+Size ScrollableWindow::GetOutputSize() const
+{
+ return PixelToLogic( GetOutputSizePixel() );
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( ScrollableWindow, EndScrollHdl, ScrollBar *, pScroll )
+{
+ // notify the start of scrolling, if not already scrolling
+ if ( !bScrolling )
+ StartScroll(), bScrolling = TRUE;
+
+ // get the delta in logic coordinates
+ Size aDelta( PixelToLogic( Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
+
+ // scroll the window, if this is not already done
+ if ( !bHandleDragging )
+ {
+ if ( pScroll == &aHScroll )
+ Scroll( aDelta.Width(), 0 );
+ else
+ Scroll( 0, aDelta.Height() );
+ }
+
+ // notify the end of scrolling
+ bScrolling = FALSE;
+ EndScroll( aDelta.Width(), aDelta.Height() );
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+IMPL_LINK( ScrollableWindow, ScrollHdl, ScrollBar *, pScroll )
+{
+ // notify the start of scrolling, if not already scrolling
+ if ( !bScrolling )
+ StartScroll(), bScrolling = TRUE;
+
+ if ( bHandleDragging )
+ {
+ // get the delta in logic coordinates
+ Size aDelta( PixelToLogic(
+ Size( aHScroll.GetDelta(), aVScroll.GetDelta() ) ) );
+ if ( pScroll == &aHScroll )
+ Scroll( aDelta.Width(), 0 );
+ else
+ Scroll( 0, aDelta.Height() );
+ }
+ return 0;
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::Resize()
+{
+ // get the new output-size in pixel
+ Size aOutPixSz = Window::GetOutputSizePixel();
+
+ // determine the size of the output-area and if we need scrollbars
+ const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ BOOL bVVisible = FALSE; // by default no vertical-ScrollBar
+ BOOL bHVisible = FALSE; // by default no horizontal-ScrollBar
+ BOOL bChanged; // determines if a visiblility was changed
+ do
+ {
+ bChanged = FALSE;
+
+ // does we need a vertical ScrollBar
+ if ( aOutPixSz.Width() < aTotPixSz.Width() && !bHVisible )
+ { bHVisible = TRUE;
+ aOutPixSz.Height() -= nScrSize;
+ bChanged = TRUE;
+ }
+
+ // does we need a horizontal ScrollBar
+ if ( aOutPixSz.Height() < aTotPixSz.Height() && !bVVisible )
+ { bVVisible = TRUE;
+ aOutPixSz.Width() -= nScrSize;
+ bChanged = TRUE;
+ }
+
+ }
+ while ( bChanged ); // until no visibility has changed
+
+ // store the old offset and map-mode
+ MapMode aMap( GetMapMode() );
+ Point aOldPixOffset( aPixOffset );
+
+ // justify (right/bottom borders should never exceed the virtual window)
+ Size aPixDelta;
+ if ( aPixOffset.X() < 0 &&
+ aPixOffset.X() + aTotPixSz.Width() < aOutPixSz.Width() )
+ aPixDelta.Width() =
+ aOutPixSz.Width() - ( aPixOffset.X() + aTotPixSz.Width() );
+ if ( aPixOffset.Y() < 0 &&
+ aPixOffset.Y() + aTotPixSz.Height() < aOutPixSz.Height() )
+ aPixDelta.Height() =
+ aOutPixSz.Height() - ( aPixOffset.Y() + aTotPixSz.Height() );
+ if ( aPixDelta.Width() || aPixDelta.Height() )
+ {
+ aPixOffset.X() += aPixDelta.Width();
+ aPixOffset.Y() += aPixDelta.Height();
+ }
+
+ // for axis without scrollbar restore the origin
+ if ( !bVVisible || !bHVisible )
+ {
+ aPixOffset = Point(
+ bHVisible
+ ? aPixOffset.X()
+ : ( bHCenter
+ ? (aOutPixSz.Width()-aTotPixSz.Width()) / 2
+ : 0 ),
+ bVVisible
+ ? aPixOffset.Y()
+ : ( bVCenter
+ ? (aOutPixSz.Height()-aTotPixSz.Height()) / 2
+ : 0 ) );
+ }
+ if ( bHVisible && !aHScroll.IsVisible() )
+ aPixOffset.X() = 0;
+ if ( bVVisible && !aVScroll.IsVisible() )
+ aPixOffset.Y() = 0;
+
+ // select the shifted map-mode
+ if ( aPixOffset != aOldPixOffset )
+ {
+ Window::SetMapMode( MapMode( MAP_PIXEL ) );
+ Window::Scroll(
+ aPixOffset.X() - aOldPixOffset.X(),
+ aPixOffset.Y() - aOldPixOffset.Y() );
+ SetMapMode( aMap );
+ }
+
+ // show or hide scrollbars
+ aVScroll.Show( bVVisible );
+ aHScroll.Show( bHVisible );
+
+ // disable painting in the corner between the scrollbars
+ if ( bVVisible && bHVisible )
+ {
+ aCornerWin.SetPosSizePixel(
+ *((Point*) &aOutPixSz), Size(nScrSize, nScrSize) );
+ aCornerWin.Show();
+ }
+ else
+ aCornerWin.Hide();
+
+ // resize scrollbars and set their ranges
+ if ( bHVisible )
+ {
+ aHScroll.SetPosSizePixel(
+ Point( 0, aOutPixSz.Height() ),
+ Size( aOutPixSz.Width(), nScrSize ) );
+ aHScroll.SetRange( Range( 0, aTotPixSz.Width() ) );
+ aHScroll.SetPageSize( aOutPixSz.Width() );
+ aHScroll.SetVisibleSize( aOutPixSz.Width() );
+ aHScroll.SetLineSize( nColumnPixW );
+ aHScroll.SetThumbPos( -aPixOffset.X() );
+ }
+ if ( bVVisible )
+ {
+ aVScroll.SetPosSizePixel(
+ Point( aOutPixSz.Width(), 0 ),
+ Size( nScrSize,aOutPixSz.Height() ) );
+ aVScroll.SetRange( Range( 0, aTotPixSz.Height() ) );
+ aVScroll.SetPageSize( aOutPixSz.Height() );
+ aVScroll.SetVisibleSize( aOutPixSz.Height() );
+ aVScroll.SetLineSize( nLinePixH );
+ aVScroll.SetThumbPos( -aPixOffset.Y() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::StartScroll()
+{
+}
+
+//-------------------------------------------------------------------
+
+void __EXPORT ScrollableWindow::EndScroll( long nDeltaX, long nDeltaY )
+{
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetMapMode( const MapMode& rNewMapMode )
+{
+ MapMode aMap( rNewMapMode );
+ aMap.SetOrigin( aMap.GetOrigin() + PixelToLogic( aPixOffset, aMap ) );
+ Window::SetMapMode( aMap );
+}
+
+//-------------------------------------------------------------------
+
+MapMode ScrollableWindow::GetMapMode() const
+{
+ MapMode aMap( Window::GetMapMode() );
+ aMap.SetOrigin( aMap.GetOrigin() - PixelToLogic( aPixOffset ) );
+ return aMap;
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetTotalSize( const Size& rNewSize )
+{
+ aTotPixSz = LogicToPixel( rNewSize );
+ ScrollableWindow::Resize();
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetVisibleSize( const Size& rNewSize )
+{
+ // get the rectangle, we wish to view
+ Rectangle aWish( Point(0, 0), LogicToPixel(rNewSize) );
+
+ // get maximum rectangle for us from our parent-window (subst our border!)
+ Rectangle aMax( Point(0, 0), GetParent()->GetOutputSizePixel() );
+ aMax.Left() -= ( Window::GetSizePixel().Width() -
+ Window::GetOutputSizePixel().Width() );
+ aMax.Bottom() -= (Window::GetSizePixel().Height() -
+ Window::GetOutputSizePixel().Height());
+
+ Size aWill( aWish.GetIntersection(aMax).GetSize() );
+ BOOL bHScroll = FALSE;
+ const long nScrSize = GetSettings().GetStyleSettings().GetScrollBarSize();
+ if ( aWill.Width() < aWish.GetSize().Width() )
+ { bHScroll = TRUE;
+ aWill.Height() =
+ Min( aWill.Height()+nScrSize, aMax.GetSize().Height() );
+ }
+ if ( aWill.Height() < aWish.GetSize().Height() )
+ aWill.Width() =
+ Min( aWill.Width()+nScrSize, aMax.GetSize().Width() );
+ if ( !bHScroll && (aWill.Width() < aWish.GetSize().Width()) )
+ aWill.Height() =
+ Min( aWill.Height()+nScrSize, aMax.GetSize().Height() );
+ Window::SetOutputSizePixel( aWill );
+}
+
+//-------------------------------------------------------------------
+
+BOOL ScrollableWindow::MakeVisible( const Rectangle& rTarget, BOOL bSloppy )
+{
+ Rectangle aTarget;
+ Rectangle aTotRect( Point(0, 0), PixelToLogic( aTotPixSz ) );
+
+ if ( bSloppy )
+ {
+ aTarget = rTarget;
+
+ // at maximum to right border
+ if ( aTarget.Right() > aTotRect.Right() )
+ {
+ long nDelta = aTarget.Right() - aTotRect.Right();
+ aTarget.Left() -= nDelta;
+ aTarget.Right() -= nDelta;
+
+ // too wide?
+ if ( aTarget.Left() < aTotRect.Left() )
+ aTarget.Left() = aTotRect.Left();
+ }
+
+ // at maximum to bottom border
+ if ( aTarget.Bottom() > aTotRect.Bottom() )
+ {
+ long nDelta = aTarget.Bottom() - aTotRect.Bottom();
+ aTarget.Top() -= nDelta;
+ aTarget.Bottom() -= nDelta;
+
+ // too high?
+ if ( aTarget.Top() < aTotRect.Top() )
+ aTarget.Top() = aTotRect.Top();
+ }
+
+ // at maximum to left border
+ if ( aTarget.Left() < aTotRect.Left() )
+ {
+ long nDelta = aTarget.Left() - aTotRect.Left();
+ aTarget.Right() -= nDelta;
+ aTarget.Left() -= nDelta;
+
+ // too wide?
+ if ( aTarget.Right() > aTotRect.Right() )
+ aTarget.Right() = aTotRect.Right();
+ }
+
+ // at maximum to top border
+ if ( aTarget.Top() < aTotRect.Top() )
+ {
+ long nDelta = aTarget.Top() - aTotRect.Top();
+ aTarget.Bottom() -= nDelta;
+ aTarget.Top() -= nDelta;
+
+ // too high?
+ if ( aTarget.Bottom() > aTotRect.Bottom() )
+ aTarget.Bottom() = aTotRect.Bottom();
+ }
+ }
+ else
+ aTarget = rTarget.GetIntersection( aTotRect );
+
+ // is the area already visible?
+ Rectangle aVisArea( GetVisibleArea() );
+ if ( aVisArea.IsInside(rTarget) )
+ return TRUE;
+
+ // is there somewhat to scroll?
+ if ( aVisArea.TopLeft() != aTarget.TopLeft() )
+ {
+ Rectangle aBox( aTarget.GetUnion(aVisArea) );
+ long nDeltaX = ( aBox.Right() - aVisArea.Right() ) +
+ ( aBox.Left() - aVisArea.Left() );
+ long nDeltaY = ( aBox.Top() - aVisArea.Top() ) +
+ ( aBox.Bottom() - aVisArea.Bottom() );
+ Scroll( nDeltaX, nDeltaY );
+ }
+
+ // determine if the target is completely visible
+ return aVisArea.GetWidth() >= aTarget.GetWidth() &&
+ aVisArea.GetHeight() >= aTarget.GetHeight();
+}
+
+//-------------------------------------------------------------------
+
+Rectangle ScrollableWindow::GetVisibleArea() const
+{
+ Point aTopLeft( PixelToLogic( Point() ) );
+ Size aSz( GetOutputSize() );
+ return Rectangle( aTopLeft, aSz );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::SetLineSize( ULONG nHorz, ULONG nVert )
+{
+ Size aPixSz( LogicToPixel( Size(nHorz, nVert) ) );
+ nColumnPixW = aPixSz.Width();
+ nLinePixH = aPixSz.Height();
+ aVScroll.SetLineSize( nLinePixH );
+ aHScroll.SetLineSize( nColumnPixW );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::Scroll( long nDeltaX, long nDeltaY )
+{
+ if ( !bScrolling )
+ StartScroll();
+
+ // get the delta in pixel
+ Size aDeltaPix( LogicToPixel( Size(nDeltaX, nDeltaY) ) );
+ Size aOutPixSz( GetOutputSizePixel() );
+ MapMode aMap( GetMapMode() );
+ Point aNewPixOffset( aPixOffset );
+
+ // scrolling horizontally?
+ if ( nDeltaX != 0 )
+ {
+ aNewPixOffset.X() -= aDeltaPix.Width();
+ if ( ( aOutPixSz.Width() - aNewPixOffset.X() ) > aTotPixSz.Width() )
+ aNewPixOffset.X() = - ( aTotPixSz.Width() - aOutPixSz.Width() );
+ else if ( aNewPixOffset.X() > 0 )
+ aNewPixOffset.X() = 0;
+ }
+
+ // scrolling vertically?
+ if ( nDeltaY != 0 )
+ {
+ aNewPixOffset.Y() -= aDeltaPix.Height();
+ if ( ( aOutPixSz.Height() - aNewPixOffset.Y() ) > aTotPixSz.Height() )
+ aNewPixOffset.Y() = - ( aTotPixSz.Height() - aOutPixSz.Height() );
+ else if ( aNewPixOffset.Y() > 0 )
+ aNewPixOffset.Y() = 0;
+ }
+
+ // recompute the logical scroll units
+ aDeltaPix.Width() = aPixOffset.X() - aNewPixOffset.X();
+ aDeltaPix.Height() = aPixOffset.Y() - aNewPixOffset.Y();
+ Size aDelta( PixelToLogic(aDeltaPix) );
+ nDeltaX = aDelta.Width();
+ nDeltaY = aDelta.Height();
+ aPixOffset = aNewPixOffset;
+
+ // scrolling?
+ if ( nDeltaX != 0 || nDeltaY != 0 )
+ {
+ Update();
+
+ // does the new area overlap the old one?
+ if ( Abs( (int)aDeltaPix.Height() ) < aOutPixSz.Height() ||
+ Abs( (int)aDeltaPix.Width() ) < aOutPixSz.Width() )
+ {
+ // scroll the overlapping area
+ SetMapMode( aMap );
+
+ // never scroll the scrollbars itself!
+ Window::Scroll(-nDeltaX, -nDeltaY,
+ PixelToLogic( Rectangle( Point(0, 0), aOutPixSz ) ) );
+ }
+ else
+ {
+ // repaint all
+ SetMapMode( aMap );
+ Invalidate();
+ }
+
+ Update();
+ }
+
+ if ( !bScrolling )
+ {
+ EndScroll( nDeltaX, nDeltaY );
+ if ( nDeltaX )
+ aHScroll.SetThumbPos( -aPixOffset.X() );
+ if ( nDeltaY )
+ aVScroll.SetThumbPos( -aPixOffset.Y() );
+ }
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::ScrollLines( long nLinesX, long nLinesY )
+{
+ Size aDelta( PixelToLogic( Size( nColumnPixW, nLinePixH ) ) );
+ Scroll( aDelta.Width()*nLinesX, aDelta.Height()*nLinesY );
+}
+
+//-------------------------------------------------------------------
+
+void ScrollableWindow::ScrollPages( long nPagesX, ULONG nOverlapX,
+ long nPagesY, ULONG nOverlapY )
+{
+ Size aOutSz( GetVisibleArea().GetSize() );
+ Scroll( nPagesX * aOutSz.Width() + (nPagesX>0 ? 1 : -1) * nOverlapX,
+ nPagesY * aOutSz.Height() + (nPagesY>0 ? 1 : -1) * nOverlapY );
+}
+
+
diff --git a/svtools/source/control/stdctrl.cxx b/svtools/source/control/stdctrl.cxx
new file mode 100644
index 000000000000..026a6642d209
--- /dev/null
+++ b/svtools/source/control/stdctrl.cxx
@@ -0,0 +1,77 @@
+/*************************************************************************
+ *
+ * $RCSfile: stdctrl.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 <stdctrl.hxx>
+
+// =======================================================================
+
+FixedInfo::FixedInfo( Window* pParent, WinBits nWinStyle ) :
+ FixedText( pParent, nWinStyle | WB_INFO )
+{
+}
+
+// -----------------------------------------------------------------------
+
+FixedInfo::FixedInfo( Window* pParent, const ResId& rResId ) :
+ FixedText( pParent, rResId )
+{
+ SetStyle( GetStyle() | WB_INFO );
+}
diff --git a/svtools/source/control/stdmenu.cxx b/svtools/source/control/stdmenu.cxx
new file mode 100644
index 000000000000..46707d960e3d
--- /dev/null
+++ b/svtools/source/control/stdmenu.cxx
@@ -0,0 +1,446 @@
+/*************************************************************************
+ *
+ * $RCSfile: stdmenu.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 _APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+
+#include <ctrltool.hxx>
+#include <stdmenu.hxx>
+
+// ========================================================================
+
+FontNameMenu::FontNameMenu()
+{
+ SetMenuFlags( GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+}
+
+// -----------------------------------------------------------------------
+
+FontNameMenu::~FontNameMenu()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::Select()
+{
+ maCurName = GetItemText( GetCurItemId() );
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::Highlight()
+{
+ XubString aTempName = maCurName;
+ maCurName = GetItemText( GetCurItemId() );
+ maHighlightHdl.Call( this );
+ maCurName = aTempName;
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::Fill( const FontList* pList )
+{
+ // Menu loeschen
+ Clear();
+
+ // Fonts eintragen
+ International aIntn = Application::GetAppInternational();
+ USHORT nFontCount = pList->GetFontNameCount();
+ for ( USHORT i = 0; i < nFontCount; i++ )
+ {
+ const XubString& rName = pList->GetFontName( i ).GetName();
+
+ // Sortieren, nach der in der Applikation eingestellten
+ // International-Klasse
+ USHORT j = GetItemCount();
+ while ( j )
+ {
+ XubString aText = GetItemText( GetItemId( j-1 ) );
+ if ( aIntn.Compare( rName, aText ) == COMPARE_GREATER )
+ break;
+ j--;
+ }
+
+ InsertItem( i+1, rName, MIB_RADIOCHECK | MIB_AUTOCHECK, j );
+ }
+
+ SetCurName( maCurName );
+}
+
+// -----------------------------------------------------------------------
+
+void FontNameMenu::SetCurName( const XubString& rName )
+{
+ maCurName = rName;
+
+ // Menueintrag checken
+ USHORT nChecked = 0;
+ USHORT nItemCount = GetItemCount();
+ for( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = GetItemId( i );
+
+ if ( IsItemChecked( nItemId ) )
+ nChecked = nItemId;
+
+ XubString aText = GetItemText( nItemId );
+ if ( aText == maCurName )
+ {
+ CheckItem( nItemId, TRUE );
+ return;
+ }
+ }
+
+ if ( nChecked )
+ CheckItem( nChecked, FALSE );
+}
+
+// ========================================================================
+
+FontStyleMenu::FontStyleMenu()
+{
+ SetMenuFlags( GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+}
+
+// -----------------------------------------------------------------------
+
+FontStyleMenu::~FontStyleMenu()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::Select()
+{
+ USHORT nCurId = GetCurItemId();
+
+ if ( (nCurId >= FONTSTYLEMENU_FIRSTID) && (nCurId <= FONTSTYLEMENU_LASTID) )
+ {
+ maCurStyle = GetItemText( nCurId );
+ maSelectHdl.Call( this );
+ }
+ else
+ PopupMenu::Select();
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::Highlight()
+{
+ USHORT nCurId = GetCurItemId();
+
+ if ( (nCurId >= FONTSTYLEMENU_FIRSTID) && (nCurId <= FONTSTYLEMENU_LASTID) )
+ {
+ XubString aTempName = maCurStyle;
+ maCurStyle = GetItemText( nCurId );
+ maHighlightHdl.Call( this );
+ maCurStyle = aTempName;
+ }
+ else
+ PopupMenu::Highlight();
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::Fill( const XubString& rName, const FontList* pList )
+{
+ USHORT nItemId = GetItemId( 0 );
+ while ( (nItemId >= FONTSTYLEMENU_FIRSTID) &&
+ (nItemId <= FONTSTYLEMENU_LASTID) )
+ {
+ RemoveItem( 0 );
+ nItemId = GetItemId( 0 );
+ }
+
+ // Existiert ein Font mit diesem Namen
+ sal_Handle hFontInfo = pList->GetFirstFontInfo( rName );
+ if ( hFontInfo )
+ {
+ USHORT nPos = 0;
+ USHORT nId = FONTSTYLEMENU_FIRSTID;
+ BOOL bNormal = FALSE;
+ BOOL bItalic = FALSE;
+ BOOL bBold = FALSE;
+ BOOL bBoldItalic = FALSE;
+ FontInfo aInfo;
+ while ( hFontInfo )
+ {
+ aInfo = pList->GetFontInfo( hFontInfo );
+
+ XubString aStyleText = pList->GetStyleName( aInfo );
+ FontWeight eWeight = aInfo.GetWeight();
+ FontItalic eItalic = aInfo.GetItalic();
+ if ( eWeight <= WEIGHT_NORMAL )
+ {
+ bNormal = TRUE;
+ if ( eItalic != ITALIC_NONE )
+ bItalic = TRUE;
+ }
+ else
+ {
+ if ( eItalic != ITALIC_NONE )
+ bBoldItalic = TRUE;
+ else
+ bBold = TRUE;
+ }
+ if ( aStyleText == pList->GetItalicStr() )
+ bItalic = TRUE;
+ else if ( aStyleText == pList->GetBoldStr() )
+ bBold = TRUE;
+ else if ( aStyleText == pList->GetBoldItalicStr() )
+ bBoldItalic = TRUE;
+
+ InsertItem( nId, aStyleText,
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+
+ hFontInfo = pList->GetNextFontInfo( hFontInfo );
+ }
+
+ // Bestimmte Styles als Nachbildung
+ if ( bNormal )
+ {
+ if ( !bItalic )
+ {
+ InsertItem( nId, pList->GetItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+ if ( !bBold )
+ {
+ InsertItem( nId, pList->GetBoldStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+ }
+ if ( !bBoldItalic )
+ {
+ if ( bNormal || bItalic || bBold )
+ {
+ InsertItem( nId, pList->GetBoldItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, nPos );
+ nPos++;
+ nId++;
+ }
+ }
+ }
+ else
+ {
+ // Wenn Font nicht, dann Standard-Styles einfuegen
+ InsertItem( FONTSTYLEMENU_FIRSTID, pList->GetNormalStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ InsertItem( FONTSTYLEMENU_FIRSTID+1, pList->GetItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ InsertItem( FONTSTYLEMENU_FIRSTID+2, pList->GetBoldStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ InsertItem( FONTSTYLEMENU_FIRSTID+3, pList->GetBoldItalicStr(),
+ MIB_RADIOCHECK | MIB_AUTOCHECK, 0 );
+ }
+
+ SetCurStyle( maCurStyle );
+}
+
+// -----------------------------------------------------------------------
+
+void FontStyleMenu::SetCurStyle( const XubString& rStyle )
+{
+ maCurStyle = rStyle;
+
+ // Menueintrag checken
+ USHORT nChecked = 0;
+ USHORT nItemCount = GetItemCount();
+ for( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = GetItemId( i );
+
+ if ( (nItemId < FONTSTYLEMENU_FIRSTID) ||
+ (nItemId > FONTSTYLEMENU_LASTID) )
+ break;
+
+ if ( IsItemChecked( nItemId ) )
+ nChecked = nItemId;
+
+ XubString aText = GetItemText( nItemId );
+ if ( aText == maCurStyle )
+ {
+ CheckItem( nItemId, TRUE );
+ return;
+ }
+ }
+
+ if ( nChecked )
+ CheckItem( nChecked, FALSE );
+}
+
+// ========================================================================
+
+FontSizeMenu::FontSizeMenu() :
+ maIntn( Application::GetAppInternational() )
+{
+ mpHeightAry = NULL;
+
+ maIntn.SetNumTrailingZeros( FALSE );
+ maIntn.SetNumDigits( 1 );
+
+ SetMenuFlags( GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
+}
+
+// -----------------------------------------------------------------------
+
+FontSizeMenu::~FontSizeMenu()
+{
+ if ( mpHeightAry )
+ delete mpHeightAry;
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::Select()
+{
+ mnCurHeight = mpHeightAry[GetCurItemId()-1];
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::Highlight()
+{
+ long nTempHeight = mnCurHeight;
+ USHORT nCurItemId = GetCurItemId();
+ if ( !nCurItemId )
+ mnCurHeight = 0;
+ else
+ mnCurHeight = mpHeightAry[nCurItemId-1];
+ maHighlightHdl.Call( this );
+ mnCurHeight = nTempHeight;
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::Fill( const FontInfo& rInfo, const FontList* pList )
+{
+ // Menu loeschen
+ Clear();
+
+ // Groessen ermitteln
+ const long* pAry = pList->GetSizeAry( rInfo );
+
+ // Array kopieren
+ if ( mpHeightAry )
+ delete mpHeightAry;
+ USHORT n = 0;
+ while ( pAry[n] )
+ n++;
+ mpHeightAry = new long[n];
+ memcpy( mpHeightAry, pAry, n*sizeof(long) );
+
+ // Groessen einfuegen
+ USHORT nId = 1;
+ while ( *pAry )
+ {
+ InsertItem( nId, maIntn.GetNum( *pAry ),
+ MIB_RADIOCHECK | MIB_AUTOCHECK );
+ nId++;
+ pAry++;
+ }
+
+ SetCurHeight( mnCurHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void FontSizeMenu::SetCurHeight( long nHeight )
+{
+ mnCurHeight = nHeight;
+
+ // Menueintrag checken
+ XubString aHeight = maIntn.GetNum( nHeight );
+ USHORT nChecked = 0;
+ USHORT nItemCount = GetItemCount();
+ for( USHORT i = 0; i < nItemCount; i++ )
+ {
+ USHORT nItemId = GetItemId( i );
+
+ if ( IsItemChecked( nItemId ) )
+ nChecked = nItemId;
+
+ XubString aText = GetItemText( nItemId );
+ if ( aText == aHeight )
+ {
+ CheckItem( nItemId, TRUE );
+ return;
+ }
+ }
+
+ if ( nChecked )
+ CheckItem( nChecked, FALSE );
+}
diff --git a/svtools/source/control/tabbar.cxx b/svtools/source/control/tabbar.cxx
new file mode 100644
index 000000000000..eaa4fee223e8
--- /dev/null
+++ b/svtools/source/control/tabbar.cxx
@@ -0,0 +1,2588 @@
+/*************************************************************************
+ *
+ * $RCSfile: tabbar.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _TOOLS_TIME_HXX
+#include <tools/time.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _VCL_POLY_HXX
+#include <vcl/poly.hxx>
+#endif
+#ifndef _VCL_APP_HXX
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _VCL_HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _VCL_DECOVIEW_HXX
+#include <vcl/decoview.hxx>
+#endif
+#ifndef _VCL_BUTTON_HXX
+#include <vcl/button.hxx>
+#endif
+#ifndef _VCL_EDIT_HXX
+#include <vcl/edit.hxx>
+#endif
+
+#define _SV_TABBAR_CXX
+#define private public
+#include <tabbar.hxx>
+
+// =======================================================================
+
+#define TABBAR_OFFSET_X 7
+#define TABBAR_OFFSET_X2 2
+#define TABBAR_DRAG_SCROLLOFF 5
+#define TABBAR_MINSIZE 5
+
+// =======================================================================
+
+struct ImplTabBarItem
+{
+ USHORT mnId;
+ TabBarPageBits mnBits;
+ XubString maText;
+ XubString maHelpText;
+ Rectangle maRect;
+ long mnWidth;
+ ULONG mnHelpId;
+ BOOL mbShort;
+ BOOL mbSelect;
+ BOOL mbEnable;
+
+ ImplTabBarItem( USHORT nItemId, const XubString& rText,
+ TabBarPageBits nPageBits ) :
+ maText( rText )
+ {
+ mnId = nItemId;
+ mnBits = nPageBits;
+ mnWidth = 0;
+ mnHelpId = 0;
+ mbShort = FALSE;
+ mbSelect = FALSE;
+ mbEnable = TRUE;
+ }
+};
+
+DECLARE_LIST( ImplTabBarList, ImplTabBarItem* );
+
+// =======================================================================
+
+// -----------------
+// - ImplTabButton -
+// -----------------
+
+class ImplTabButton : public PushButton
+{
+public:
+ ImplTabButton( TabBar* pParent, WinBits nWinStyle = 0 ) :
+ PushButton( pParent, nWinStyle | WB_RECTSTYLE | WB_SMALLSTYLE | WB_NOLIGHTBORDER | WB_NOPOINTERFOCUS ) {}
+
+ TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual BOOL QueryDrop( const DropEvent& rDEvt );
+ virtual BOOL Drop( const DropEvent& rEvt );
+};
+
+// =======================================================================
+
+long ImplTabButton::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
+ {
+ if ( GetParent()->IsInEditMode() )
+ {
+ GetParent()->EndEditMode();
+ return TRUE;
+ }
+ }
+
+ return PushButton::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplTabButton::QueryDrop( const DropEvent& rDEvt )
+{
+ TabBar* pParent = GetParent();
+ Point aPos = OutputToScreenPixel( rDEvt.GetPosPixel() );
+ aPos = pParent->ScreenToOutputPixel( aPos );
+ BYTE nWindowType = rDEvt.GetWindowType();
+ if ( rDEvt.IsLeaveWindow() )
+ {
+ Size aWinSize = pParent->GetSizePixel();
+ if ( ((aPos.X() >= 0) && (aPos.X() < aWinSize.Width())) &&
+ ((aPos.Y() >= 0) && (aPos.Y() < aWinSize.Height())) )
+ nWindowType = 0;
+ }
+ DropEvent aNewDEvt( aPos, rDEvt.GetData(), rDEvt.GetAction(), nWindowType );
+ return pParent->QueryDrop( aNewDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplTabButton::Drop( const DropEvent& rDEvt )
+{
+ TabBar* pParent = GetParent();
+ Point aPos = OutputToScreenPixel( rDEvt.GetPosPixel() );
+ aPos = pParent->ScreenToOutputPixel( aPos );
+ DropEvent aNewDEvt( aPos, rDEvt.GetData(), rDEvt.GetAction(), rDEvt.GetWindowType() );
+ return pParent->Drop( aNewDEvt );
+}
+
+// =======================================================================
+
+// ----------------
+// - ImplTabSizer -
+// ----------------
+
+class ImplTabSizer : public Window
+{
+private:
+ Point maStartPos;
+ long mnOff;
+
+public:
+ ImplTabSizer( TabBar* pParent, WinBits nWinStyle = 0 );
+
+ TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
+ void ImplTrack( const Point& rMousePos );
+
+ virtual void MouseButtonDown( const MouseEvent& rMEvt );
+ virtual void Tracking( const TrackingEvent& rTEvt );
+ virtual void Paint( const Rectangle& rRect );
+ virtual BOOL QueryDrop( const DropEvent& rDEvt );
+ virtual BOOL Drop( const DropEvent& rEvt );
+};
+
+// -----------------------------------------------------------------------
+
+ImplTabSizer::ImplTabSizer( TabBar* pParent, WinBits nWinStyle ) :
+ Window( pParent, nWinStyle & WB_3DLOOK )
+{
+ SetPointer( Pointer( POINTER_HSIZEBAR ) );
+ SetSizePixel( Size( 7, 0 ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::ImplTrack( const Point& rMousePos )
+{
+ TabBar* pParent = GetParent();
+ Point aWinPos = pParent->GetPosPixel();
+ Size aWinSize = GetSizePixel();
+
+ aWinPos = pParent->GetParent()->OutputToScreenPixel( aWinPos );
+ pParent->mnSplitSize = rMousePos.X() - aWinPos.X() + (aWinSize.Width()-mnOff);
+ if ( pParent->mnSplitSize < TABBAR_MINSIZE )
+ pParent->mnSplitSize = TABBAR_MINSIZE;
+ pParent->Split();
+ pParent->Update();
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( GetParent()->IsInEditMode() )
+ {
+ GetParent()->EndEditMode();
+ return;
+ }
+
+ if ( rMEvt.IsLeft() )
+ {
+ Point aMousePos = rMEvt.GetPosPixel();
+ maStartPos = OutputToScreenPixel( aMousePos );
+ mnOff = aMousePos.X();
+ StartTracking();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( rTEvt.IsTrackingCanceled() )
+ ImplTrack( maStartPos );
+ GetParent()->mnSplitSize = 0;
+ }
+ else
+ ImplTrack( OutputToScreenPixel( rTEvt.GetMouseEvent().GetPosPixel() ) );
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTabSizer::Paint( const Rectangle& )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ DecorationView aDecoView( this );
+ long nOffX = 0;
+ Size aOutputSize = GetOutputSizePixel();
+
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( 0, 0 ), Point( 0, aOutputSize.Height()-1 ) );
+ nOffX++;
+ aOutputSize.Width()--;
+ }
+ aDecoView.DrawButton( Rectangle( Point( nOffX, 0 ), aOutputSize ), BUTTON_DRAW_NOLIGHTBORDER );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplTabSizer::QueryDrop( const DropEvent& rDEvt )
+{
+ TabBar* pParent = GetParent();
+ Point aPos = OutputToScreenPixel( rDEvt.GetPosPixel() );
+ aPos = pParent->ScreenToOutputPixel( aPos );
+ BYTE nWindowType = rDEvt.GetWindowType();
+ if ( rDEvt.IsLeaveWindow() )
+ {
+ Size aWinSize = pParent->GetSizePixel();
+ if ( ((aPos.X() >= 0) && (aPos.X() < aWinSize.Width())) &&
+ ((aPos.Y() >= 0) && (aPos.Y() < aWinSize.Height())) )
+ nWindowType = 0;
+ }
+ DropEvent aNewDEvt( aPos, rDEvt.GetData(), rDEvt.GetAction(), nWindowType );
+ return pParent->QueryDrop( aNewDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ImplTabSizer::Drop( const DropEvent& rDEvt )
+{
+ TabBar* pParent = GetParent();
+ Point aPos = OutputToScreenPixel( rDEvt.GetPosPixel() );
+ aPos = pParent->ScreenToOutputPixel( aPos );
+ DropEvent aNewDEvt( aPos, rDEvt.GetData(), rDEvt.GetAction(), rDEvt.GetWindowType() );
+ return pParent->Drop( aNewDEvt );
+}
+
+// =======================================================================
+
+// Heisst nicht Impl, da evtl. mal von aussen benutz- und ueberladbar
+
+// --------------
+// - TabBarEdit -
+// --------------
+
+class TabBarEdit : public Edit
+{
+private:
+ Timer maLoseFocusTimer;
+ BOOL mbPostEvt;
+
+ DECL_LINK( ImplEndEditHdl, void* );
+ DECL_LINK( ImplEndTimerHdl, void* );
+
+public:
+ TabBarEdit( TabBar* pParent, WinBits nWinStyle = 0 );
+
+ TabBar* GetParent() const { return (TabBar*)Window::GetParent(); }
+
+ void SetPostEvent() { mbPostEvt = TRUE; }
+ void ResetPostEvent() { mbPostEvt = FALSE; }
+
+ virtual long PreNotify( NotifyEvent& rNEvt );
+ virtual void LoseFocus();
+};
+
+// -----------------------------------------------------------------------
+
+TabBarEdit::TabBarEdit( TabBar* pParent, WinBits nWinStyle ) :
+ Edit( pParent, nWinStyle )
+{
+ mbPostEvt = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBarEdit::PreNotify( NotifyEvent& rNEvt )
+{
+ if ( rNEvt.GetType() == EVENT_KEYINPUT )
+ {
+ const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
+ if ( !pKEvt->GetKeyCode().GetModifier() )
+ {
+ if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
+ {
+ if ( !mbPostEvt )
+ {
+ if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
+ mbPostEvt = TRUE;
+ }
+ return TRUE;
+ }
+ else if ( pKEvt->GetKeyCode().GetCode() == KEY_ESCAPE )
+ {
+ if ( !mbPostEvt )
+ {
+ if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)TRUE ) )
+ mbPostEvt = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ }
+
+ return Edit::PreNotify( rNEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBarEdit::LoseFocus()
+{
+ if ( !mbPostEvt )
+ {
+ if ( PostUserEvent( LINK( this, TabBarEdit, ImplEndEditHdl ), (void*)FALSE ) )
+ mbPostEvt = TRUE;
+ }
+
+ Edit::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabBarEdit, ImplEndEditHdl, void*, pCancel )
+{
+ ResetPostEvent();
+ maLoseFocusTimer.Stop();
+
+ // We need this query, because the edit get a losefous event,
+ // when it shows the context menu or the insert symbol dialog
+ if ( !HasFocus() && HasChildPathFocus( TRUE ) )
+ {
+ maLoseFocusTimer.SetTimeout( 30 );
+ maLoseFocusTimer.SetTimeoutHdl( LINK( this, TabBarEdit, ImplEndTimerHdl ) );
+ maLoseFocusTimer.Start();
+ }
+ else
+ GetParent()->EndEditMode( pCancel != 0 );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabBarEdit, ImplEndTimerHdl, void*, pCancel )
+{
+ if ( HasFocus() )
+ return 0;
+
+ // We need this query, because the edit get a losefous event,
+ // when it shows the context menu or the insert symbol dialog
+ if ( HasChildPathFocus( TRUE ) )
+ maLoseFocusTimer.Start();
+ else
+ GetParent()->EndEditMode( TRUE );
+
+ return 0;
+}
+
+// =======================================================================
+
+void TabBar::ImplInit( WinBits nWinStyle )
+{
+ mpItemList = new ImplTabBarList;
+ mpFirstBtn = NULL;
+ mpPrevBtn = NULL;
+ mpNextBtn = NULL;
+ mpLastBtn = NULL;
+ mpSizer = NULL;
+ mpEdit = NULL;
+ mnMaxPageWidth = 0;
+ mnCurMaxWidth = 0;
+ mnOffX = 0;
+ mnOffY = 0;
+ mnOutWidth = 0;
+ mnSplitSize = 0;
+ mnSwitchTime = 0;
+ mnWinStyle = nWinStyle;
+ mnCurPageId = 0;
+ mnFirstPos = 0;
+ mnDropPos = 0;
+ mnSwitchId = 0;
+ mnEditId = 0;
+ mbFormat = TRUE;
+ mbFirstFormat = TRUE;
+ mbSizeFormat = TRUE;
+ mbAutoMaxWidth = TRUE;
+ mbInSwitching = FALSE;
+ mbAutoEditMode = FALSE;
+ mbEditCanceled = FALSE;
+ mbDropPos = FALSE;
+ mbInSelect = FALSE;
+ mbSelColor = FALSE;
+ mbSelTextColor = FALSE;
+
+ if ( nWinStyle & WB_3DTAB )
+ mnOffY++;
+
+ if ( nWinStyle & WB_DRAG )
+ EnableDrop();
+
+ ImplInitControls();
+ ImplInitSettings( TRUE, TRUE );
+ SetSizePixel( Size( 100, CalcWindowSizePixel().Height() ) );
+}
+
+// -----------------------------------------------------------------------
+
+TabBar::TabBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, (nWinStyle & WB_3DLOOK) | WB_CLIPCHILDREN )
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+TabBar::~TabBar()
+{
+ EndEditMode( TRUE );
+
+ // Controls loeschen
+ if ( mpPrevBtn )
+ delete mpPrevBtn;
+ if ( mpNextBtn )
+ delete mpNextBtn;
+ if ( mpFirstBtn )
+ delete mpFirstBtn;
+ if ( mpLastBtn )
+ delete mpLastBtn;
+ if ( mpSizer )
+ delete mpSizer;
+
+ // Alle Items loeschen
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Itemlist loeschen
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplInitSettings( BOOL bFont, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetToolFont();
+ if ( IsControlFont() )
+ aFont.Merge( GetControlFont() );
+ aFont.SetWeight( WEIGHT_BOLD );
+ SetZoomedPointFont( aFont );
+ }
+
+ if ( bBackground )
+ {
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplGetColors( Color& rFaceColor, Color& rFaceTextColor,
+ Color& rSelectColor, Color& rSelectTextColor )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( IsControlBackground() )
+ rFaceColor = GetControlBackground();
+ else
+ rFaceColor = rStyleSettings.GetFaceColor();
+ if ( IsControlForeground() )
+ rFaceTextColor = GetControlForeground();
+ else
+ rFaceTextColor = rStyleSettings.GetButtonTextColor();
+ if ( mbSelColor )
+ rSelectColor = maSelColor;
+ else
+ rSelectColor = rStyleSettings.GetWindowColor();
+ if ( mbSelTextColor )
+ rSelectTextColor = maSelTextColor;
+ else
+ rSelectTextColor = rStyleSettings.GetWindowTextColor();
+
+ // Bei 3D-Tabs wird Selektions- und Face-Farbe umgedreht, da die
+ // selektierten Tabs in 3D erscheinen sollen
+ if ( mnWinStyle & WB_3DTAB )
+ {
+ Color aTempColor = rFaceColor;
+ rFaceColor = rSelectColor;
+ rSelectColor = aTempColor;
+ aTempColor = rFaceTextColor;
+ rFaceTextColor = rSelectTextColor;
+ rSelectTextColor = rFaceTextColor;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::ImplCalcWidth()
+{
+ // Groessen muessen nur ermittelt werden, wenn sich Text aendert oder
+ // wenn der Font geaendert wurde
+ if ( !mbSizeFormat )
+ return FALSE;
+
+ // Breiten der Tabs mit dem fetten Font ermitteln
+ Font aFont = GetFont();
+ if ( aFont.GetWeight() != WEIGHT_BOLD )
+ {
+ aFont.SetWeight( WEIGHT_BOLD );
+ SetFont( aFont );
+ }
+
+ if ( mnMaxPageWidth )
+ mnCurMaxWidth = mnMaxPageWidth;
+ else if ( mbAutoMaxWidth )
+ {
+ mnCurMaxWidth = mnOutWidth-mnOffX-
+ TABBAR_OFFSET_X-TABBAR_OFFSET_X-
+ TABBAR_OFFSET_X2-TABBAR_OFFSET_X2-TABBAR_OFFSET_X2;
+ if ( mnCurMaxWidth < 1 )
+ mnCurMaxWidth = 1;
+ }
+ else
+ mnCurMaxWidth = 0;
+
+ BOOL bChanged = FALSE;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ long nNewWidth = GetTextWidth( pItem->maText );
+ if ( mnCurMaxWidth && (nNewWidth > mnCurMaxWidth) )
+ {
+ pItem->mbShort = TRUE;
+ nNewWidth = mnCurMaxWidth;
+ }
+ else
+ pItem->mbShort = FALSE;
+ nNewWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
+ if ( pItem->mnWidth != nNewWidth )
+ {
+ pItem->mnWidth = nNewWidth;
+ if ( !pItem->maRect.IsEmpty() )
+ bChanged = TRUE;
+ }
+ pItem = mpItemList->Next();
+ }
+ mbSizeFormat = FALSE;
+ mbFormat = TRUE;
+ return bChanged;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplFormat()
+{
+ ImplCalcWidth();
+
+ if ( !mbFormat )
+ return;
+
+ USHORT n = 0;
+ long x = mnOffX;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Bei allen nicht sichtbaren Tabs, wird ein leeres Rechteck
+ // gesetzt
+ if ( (n+1 < mnFirstPos) || (x > mnOutWidth) )
+ pItem->maRect.SetEmpty();
+ else
+ {
+ // Etwas von der Tab vor der ersten sichtbaren Page
+ // muss auch zu sehen sein
+ if ( n+1 == mnFirstPos )
+ pItem->maRect.Left() = x-pItem->mnWidth;
+ else
+ {
+ pItem->maRect.Left() = x;
+ x += pItem->mnWidth;
+ }
+ pItem->maRect.Right() = x+TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
+ pItem->maRect.Bottom() = maWinSize.Height()-1;
+ }
+
+ n++;
+ pItem = mpItemList->Next();
+ }
+
+ mbFormat = FALSE;
+
+ // Button enablen/disablen
+ ImplEnableControls();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::ImplGetLastFirstPos()
+{
+ USHORT nCount = (USHORT)(mpItemList->Count());
+ if ( !nCount || mbSizeFormat || mbFormat )
+ return 0;
+
+ USHORT nLastFirstPos = nCount-1;
+ long nWinWidth = mnOutWidth-mnOffX-TABBAR_OFFSET_X;
+ long nWidth = mpItemList->GetObject( nLastFirstPos )->mnWidth;
+ while ( nLastFirstPos && (nWidth < nWinWidth) )
+ {
+ nLastFirstPos--;
+ nWidth += mpItemList->GetObject( nLastFirstPos )->mnWidth;
+ }
+ if ( (nLastFirstPos != (USHORT)(mpItemList->Count()-1)) &&
+ (nWidth > nWinWidth) )
+ nLastFirstPos++;
+ return nLastFirstPos;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplInitControls()
+{
+ if ( mnWinStyle & WB_SIZEABLE )
+ {
+ if ( !mpSizer )
+ mpSizer = new ImplTabSizer( this, mnWinStyle & (WB_DRAG | WB_3DLOOK) );
+ mpSizer->Show();
+
+ if ( mnWinStyle & WB_DRAG )
+ mpSizer->EnableDrop();
+ }
+ else
+ {
+ if ( mpSizer )
+ {
+ delete mpSizer;
+ mpSizer = NULL;
+ }
+ }
+
+ Link aLink = LINK( this, TabBar, ImplClickHdl );
+
+ if ( mnWinStyle & (WB_MINSCROLL | WB_SCROLL) )
+ {
+ if ( !mpPrevBtn )
+ {
+ mpPrevBtn = new ImplTabButton( this, WB_REPEAT );
+ mpPrevBtn->SetSymbol( SYMBOL_PREV );
+ mpPrevBtn->SetClickHdl( aLink );
+ if ( mnWinStyle & WB_DRAG )
+ mpPrevBtn->EnableDrop();
+ }
+ mpPrevBtn->Show();
+
+ if ( !mpNextBtn )
+ {
+ mpNextBtn = new ImplTabButton( this, WB_REPEAT );
+ mpNextBtn->SetSymbol( SYMBOL_NEXT );
+ mpNextBtn->SetClickHdl( aLink );
+ if ( mnWinStyle & WB_DRAG )
+ mpNextBtn->EnableDrop();
+ }
+ mpNextBtn->Show();
+ }
+ else
+ {
+ if ( mpPrevBtn )
+ {
+ delete mpPrevBtn;
+ mpPrevBtn = NULL;
+ }
+ if ( mpNextBtn )
+ {
+ delete mpNextBtn;
+ mpNextBtn = NULL;
+ }
+ }
+
+ if ( mnWinStyle & WB_SCROLL )
+ {
+ if ( !mpFirstBtn )
+ {
+ mpFirstBtn = new ImplTabButton( this );
+ mpFirstBtn->SetSymbol( SYMBOL_FIRST );
+ mpFirstBtn->SetClickHdl( aLink );
+ if ( mnWinStyle & WB_DRAG )
+ mpFirstBtn->EnableDrop();
+ }
+ mpFirstBtn->Show();
+
+ if ( !mpLastBtn )
+ {
+ mpLastBtn = new ImplTabButton( this );
+ mpLastBtn->SetSymbol( SYMBOL_LAST );
+ mpLastBtn->SetClickHdl( aLink );
+ if ( mnWinStyle & WB_DRAG )
+ mpLastBtn->EnableDrop();
+ }
+ mpLastBtn->Show();
+ }
+ else
+ {
+ if ( mpFirstBtn )
+ {
+ delete mpFirstBtn;
+ mpFirstBtn = NULL;
+ }
+ if ( mpLastBtn )
+ {
+ delete mpLastBtn;
+ mpLastBtn = NULL;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplEnableControls()
+{
+ if ( mbSizeFormat || mbFormat )
+ return;
+
+ // Buttons enablen/disblen
+ BOOL bEnableBtn = mnFirstPos > 0;
+ if ( mpFirstBtn )
+ mpFirstBtn->Enable( bEnableBtn );
+ if ( mpPrevBtn )
+ mpPrevBtn->Enable( bEnableBtn );
+
+ bEnableBtn = mnFirstPos < ImplGetLastFirstPos();
+ if ( mpNextBtn )
+ mpNextBtn->Enable( bEnableBtn );
+ if ( mpLastBtn )
+ mpLastBtn->Enable( bEnableBtn );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ImplShowPage( USHORT nPos )
+{
+ // Breite berechnen
+ long nWidth = GetOutputSizePixel().Width();
+ if ( nWidth >= TABBAR_OFFSET_X )
+ nWidth -= TABBAR_OFFSET_X;
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( nPos < mnFirstPos )
+ SetFirstPageId( pItem->mnId );
+ else if ( pItem->maRect.Right() > nWidth )
+ {
+ while ( pItem->maRect.Right() > nWidth )
+ {
+ USHORT nNewPos = mnFirstPos+1;
+ SetFirstPageId( GetPageId( nNewPos ) );
+ ImplFormat();
+ if ( nNewPos != mnFirstPos )
+ break;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TabBar, ImplClickHdl, ImplTabButton*, pBtn )
+{
+ EndEditMode();
+
+ USHORT nNewPos = mnFirstPos;
+
+ if ( pBtn == mpFirstBtn )
+ nNewPos = 0;
+ else if ( pBtn == mpPrevBtn )
+ {
+ if ( mnFirstPos )
+ nNewPos = mnFirstPos-1;
+ }
+ else if ( pBtn == mpNextBtn )
+ {
+ USHORT nCount = GetPageCount();
+ if ( mnFirstPos < nCount )
+ nNewPos = mnFirstPos+1;
+ }
+ else
+ {
+ USHORT nCount = GetPageCount();
+ if ( nCount )
+ nNewPos = nCount-1;
+ }
+
+ if ( nNewPos != mnFirstPos )
+ SetFirstPageId( GetPageId( nNewPos ) );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeaveWindow() )
+ mbInSelect = FALSE;
+
+ Window::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ // Bei Klick in unser Fenster EditModus nur beenden und Klick nicht
+ // ausfuehren
+ if ( IsInEditMode() )
+ {
+ EndEditMode();
+ return;
+ }
+
+ if ( !rMEvt.IsLeft() )
+ {
+ Window::MouseButtonDown( rMEvt );
+ return;
+ }
+
+ ImplTabBarItem* pItem;
+ USHORT nSelId = GetPageId( rMEvt.GetPosPixel() );
+
+ if ( rMEvt.IsMod2() && mbAutoEditMode && nSelId )
+ {
+ if ( StartEditMode( nSelId ) )
+ return;
+ }
+
+ if ( (rMEvt.GetMode() & (MOUSE_MULTISELECT | MOUSE_RANGESELECT)) && (rMEvt.GetClicks() == 1) )
+ {
+ if ( nSelId )
+ {
+ USHORT nPos = GetPagePos( nSelId );
+ BOOL bSelectTab = FALSE;
+ pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable )
+ {
+ if ( (rMEvt.GetMode() & MOUSE_MULTISELECT) && (mnWinStyle & WB_MULTISELECT) )
+ {
+ if ( nSelId != mnCurPageId )
+ {
+ SelectPage( nSelId, !IsPageSelected( nSelId ) );
+ bSelectTab = TRUE;
+ }
+ }
+ else if ( mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT) )
+ {
+ bSelectTab = TRUE;
+ USHORT n;
+ BOOL bSelect;
+ USHORT nCurPos = GetPagePos( mnCurPageId );
+ if ( nPos <= nCurPos )
+ {
+ // Alle Tabs bis zur angeklickten Tab deselektieren
+ // und alle Tabs von der angeklickten Tab bis
+ // zur aktuellen Position selektieren
+ n = 0;
+ while ( n < nCurPos )
+ {
+ pItem = mpItemList->GetObject( n );
+ if ( n < nPos )
+ bSelect = FALSE;
+ else
+ bSelect = TRUE;
+
+ if ( pItem->mbSelect != bSelect )
+ {
+ pItem->mbSelect = bSelect;
+ if ( !pItem->maRect.IsEmpty() )
+ Invalidate( pItem->maRect );
+ }
+
+ n++;
+ }
+ }
+
+ if ( nPos >= nCurPos )
+ {
+ // Alle Tabs von der aktuellen bis zur angeklickten
+ // Tab selektieren und alle Tabs von der angeklickten
+ // Tab bis zur letzten Tab deselektieren
+ USHORT nCount = (USHORT)mpItemList->Count();
+ n = nCurPos;
+ while ( n < nCount )
+ {
+ pItem = mpItemList->GetObject( n );
+
+ if ( n <= nPos )
+ bSelect = TRUE;
+ else
+ bSelect = FALSE;
+
+ if ( pItem->mbSelect != bSelect )
+ {
+ pItem->mbSelect = bSelect;
+ if ( !pItem->maRect.IsEmpty() )
+ Invalidate( pItem->maRect );
+ }
+
+ n++;
+ }
+ }
+ }
+
+ // Gegebenenfalls muss die selektierte Tab gescrollt werden
+ if ( bSelectTab )
+ {
+ ImplShowPage( nPos );
+ Update();
+ Select();
+ }
+ }
+ else
+ ImplShowPage( nPos );
+ mbInSelect = TRUE;
+
+ return;
+ }
+ }
+ else if ( rMEvt.GetClicks() == 2 )
+ {
+ // Gegebenenfalls den Double-Click-Handler rufen
+ if ( !rMEvt.GetModifier() && (!nSelId || (nSelId == mnCurPageId)) )
+ {
+ USHORT nOldCurId = mnCurPageId;
+ mnCurPageId = nSelId;
+ DoubleClick();
+ // Abfrage, da im DoubleClick-Handler die aktuelle Seite
+ // umgeschaltet werden konnte
+ if ( mnCurPageId == nSelId )
+ mnCurPageId = nOldCurId;
+ }
+
+ return;
+ }
+ else
+ {
+ if ( nSelId )
+ {
+ // Nur Select ausfuehren, wenn noch nicht aktuelle Page
+ if ( nSelId != mnCurPageId )
+ {
+ USHORT nPos = GetPagePos( nSelId );
+ pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable )
+ {
+ if ( !pItem->mbSelect )
+ {
+ // Muss invalidiert werden
+ BOOL bUpdate = FALSE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ bUpdate = TRUE;
+
+ // Alle selektierten Items deselektieren
+ pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
+ {
+ pItem->mbSelect = FALSE;
+ if ( bUpdate )
+ Invalidate( pItem->maRect );
+ }
+
+ pItem = mpItemList->Next();
+ }
+ }
+
+ if ( DeactivatePage() )
+ {
+ SetCurPageId( nSelId );
+ Update();
+ ActivatePage();
+ Select();
+ }
+ }
+ else
+ ImplShowPage( nPos );
+ mbInSelect = TRUE;
+ }
+
+ return;
+ }
+ }
+
+ Window::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ mbInSelect = FALSE;
+ Window::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Paint( const Rectangle& )
+{
+ // Items berechnen und ausgeben
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ ImplTabBarItem* pItem;
+
+ // kein Item, dann auch nichts zu tun
+ if ( nItemCount )
+ {
+ // TabBar muss formatiert sein
+ ImplFormat();
+
+ // Beim ersten Format auch dafuer sorgen, das aktuelle TabPage
+ // sichtbar wird
+ if ( mbFirstFormat )
+ {
+ mbFirstFormat = FALSE;
+
+ if ( mnCurPageId && (mnFirstPos == 0) && !mbDropPos )
+ {
+ pItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
+ if ( pItem->maRect.IsEmpty() )
+ {
+ // mbDropPos setzen (bzw. misbrauchen) um Invalidate()
+ // zu unterbinden
+ mbDropPos = TRUE;
+ SetFirstPageId( mnCurPageId );
+ mbDropPos = FALSE;
+ if ( mnFirstPos != 0 )
+ ImplFormat();
+ }
+ }
+ }
+ }
+
+ // Farben ermitteln
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aFaceColor;
+ Color aSelectColor;
+ Color aFaceTextColor;
+ Color aSelectTextColor;
+ ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
+
+ // Font selektieren
+ Font aFont = GetFont();
+ Font aLightFont = aFont;
+ aLightFont.SetWeight( WEIGHT_LIGHT );
+
+ // Bei Border oben und unten einen Strich extra malen
+ if ( (mnWinStyle & WB_BORDER) || (mnWinStyle & WB_TOPBORDER) )
+ {
+ Size aOutputSize = GetOutputSizePixel();
+
+ // Bei 3D-Tabs wird auch der Border in 3D gemalt
+ if ( mnWinStyle & WB_3DTAB )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( mnOffX, 0 ), Point( aOutputSize.Width(), 0 ) );
+ }
+
+ // Border malen (Strich oben und Strich unten)
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ DrawLine( Point( mnOffX, mnOffY ), Point( aOutputSize.Width()-1, mnOffY ) );
+ }
+ else
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+
+ // Items ausgeben
+ if ( nItemCount )
+ {
+ // letzten sichtbaren Eintrag suchen
+ USHORT n = mnFirstPos+1;
+ if ( n >= nItemCount )
+ n = nItemCount-1;
+ pItem = mpItemList->Seek( n );
+ while ( pItem )
+ {
+ if ( !pItem->maRect.IsEmpty() )
+ {
+ n++;
+ pItem = mpItemList->Next();
+ }
+ else
+ break;
+ }
+
+ // Alle Tabs ausgeben (von hinten nach vorn und aktuellen zuletzt)
+ if ( pItem )
+ n--;
+ else if ( n >= nItemCount )
+ n = nItemCount-1;
+ pItem = mpItemList->Seek( n );
+ ImplTabBarItem* pCurItem = NULL;
+ while ( pItem )
+ {
+ // CurrentItem als letztes ausgeben, da es alle anderen ueberdeckt
+ if ( !pCurItem && (pItem->mnId == mnCurPageId) )
+ {
+ pCurItem = pItem;
+ pItem = mpItemList->Prev();
+ if ( !pItem )
+ pItem = pCurItem;
+ continue;
+ }
+
+ if ( !pItem->maRect.IsEmpty() )
+ {
+ Rectangle aRect = pItem->maRect;
+
+ // Aktuelle Page wird mit einem fetten Font ausgegeben
+ if ( pItem->mnId == mnCurPageId )
+ SetFont( aFont );
+ else
+ SetFont( aLightFont );
+
+ // Je nach Status die richtige FillInBrush setzen
+ if ( pItem->mbSelect || (pItem->mnId == mnCurPageId) )
+ {
+ SetFillColor( aSelectColor );
+ SetTextColor( aSelectTextColor );
+ }
+ else
+ {
+ SetFillColor( aFaceColor );
+ SetTextColor( aFaceTextColor );
+ }
+
+ // Muss Font Kursiv geschaltet werden
+ if ( pItem->mnBits & TPB_SPECIAL )
+ {
+ SetTextColor( Color( COL_LIGHTBLUE ) );
+ }
+
+ // Position der Page berechnen
+ Point aPos0 = Point( aRect.Left(), mnOffY );
+ Point aPos1 = Point( aRect.Left()+TABBAR_OFFSET_X, aRect.Bottom() );
+ Point aPos2 = Point( aRect.Right()-TABBAR_OFFSET_X, aRect.Bottom() );
+ Point aPos3 = Point( aRect.Right(), mnOffY );
+
+ // Zuerst geben wir das Polygon gefuellt aus
+ Polygon aPoly( 4 );
+ aPoly[0] = aPos0;
+ aPoly[1] = aPos1;
+ aPoly[2] = aPos2;
+ aPoly[3] = aPos3;
+ DrawPolygon( aPoly );
+
+ // Danach den Text zentiert ausgeben
+ XubString aText = pItem->maText;
+ if ( pItem->mbShort )
+ aText = GetEllipsisString( aText, mnCurMaxWidth, TEXT_DRAW_ENDELLIPSIS );
+ Size aRectSize = aRect.GetSize();
+ long nTextWidth = GetTextWidth( aText );
+ long nTextHeight = GetTextHeight();
+ Point aTxtPos( aRect.Left()+(aRectSize.Width()-nTextWidth)/2,
+ (aRectSize.Height()-nTextHeight)/2 );
+ if ( !pItem->mbEnable )
+ DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, (TEXT_DRAW_DISABLE | TEXT_DRAW_MNEMONIC) );
+ else
+ DrawText( aTxtPos, aText );
+
+ // Jetzt im Inhalt den 3D-Effekt ausgeben
+ aPos0.X()++;
+ aPos1.X()++;
+ aPos2.X()--;
+ aPos3.X()--;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( aPos0, aPos1 );
+
+ if ( !pItem->mbSelect && (pItem->mnId != mnCurPageId) )
+ {
+ DrawLine( Point( aPos0.X(), aPos0.Y()+1 ),
+ Point( aPos3.X(), aPos3.Y()+1 ) );
+ }
+
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( aPos2, aPos3 );
+ aPos1.X()--;
+ aPos1.Y()--;
+ aPos2.Y()--;
+ DrawLine( aPos1, aPos2 );
+
+ // Da etwas uebermalt werden konnte, muessen wir die Polygon-
+ // umrandung nocheinmal ausgeben
+ SetLineColor( rStyleSettings.GetDarkShadowColor() );
+ SetFillColor();
+ DrawPolygon( aPoly );
+
+ // Beim dem aktuellen Tab die restlichten Ausgaben vornehmen und
+ // die Schleife abbrechen, da die aktuelle Tab als letztes
+ // ausgegeben wird
+ if ( pItem == pCurItem )
+ {
+ // Beim aktuellen Item muss der oberstes Strich geloescht
+ // werden
+ SetLineColor();
+ SetFillColor( aSelectColor );
+ Rectangle aDelRect( aPos0, aPos3 );
+ DrawRect( aDelRect );
+ if ( mnWinStyle & WB_3DTAB )
+ {
+ aDelRect.Top()--;
+ DrawRect( aDelRect );
+ }
+
+ break;
+ }
+
+ pItem = mpItemList->Prev();
+ }
+ else
+ {
+ if ( pItem == pCurItem )
+ break;
+
+ pItem = NULL;
+ }
+
+ if ( !pItem )
+ pItem = pCurItem;
+ }
+ }
+
+ // Font wieder herstellen
+ SetFont( aFont );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Resize()
+{
+ Size aNewSize = GetOutputSizePixel();
+
+ // Sizer anordnen
+ if ( mpSizer )
+ {
+ Size aSizerSize = mpSizer->GetSizePixel();
+ Point aNewSizerPos( aNewSize.Width()-aSizerSize.Width(), 0 );
+ Size aNewSizerSize( aSizerSize.Width(), aNewSize.Height() );
+ mpSizer->SetPosSizePixel( aNewSizerPos, aNewSizerSize );
+ mnOutWidth = aNewSize.Width() - aSizerSize.Width() - 1;
+ }
+ else
+ mnOutWidth = aNewSize.Width()-1;
+
+ // Scroll-Buttons anordnen
+ long nHeight = aNewSize.Height();
+ if ( nHeight != maWinSize.Height() )
+ {
+ long nX = 0;
+ Size aBtnSize( nHeight, nHeight );
+ if ( mpFirstBtn )
+ {
+ mpFirstBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nHeight;
+ }
+ if ( mpPrevBtn )
+ {
+ mpPrevBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nHeight;
+ }
+ if ( mpNextBtn )
+ {
+ mpNextBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nHeight;
+ }
+ if ( mpLastBtn )
+ {
+ mpLastBtn->SetPosSizePixel( Point( nX, 0 ), aBtnSize );
+ nX += nHeight;
+ }
+ mnOffX = nX;
+ }
+
+ // Groesse merken
+ maWinSize = aNewSize;
+
+ // Neu formatieren
+ mbSizeFormat = TRUE;
+ if ( IsReallyVisible() )
+ {
+ if ( ImplCalcWidth() )
+ Invalidate();
+ ImplFormat();
+ }
+
+ // Button enablen/disablen
+ ImplEnableControls();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ USHORT nItemId = GetPageId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+ if ( nItemId )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ XubString aStr = GetHelpText( nItemId );
+ if ( aStr.Len() )
+ {
+ Rectangle aItemRect = GetPageRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ return;
+ }
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ ULONG nHelpId = GetHelpId( nItemId );
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId );
+ return;
+ }
+ }
+
+ // Bei Quick- oder Ballloon-Help zeigen wir den Text an,
+ // wenn dieser abgeschnitten oder nicht voll sichtbar ist
+ if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
+ {
+ USHORT nPos = GetPagePos( nItemId );
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem->mbShort ||
+ (pItem->maRect.Right()-TABBAR_OFFSET_X-5 > mnOutWidth) )
+ {
+ Rectangle aItemRect = GetPageRect( nItemId );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ XubString aStr = mpItemList->GetObject( nPos )->maText;
+ if ( aStr.Len() )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ return;
+ }
+ }
+ }
+ }
+
+ Window::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( (mbSizeFormat || mbFormat) && mpItemList->Count() )
+ ImplFormat();
+ }
+ else if ( (nType == STATE_CHANGE_ZOOM) ||
+ (nType == STATE_CHANGE_CONTROLFONT) )
+ {
+ ImplInitSettings( TRUE, FALSE );
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
+ Invalidate();
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings( FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ ImplInitSettings( TRUE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Split()
+{
+ maSplitHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::ActivatePage()
+{
+ maActivatePageHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::DeactivatePage()
+{
+ if ( maDeactivatePageHdl.IsSet() )
+ return maDeactivatePageHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::StartRenaming()
+{
+ if ( maStartRenamingHdl.IsSet() )
+ return maStartRenamingHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::AllowRenaming()
+{
+ if ( maAllowRenamingHdl.IsSet() )
+ return maAllowRenamingHdl.Call( this );
+ else
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EndRenaming()
+{
+ maEndRenamingHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::InsertPage( USHORT nPageId, const XubString& rText,
+ TabBarPageBits nBits, USHORT nPos )
+{
+ DBG_ASSERT( nPageId, "TabBar::InsertPage(): PageId == 0" );
+ DBG_ASSERT( GetPagePos( nPageId ) == TAB_PAGE_NOTFOUND,
+ "TabBar::InsertPage(): PageId already exists" );
+ DBG_ASSERT( nBits <= TPB_SPECIAL, "TabBar::InsertPage(): nBits is wrong" );
+
+ // PageItem anlegen und in die Item-Liste eintragen
+ ImplTabBarItem* pItem = new ImplTabBarItem( nPageId, rText, nBits );
+ mpItemList->Insert( pItem, nPos );
+ mbSizeFormat = TRUE;
+
+ // CurPageId gegebenenfalls setzen
+ if ( !mnCurPageId )
+ mnCurPageId = nPageId;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::RemovePage( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Existiert Item
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ if ( mnCurPageId == nPageId )
+ mnCurPageId = 0;
+
+ // Testen, ob erste sichtbare Seite verschoben werden muss
+ if ( mnFirstPos > nPos )
+ mnFirstPos--;
+
+ // Item-Daten loeschen
+ delete mpItemList->Remove( nPos );
+ mbFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::MovePage( USHORT nPageId, USHORT nNewPos )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos < nNewPos )
+ nNewPos--;
+
+ if ( nPos == nNewPos )
+ return;
+
+ // Existiert Item
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ // TabBar-Item in der Liste verschieben
+ ImplTabBarItem* pItem = mpItemList->Remove( nPos );
+ mpItemList->Insert( pItem, nNewPos );
+ mbFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::Clear()
+{
+ // Alle Items loeschen
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ // Item-Daten loeschen
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ // Items aus der Liste loeschen
+ mpItemList->Clear();
+ mbSizeFormat = TRUE;
+ mnCurPageId = 0;
+ mnFirstPos = 0;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EnablePage( USHORT nPageId, BOOL bEnable )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbEnable != bEnable )
+ {
+ pItem->mbEnable = bEnable;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate( pItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::IsPageEnabled( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mbEnable;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetPageBits( USHORT nPageId, TabBarPageBits nBits )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mnBits != nBits )
+ {
+ pItem->mnBits = nBits;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate( pItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+TabBarPageBits TabBar::GetPageBits( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnBits;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPageCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPageId( USHORT nPos ) const
+{
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPagePos( USHORT nPageId ) const
+{
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nPageId )
+ return (USHORT)mpItemList->GetCurPos();
+
+ pItem = mpItemList->Next();
+ }
+
+ return TAB_PAGE_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetPageId( const Point& rPos ) const
+{
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->maRect.IsInside( rPos ) )
+ return pItem->mnId;
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle TabBar::GetPageRect( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maRect;
+ else
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetCurPageId( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Wenn Item nicht existiert, dann nichts machen
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ // Wenn sich aktuelle Page nicht geaendert hat, dann muessen wir
+ // jetzt nichts mehr machen
+ if ( nPageId == mnCurPageId )
+ return;
+
+ // Muss invalidiert werden
+ BOOL bUpdate = FALSE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ bUpdate = TRUE;
+
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ ImplTabBarItem* pOldItem;
+
+ if ( mnCurPageId )
+ pOldItem = mpItemList->GetObject( GetPagePos( mnCurPageId ) );
+ else
+ pOldItem = NULL;
+
+ // Wenn Page nicht selektiert, dann vorher selektierte Seite
+ // deselktieren, wenn dies die einzige selektierte Seite ist
+ if ( !pItem->mbSelect && pOldItem )
+ {
+ USHORT nSelPageCount = GetSelectPageCount();
+ if ( nSelPageCount == 1 )
+ pOldItem->mbSelect = FALSE;
+ pItem->mbSelect = TRUE;
+ }
+
+ mnCurPageId = nPageId;
+ mbFormat = TRUE;
+
+ // Dafuer sorgen, das aktuelle Page sichtbar wird
+ if ( IsReallyVisible() )
+ {
+ if ( nPos < mnFirstPos )
+ SetFirstPageId( nPageId );
+ else
+ {
+ // sichtbare Breite berechnen
+ long nWidth = mnOutWidth;
+ if ( nWidth > TABBAR_OFFSET_X )
+ nWidth -= TABBAR_OFFSET_X;
+
+ if ( pItem->maRect.IsEmpty() )
+ ImplFormat();
+
+ while ( (pItem->maRect.Right() > nWidth) ||
+ pItem->maRect.IsEmpty() )
+ {
+ USHORT nNewPos = mnFirstPos+1;
+ // Dafuer sorgen, das min. die aktuelle TabPages als
+ // erste TabPage sichtbar ist
+ if ( nNewPos >= nPos )
+ {
+ SetFirstPageId( nPageId );
+ break;
+ }
+ else
+ SetFirstPageId( GetPageId( nNewPos ) );
+ ImplFormat();
+ // Falls erste Seite nicht weitergeschaltet wird, dann
+ // koennen wir abbrechen
+ if ( nNewPos != mnFirstPos )
+ break;
+ }
+ }
+ }
+
+ // Leiste neu ausgeben
+ if ( bUpdate )
+ {
+ Invalidate( pItem->maRect );
+ if ( pOldItem )
+ Invalidate( pOldItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetFirstPageId( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ // Wenn Item nicht existiert, dann FALSE zurueckgeben
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ if ( nPos != mnFirstPos )
+ {
+ // Dafuer sorgen, das nach Moeglichkteit soviele Pages wie
+ // moeglich sichtbar sind
+ ImplFormat();
+ USHORT nLastFirstPos = ImplGetLastFirstPos();
+ USHORT nNewPos;
+ if ( nPos > nLastFirstPos )
+ nNewPos = nLastFirstPos;
+ else
+ nNewPos = nPos;
+
+ if ( nNewPos != mnFirstPos )
+ {
+ mnFirstPos = nNewPos;
+ mbFormat = TRUE;
+
+ // Leiste neu ausgeben (Achtung: mbDropPos beachten, da wenn
+ // dieses Flag gesetzt ist, wird direkt gepaintet)
+ if ( IsReallyVisible() && IsUpdateMode() && !mbDropPos )
+ Invalidate();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SelectPage( USHORT nPageId, BOOL bSelect )
+{
+ USHORT nPos = GetPagePos( nPageId );
+
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem->mbSelect != bSelect )
+ {
+ pItem->mbSelect = bSelect;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate( pItem->maRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SelectPageRange( BOOL bSelect, USHORT nStartPos, USHORT nEndPos )
+{
+ Rectangle aPaintRect;
+ USHORT nPos = nStartPos;
+ ImplTabBarItem* pItem = mpItemList->Seek( nPos );
+ while ( pItem && (nPos <= nEndPos) )
+ {
+ if ( (pItem->mbSelect != bSelect) && (pItem->mnId != mnCurPageId) )
+ {
+ pItem->mbSelect = bSelect;
+ aPaintRect.Union( pItem->maRect );
+ }
+
+ nPos++;
+ pItem = mpItemList->Next();
+ }
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() && !aPaintRect.IsEmpty() )
+ Invalidate( aPaintRect );
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetSelectPage( USHORT nSelIndex ) const
+{
+ USHORT nSelected = 0;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect )
+ nSelected++;
+
+ if ( nSelected == nSelIndex )
+ return pItem->mnId;
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::GetSelectPageCount() const
+{
+ USHORT nSelected = 0;
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect )
+ nSelected++;
+
+ pItem = mpItemList->Next();
+ }
+
+ return nSelected;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::IsPageSelected( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mbSelect;
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::StartEditMode( USHORT nPageId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( mpEdit || (nPos == TAB_PAGE_NOTFOUND) || (mnOutWidth < 8) )
+ return FALSE;
+
+ mnEditId = nPageId;
+ if ( StartRenaming() )
+ {
+ ImplShowPage( nPos );
+ ImplFormat();
+ Update();
+
+ mpEdit = new TabBarEdit( this, WB_CENTER );
+ Rectangle aRect = GetPageRect( mnEditId );
+ long nX = aRect.Left()+TABBAR_OFFSET_X+(TABBAR_OFFSET_X2/2);
+ long nWidth = aRect.GetWidth()-(TABBAR_OFFSET_X*2)-TABBAR_OFFSET_X2;
+ if ( mnEditId != GetCurPageId() )
+ nX += 1;
+ if ( nX+nWidth > mnOutWidth )
+ nWidth = mnOutWidth-nX;
+ if ( nWidth < 3 )
+ {
+ nX = aRect.Left();
+ nWidth = aRect.GetWidth();
+ }
+ mpEdit->SetText( GetPageText( mnEditId ) );
+ mpEdit->SetPosSizePixel( nX, aRect.Top()+mnOffY+1, nWidth, aRect.GetHeight()-3 );
+ Font aFont = GetPointFont();
+ Color aForegroundColor;
+ Color aBackgroundColor;
+ Color aFaceColor;
+ Color aSelectColor;
+ Color aFaceTextColor;
+ Color aSelectTextColor;
+ ImplGetColors( aFaceColor, aFaceTextColor, aSelectColor, aSelectTextColor );
+ if ( mnEditId != GetCurPageId() )
+ aFont.SetWeight( WEIGHT_LIGHT );
+ if ( IsPageSelected( mnEditId ) || (mnEditId == GetCurPageId()) )
+ {
+ aForegroundColor = aSelectTextColor;
+ aBackgroundColor = aSelectColor;
+ }
+ else
+ {
+ aForegroundColor = aFaceTextColor;
+ aBackgroundColor = aFaceColor;
+ }
+ if ( GetPageBits( mnEditId ) & TPB_SPECIAL )
+ aForegroundColor = Color( COL_LIGHTBLUE );
+ mpEdit->SetControlFont( aFont );
+ mpEdit->SetControlForeground( aForegroundColor );
+ mpEdit->SetControlBackground( aBackgroundColor );
+ mpEdit->GrabFocus();
+ mpEdit->SetSelection( Selection( 0, mpEdit->GetText().Len() ) );
+ mpEdit->Show();
+ return TRUE;
+ }
+ else
+ {
+ mnEditId = 0;
+ return FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EndEditMode( BOOL bCancel )
+{
+ if ( mpEdit )
+ {
+ // call hdl
+ BOOL bEnd = TRUE;
+ mbEditCanceled = bCancel;
+ maEditText = mpEdit->GetText();
+ mpEdit->SetPostEvent();
+ if ( !bCancel )
+ {
+ long nAllowRenaming = AllowRenaming();
+ if ( nAllowRenaming == TAB_RENAMING_YES )
+ SetPageText( mnEditId, maEditText );
+ else if ( nAllowRenaming == TAB_RENAMING_NO )
+ bEnd = FALSE;
+ else // nAllowRenaming == TAB_RENAMING_CANCEL
+ mbEditCanceled = TRUE;
+ }
+
+ // renaming not allowed, than reset edit data
+ if ( !bEnd )
+ {
+ mpEdit->ResetPostEvent();
+ mpEdit->GrabFocus();
+ }
+ else
+ {
+ // close edit and call end hdl
+ delete mpEdit;
+ mpEdit = NULL;
+ EndRenaming();
+ mnEditId = 0;
+ }
+
+ // reset
+ maEditText.Erase();
+ mbEditCanceled = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetMaxPageWidth( long nMaxWidth )
+{
+ if ( mnMaxPageWidth != nMaxWidth )
+ {
+ mnMaxPageWidth = nMaxWidth;
+ mbSizeFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectColor()
+{
+ if ( mbSelColor )
+ {
+ maSelColor = Color( COL_TRANSPARENT );
+ mbSelColor = FALSE;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectColor( const Color& rColor )
+{
+ if ( rColor.GetTransparency() )
+ {
+ if ( mbSelColor )
+ {
+ maSelColor = Color( COL_TRANSPARENT );
+ mbSelColor = FALSE;
+ Invalidate();
+ }
+ }
+ else
+ {
+ if ( maSelColor != rColor )
+ {
+ maSelColor = rColor;
+ mbSelColor = TRUE;
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectTextColor()
+{
+ if ( mbSelTextColor )
+ {
+ maSelTextColor = Color( COL_TRANSPARENT );
+ mbSelTextColor = FALSE;
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetSelectTextColor( const Color& rColor )
+{
+ if ( rColor.GetTransparency() )
+ {
+ if ( mbSelTextColor )
+ {
+ maSelTextColor = Color( COL_TRANSPARENT );
+ mbSelTextColor = FALSE;
+ Invalidate();
+ }
+ }
+ else
+ {
+ if ( maSelTextColor != rColor )
+ {
+ maSelTextColor = rColor;
+ mbSelTextColor = TRUE;
+ Invalidate();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetPageText( USHORT nPageId, const XubString& rText )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ mpItemList->GetObject( nPos )->maText = rText;
+ mbSizeFormat = TRUE;
+
+ // Leiste neu ausgeben
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString TabBar::GetPageText( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maText;
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetHelpText( USHORT nPageId, const XubString& rText )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ mpItemList->GetObject( nPos )->maHelpText = rText;
+}
+
+// -----------------------------------------------------------------------
+
+XubString TabBar::GetHelpText( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ {
+ ImplTabBarItem* pItem = mpItemList->GetObject( nPos );
+ if ( !pItem->maHelpText.Len() && pItem->mnHelpId )
+ {
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pItem->maHelpText = pHelp->GetHelpText( pItem->mnHelpId );
+ }
+
+ return pItem->maHelpText;
+ }
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetHelpId( USHORT nPageId, ULONG nHelpId )
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ mpItemList->GetObject( nPos )->mnHelpId = nHelpId;
+}
+
+// -----------------------------------------------------------------------
+
+ULONG TabBar::GetHelpId( USHORT nPageId ) const
+{
+ USHORT nPos = GetPagePos( nPageId );
+ if ( nPos != TAB_PAGE_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnHelpId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+long TabBar::GetMinSize() const
+{
+ long nMinSize = TABBAR_MINSIZE + TABBAR_OFFSET_X;
+ if ( mnWinStyle & WB_MINSCROLL )
+ nMinSize += mpPrevBtn->GetSizePixel().Width()*2;
+ else if ( mnWinStyle & WB_SCROLL )
+ nMinSize += mpFirstBtn->GetSizePixel().Width()*4;
+ return nMinSize;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
+{
+ if ( !(mnWinStyle & WB_DRAG) || (rCEvt.GetCommand() != COMMAND_STARTDRAG) )
+ return FALSE;
+
+ // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
+ // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
+ // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
+ // dies nur bei einer Mausaktion.
+ // Ausserdem machen wir das nur, wenn kein Select() ausgeloest wurde,
+ // da der Select schon den Bereich gescrollt haben kann
+ if ( rCEvt.IsMouseEvent() && !mbInSelect )
+ {
+ USHORT nSelId = GetPageId( rCEvt.GetMousePosPixel() );
+
+ // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
+ if ( !nSelId )
+ return FALSE;
+
+ // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
+ // Seite setzen und Select rufen.
+ if ( !IsPageSelected( nSelId ) )
+ {
+ if ( DeactivatePage() )
+ {
+ SetCurPageId( nSelId );
+ Update();
+ ActivatePage();
+ Select();
+ }
+ else
+ return FALSE;
+ }
+ }
+ mbInSelect = FALSE;
+
+
+#ifdef MAC
+ PolyPolygon aPolyPoly;
+
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mbSelect && !pItem->maRect.IsEmpty() )
+ {
+ // Polygon fuer DragRegion aufbauen
+ Rectangle aRect = pItem->maRect;
+ Polygon aPoly( 4 );
+ aPoly[0] = Point( aRect.Left(), mnOffY );
+ aPoly[1] = Point( aRect.Left()+TABBAR_OFFSET_X, aRect.Bottom() );
+ aPoly[2] = Point( aRect.Right()-TABBAR_OFFSET_X, aRect.Bottom() );
+ aPoly[3] = Point( aRect.Right(), mnOffY );
+ aPolyPoly.Insert( aPoly );
+ }
+
+ pItem = mpItemList->Next();
+ }
+
+ Region aRegion( aPolyPoly );
+#else
+ Region aRegion;
+#endif
+
+ // Region zuweisen
+ rRegion = aRegion;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT TabBar::ShowDropPos( const Point& rPos )
+{
+ ImplTabBarItem* pItem;
+ USHORT nDropId;
+ USHORT nNewDropPos;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ short nScroll = 0;
+
+ if ( rPos.X() > mnOutWidth-TABBAR_DRAG_SCROLLOFF )
+ {
+ pItem = mpItemList->GetObject( mpItemList->Count()-1 );
+ if ( !pItem->maRect.IsEmpty() && (rPos.X() > pItem->maRect.Right()) )
+ nNewDropPos = (USHORT)mpItemList->Count();
+ else
+ {
+ nNewDropPos = mnFirstPos+1;
+ nScroll = 1;
+ }
+ }
+ else if ( (rPos.X() <= mnOffX) ||
+ (!mnOffX && (rPos.X() <= TABBAR_DRAG_SCROLLOFF)) )
+ {
+ if ( mnFirstPos )
+ {
+ nNewDropPos = mnFirstPos;
+ nScroll = -1;
+ }
+ else
+ nNewDropPos = 0;
+ }
+ else
+ {
+ nDropId = GetPageId( rPos );
+ if ( nDropId )
+ {
+ nNewDropPos = GetPagePos( nDropId );
+ if ( mnFirstPos && (nNewDropPos == mnFirstPos-1) )
+ nScroll = -1;
+ }
+ else
+ nNewDropPos = nItemCount;
+ }
+
+ if ( mbDropPos && (nNewDropPos == mnDropPos) && !nScroll )
+ return mnDropPos;
+
+ if ( mbDropPos )
+ HideDropPos();
+ mbDropPos = TRUE;
+ mnDropPos = nNewDropPos;
+
+ if ( nScroll )
+ {
+ USHORT nOldFirstPos = mnFirstPos;
+ SetFirstPageId( GetPageId( mnFirstPos+nScroll ) );
+
+ // Direkt ausgeben, da kein Paint bei Drag and Drop moeglich
+ if ( nOldFirstPos != mnFirstPos )
+ {
+ Rectangle aRect( mnOffX, 0, mnOutWidth, maWinSize.Height() );
+ SetFillColor();
+ DrawRect( aRect );
+ Paint( aRect );
+ }
+ }
+
+ // Drop-Position-Pfeile ausgeben
+ Color aBlackColor( COL_BLACK );
+ long nX;
+ long nY = (maWinSize.Height()/2)-1;
+ USHORT nCurPos = GetPagePos( mnCurPageId );
+
+ SetLineColor( aBlackColor );
+ if ( mnDropPos < nItemCount )
+ {
+ pItem = mpItemList->GetObject( mnDropPos );
+ nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
+ if ( mnDropPos == nCurPos )
+ nX--;
+ else
+ nX++;
+ DrawLine( Point( nX, nY ), Point( nX, nY ) );
+ DrawLine( Point( nX+1, nY-1 ), Point( nX+1, nY+1 ) );
+ DrawLine( Point( nX+2, nY-2 ), Point( nX+2, nY+2 ) );
+ }
+ if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
+ {
+ pItem = mpItemList->GetObject( mnDropPos-1 );
+ nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
+ if ( mnDropPos == nCurPos )
+ nX++;
+ DrawLine( Point( nX, nY ), Point( nX, nY ) );
+ DrawLine( Point( nX-1, nY-1 ), Point( nX-1, nY+1 ) );
+ DrawLine( Point( nX-2, nY-2 ), Point( nX-2, nY+2 ) );
+ }
+
+ return mnDropPos;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::HideDropPos()
+{
+ if ( mbDropPos )
+ {
+ ImplTabBarItem* pItem;
+ long nX;
+ long nY1 = (maWinSize.Height()/2)-3;
+ long nY2 = nY1 + 5;
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+
+ if ( mnDropPos < nItemCount )
+ {
+ pItem = mpItemList->GetObject( mnDropPos );
+ nX = pItem->maRect.Left()+TABBAR_OFFSET_X;
+ // Paint direkt aufrufen, da bei Drag and Drop kein Paint
+ // moeglich
+ Rectangle aRect( nX-1, nY1, nX+3, nY2 );
+ Region aRegion( aRect );
+ SetClipRegion( aRegion );
+ Paint( aRect );
+ SetClipRegion();
+ }
+ if ( (mnDropPos > 0) && (mnDropPos < nItemCount+1) )
+ {
+ pItem = mpItemList->GetObject( mnDropPos-1 );
+ nX = pItem->maRect.Right()-TABBAR_OFFSET_X;
+ // Paint direkt aufrufen, da bei Drag and Drop kein Paint
+ // moeglich
+ Rectangle aRect( nX-2, nY1, nX+1, nY2 );
+ Region aRegion( aRect );
+ SetClipRegion( aRegion );
+ Paint( aRect );
+ SetClipRegion();
+ }
+
+ mbDropPos = FALSE;
+ mnDropPos = 0;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TabBar::SwitchPage( const Point& rPos )
+{
+ BOOL bSwitch = FALSE;
+ USHORT nSwitchId = GetPageId( rPos );
+ if ( !nSwitchId )
+ EndSwitchPage();
+ else
+ {
+ if ( nSwitchId != mnSwitchId )
+ {
+ mnSwitchId = nSwitchId;
+ mnSwitchTime = Time::GetSystemTicks();
+ }
+ else
+ {
+ // Erst nach 500 ms umschalten
+ if ( mnSwitchId != GetCurPageId() )
+ {
+ if ( Time::GetSystemTicks() > mnSwitchTime+500 )
+ {
+ mbInSwitching = TRUE;
+ if ( DeactivatePage() )
+ {
+ SetCurPageId( mnSwitchId );
+ Update();
+ ActivatePage();
+ Select();
+ bSwitch = TRUE;
+ }
+ mbInSwitching = FALSE;
+ }
+ }
+ }
+ }
+
+ return bSwitch;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::EndSwitchPage()
+{
+ mnSwitchTime = 0;
+ mnSwitchId = 0;
+}
+
+// -----------------------------------------------------------------------
+
+void TabBar::SetStyle( WinBits nStyle )
+{
+ mnWinStyle = nStyle;
+ ImplInitControls();
+ // Evt. Controls neu anordnen
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+Size TabBar::CalcWindowSizePixel() const
+{
+ long nWidth = 0;
+
+ if ( mpItemList->Count() )
+ {
+ ((TabBar*)this)->ImplCalcWidth();
+ ImplTabBarItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ nWidth += pItem->mnWidth;
+ pItem = mpItemList->Next();
+ }
+ nWidth += TABBAR_OFFSET_X+TABBAR_OFFSET_X2;
+ }
+
+ return Size( nWidth, GetTextHeight()+3 );
+}
diff --git a/svtools/source/control/taskbar.cxx b/svtools/source/control/taskbar.cxx
new file mode 100644
index 000000000000..131bede4df03
--- /dev/null
+++ b/svtools/source/control/taskbar.cxx
@@ -0,0 +1,645 @@
+/*************************************************************************
+ *
+ * $RCSfile: taskbar.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _VCL_FLOATWIN_HXX
+#include <vcl/floatwin.hxx>
+#endif
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+class ImplTaskBarFloat : public FloatingWindow
+{
+public:
+ TaskBar* mpTaskBar;
+
+public:
+ ImplTaskBarFloat( TaskBar* pTaskBar );
+
+ void Paint();
+};
+
+// -----------------------------------------------------------------------
+
+ImplTaskBarFloat::ImplTaskBarFloat( TaskBar* pTaskBar ) :
+ FloatingWindow( pTaskBar, 0 )
+{
+ mpTaskBar = pTaskBar;
+}
+
+// -----------------------------------------------------------------------
+
+void ImplTaskBarFloat::Paint()
+{
+}
+
+// =======================================================================
+
+#define TASKBAR_BORDER 2
+#define TASKBAR_OFFSIZE 3
+#define TASKBAR_OFFX 2
+#define TASKBAR_OFFY 1
+#define TASKBAR_BUTTONOFF 5
+#define TASKBAR_AUTOHIDE_HEIGHT 2
+
+// =======================================================================
+
+TaskBar::TaskBar( Window* pParent, WinBits nWinStyle ) :
+ Window( pParent, WB_3DLOOK )
+{
+ mpButtonBar = NULL;
+ mpTaskToolBox = NULL;
+ mpStatusBar = NULL;
+ mnStatusWidth = 0;
+ mnOldStatusWidth = 0;
+ mnLines = 1;
+ mnWinBits = nWinStyle;
+ mbStatusText = FALSE;
+ mbShowItems = FALSE;
+ mbAutoHide = FALSE;
+
+ ImplInitSettings();
+}
+
+// -----------------------------------------------------------------------
+
+TaskBar::~TaskBar()
+{
+ if ( mpButtonBar )
+ delete mpButtonBar;
+ if ( mpTaskToolBox )
+ delete mpTaskToolBox;
+ if ( mpStatusBar )
+ delete mpStatusBar;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::ImplInitSettings()
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ Color aColor;
+ if ( IsControlBackground() )
+ aColor = GetControlBackground();
+ else if ( Window::GetStyle() & WB_3DLOOK )
+ aColor = rStyleSettings.GetFaceColor();
+ else
+ aColor = rStyleSettings.GetWindowColor();
+ SetBackground( aColor );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::ImplNewHeight( long nNewHeight )
+{
+ long nOldHeight = GetSizePixel().Height();
+ if ( nNewHeight != nOldHeight )
+ {
+ long nY = GetPosPixel().Y()-(nNewHeight-nOldHeight);
+ SetPosSizePixel( 0, nY, 0, nNewHeight,
+ WINDOW_POSSIZE_Y | WINDOW_POSSIZE_HEIGHT );
+ TaskResize();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::TaskResize()
+{
+ maTaskResizeHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+TaskButtonBar* TaskBar::CreateButtonBar()
+{
+ return new TaskButtonBar( this );
+}
+
+// -----------------------------------------------------------------------
+
+TaskToolBox* TaskBar::CreateTaskToolBox()
+{
+ return new TaskToolBox( this );
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusBar* TaskBar::CreateTaskStatusBar()
+{
+ return new TaskStatusBar( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::MouseMove( const MouseEvent& rMEvt )
+{
+ if ( mnWinBits & WB_SIZEABLE )
+ {
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+
+ if ( pTempTaskToolBox && pTempStatusBar )
+ {
+ long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ long nMouseX = rMEvt.GetPosPixel().X();
+ PointerStyle ePtrStyle;
+ if ( (nMouseX >= nStatusX-1) && (nMouseX <= nStatusX+3) )
+ ePtrStyle = POINTER_HSIZEBAR;
+ else
+ ePtrStyle = POINTER_ARROW;
+ Pointer aPtr( ePtrStyle );
+ SetPointer( aPtr );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() && (mnWinBits & WB_SIZEABLE) )
+ {
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+
+ if ( pTempTaskToolBox && pTempStatusBar )
+ {
+ long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ long nMouseX = rMEvt.GetPosPixel().X();
+ if ( (nMouseX >= nStatusX-1) && (nMouseX <= nStatusX+3) )
+ {
+ if ( rMEvt.GetClicks() == 2 )
+ {
+ if ( mnStatusWidth )
+ {
+ mnStatusWidth = 0;
+ Resize();
+ }
+ }
+ else
+ {
+ StartTracking();
+ mnOldStatusWidth = mnStatusWidth;
+ mnMouseOff = nMouseX-nStatusX;
+ }
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Tracking( const TrackingEvent& rTEvt )
+{
+ if ( rTEvt.IsTrackingEnded() )
+ {
+ if ( rTEvt.IsTrackingCanceled() )
+ {
+ mnStatusWidth = mnOldStatusWidth;
+ Resize();
+ Update();
+ }
+ }
+ else
+ {
+ Size aSize = GetOutputSizePixel();
+
+#ifdef MAC
+ if ( !Application::IsFullScreenMode() )
+ aSize.Width() -= 17;
+#endif
+
+ long nMouseX = rTEvt.GetMouseEvent().GetPosPixel().X()-mnMouseOff;
+ if ( nMouseX < 0 )
+ nMouseX = 0;
+ long nMaxX = aSize.Width()-TASKBAR_OFFX-TASKBAR_OFFSIZE-1;
+ if ( nMouseX > nMaxX )
+ nMouseX = nMaxX;
+ mnStatusWidth = aSize.Width()-nMouseX-TASKBAR_OFFX-TASKBAR_OFFSIZE;
+ Resize();
+ Update();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Paint( const Rectangle& rRect )
+{
+ if ( mnWinBits & (WB_BORDER | WB_SIZEABLE) )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Size aSize = GetOutputSizePixel();
+ long nY = 0;
+
+ if ( mnWinBits & WB_BORDER )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( 0, 0 ), Point( aSize.Width()-1, 0 ) );
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( 0, 1 ), Point( aSize.Width()-1, 1 ) );
+ nY += 2;
+ }
+
+ if ( (mnWinBits & WB_SIZEABLE) )
+ {
+ TaskButtonBar* pTempButtonBar = GetButtonBar();
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+
+ if ( pTempTaskToolBox && pTempStatusBar )
+ {
+ long nStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ if ( nStatusX > 0 )
+ {
+ SetLineColor( rStyleSettings.GetShadowColor() );
+ DrawLine( Point( nStatusX, nY ), Point( nStatusX, aSize.Height()-1 ) );
+ nStatusX++;
+ SetLineColor( rStyleSettings.GetLightColor() );
+ DrawLine( Point( nStatusX, nY ), Point( nStatusX, aSize.Height()-1 ) );
+ }
+ }
+ }
+ }
+
+ Window::Paint( rRect );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Resize()
+{
+ if ( !IsReallyShown() )
+ return;
+
+ TaskButtonBar* pTempButtonBar = GetButtonBar();
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+ Point aToolPos( TASKBAR_OFFX, 0 );
+ Size aSize = GetOutputSizePixel();
+ Size aStatusSize;
+ Size aToolSize( aSize.Width()-(TASKBAR_OFFX*2), 0 );
+ long nOldStatusX = -1;
+ long nNewStatusX = -1;
+ long nTaskHeight = aSize.Height() - (TASKBAR_OFFY*2);
+
+#ifdef MAC
+ if ( !Application::IsFullScreenMode() )
+ aSize.Width() -= 17;
+#endif
+
+ if ( mnWinBits & WB_BORDER )
+ {
+ nTaskHeight -= TASKBAR_BORDER;
+ aToolPos.Y() += TASKBAR_BORDER;
+ }
+
+ if ( pTempButtonBar )
+ {
+ USHORT i = 0;
+ BOOL bVisibleItems = FALSE;
+ while ( i < pTempButtonBar->GetItemCount() )
+ {
+ if ( pTempButtonBar->IsItemVisible( pTempButtonBar->GetItemId( i ) ) )
+ {
+ bVisibleItems = TRUE;
+ break;
+ }
+ i++;
+ }
+ if ( mbStatusText || !bVisibleItems )
+ pTempButtonBar->Hide();
+ else
+ {
+ Size aButtonBarSize = pTempButtonBar->CalcWindowSizePixel();
+ if ( pTempButtonBar->GetItemCount() )
+ nTaskHeight = aButtonBarSize.Height();
+ else
+ aButtonBarSize.Height() = nTaskHeight;
+ Point aTempPos = aToolPos;
+ aTempPos.Y() += (aSize.Height()-aButtonBarSize.Height()-aTempPos.Y())/2;
+ pTempButtonBar->SetPosSizePixel( aTempPos, aButtonBarSize );
+ pTempButtonBar->Show();
+ aToolPos.X() += aButtonBarSize.Width()+TASKBAR_BUTTONOFF;
+ }
+ }
+
+ if ( pTempStatusBar )
+ {
+ aStatusSize = pTempStatusBar->CalcWindowSizePixel();
+ if ( mnStatusWidth )
+ aStatusSize.Width() = mnStatusWidth;
+ if ( !pTempTaskToolBox || mbStatusText )
+ aStatusSize.Width() = aSize.Width();
+ long nMaxHeight = aSize.Height()-(TASKBAR_OFFY*2);
+ if ( mnWinBits & WB_BORDER )
+ nMaxHeight -= TASKBAR_BORDER;
+ if ( nMaxHeight+2 > aStatusSize.Height() )
+ aStatusSize.Height() = nMaxHeight;
+ Point aPos( aSize.Width()-aStatusSize.Width(), 0 );
+ if ( pTempTaskToolBox && (mnWinBits & WB_SIZEABLE) && !mbStatusText )
+ {
+ long nMinToolWidth = aToolPos.X()+50;
+ if ( aPos.X() < nMinToolWidth )
+ {
+ aStatusSize.Width() -= nMinToolWidth-aPos.X();
+ aPos.X() = nMinToolWidth;
+ }
+ }
+ if ( aPos.X() < 0 )
+ {
+ aStatusSize.Width() = aSize.Width();
+ aPos.X() = 0;
+ }
+ if ( mnWinBits & WB_BORDER )
+ aPos.Y() += TASKBAR_BORDER;
+ aPos.Y() += (aSize.Height()-aStatusSize.Height()-aPos.Y())/2;
+ if ( mnWinBits & WB_SIZEABLE )
+ {
+ if ( pTempTaskToolBox )
+ {
+ nOldStatusX = pTempStatusBar->GetPosPixel().X()-TASKBAR_OFFSIZE-2;
+ nNewStatusX = aPos.X()-TASKBAR_OFFSIZE-2;
+ }
+ }
+ pTempStatusBar->SetPosSizePixel( aPos, aStatusSize );
+ pTempStatusBar->Show();
+ aToolSize.Width() = aPos.X()-aToolPos.X()-TASKBAR_OFFX;
+ if ( mnWinBits & WB_SIZEABLE )
+ aToolSize.Width() -= (TASKBAR_OFFSIZE*2)-2;
+ }
+
+ if ( pTempTaskToolBox )
+ {
+ if ( aToolSize.Width() <= 24 )
+ pTempTaskToolBox->Hide();
+ else
+ {
+ aToolSize.Height() = pTempTaskToolBox->CalcWindowSizePixel().Height();
+ if ( pTempTaskToolBox->GetItemCount() )
+ nTaskHeight = aToolSize.Height();
+ else
+ aToolSize.Height() = nTaskHeight;
+ aToolPos.Y() += (aSize.Height()-aToolSize.Height()-aToolPos.Y())/2;
+ pTempTaskToolBox->SetPosSizePixel( aToolPos, aToolSize );
+ pTempTaskToolBox->Show();
+ }
+ }
+
+ if ( nOldStatusX != nNewStatusX )
+ {
+ if ( nOldStatusX > 0 )
+ {
+ Rectangle aRect( nOldStatusX, 0, nOldStatusX+2, aSize.Height()-1 );
+ Invalidate( aRect );
+ }
+ if ( nNewStatusX > 0 )
+ {
+ Rectangle aRect( nNewStatusX, 0, nNewStatusX+2, aSize.Height()-1 );
+ Invalidate( aRect );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::StateChanged( StateChangedType nType )
+{
+ Window::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ Format();
+ else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
+ {
+ ImplInitSettings();
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_FORMAT )
+ {
+ ImplInitSettings();
+ ImplNewHeight( CalcWindowSizePixel().Height() );
+ Format();
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Window::DataChanged( rDCEvt );
+
+ if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
+ (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
+ ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
+ (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
+ {
+ // Asyncronen StateChanged ausloesen, damit sich die
+ // TaskBar an die neuen Groessen der Child-Fenster
+ // orientieren kann
+ PostStateChanged( STATE_CHANGE_FORMAT );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::Format()
+{
+ ImplNewHeight( CalcWindowSizePixel().Height() );
+ Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::SetLines( USHORT nLines )
+{
+ mnLines = nLines;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::EnableAutoHide( BOOL bAutoHide )
+{
+ mbAutoHide = bAutoHide;
+
+ if ( mbAutoHide )
+ {
+ ImplNewHeight( TASKBAR_AUTOHIDE_HEIGHT );
+ }
+ else
+ {
+ ImplNewHeight( CalcWindowSizePixel().Height() );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::ShowStatusText( const String& rText )
+{
+ if ( mpStatusBar )
+ {
+ if ( !mbStatusText )
+ {
+ mbStatusText = TRUE;
+ if ( mpStatusBar->AreItemsVisible() )
+ {
+ mbShowItems = TRUE;
+ mpStatusBar->HideItems();
+ }
+ else
+ mbShowItems = TRUE;
+ maOldText = mpStatusBar->GetText();
+ Resize();
+ mpStatusBar->SetText( rText );
+ Update();
+ mpStatusBar->Update();
+ }
+ else
+ mpStatusBar->SetText( rText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskBar::HideStatusText()
+{
+ if ( mbStatusText && mpStatusBar )
+ {
+ mbStatusText = FALSE;
+ mpStatusBar->SetText( maOldText );
+ Resize();
+ if ( mbShowItems )
+ mpStatusBar->ShowItems();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+Size TaskBar::CalcWindowSizePixel() const
+{
+ TaskButtonBar* pTempButtonBar = GetButtonBar();
+ TaskToolBox* pTempTaskToolBox = GetTaskToolBox();
+ TaskStatusBar* pTempStatusBar = GetStatusBar();
+ Size aSize;
+ long nTempHeight;
+
+ if ( pTempButtonBar && pTempButtonBar->GetItemCount() )
+ aSize.Height() = pTempButtonBar->CalcWindowSizePixel().Height()+(TASKBAR_OFFY*2);
+ if ( pTempTaskToolBox && pTempTaskToolBox->GetItemCount() )
+ {
+ nTempHeight = pTempTaskToolBox->CalcWindowSizePixel().Height()+(TASKBAR_OFFY*2);
+ if ( nTempHeight > aSize.Height() )
+ aSize.Height() = nTempHeight;
+ }
+ if ( pTempStatusBar )
+ {
+ nTempHeight = pTempStatusBar->GetSizePixel().Height();
+ if ( nTempHeight > aSize.Height() )
+ aSize.Height() = nTempHeight;
+ }
+
+ if ( mnWinBits & WB_BORDER )
+ aSize.Height() += TASKBAR_BORDER;
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+TaskButtonBar* TaskBar::GetButtonBar() const
+{
+ if ( !mpButtonBar )
+ ((TaskBar*)this)->mpButtonBar = ((TaskBar*)this)->CreateButtonBar();
+ return mpButtonBar;
+}
+
+// -----------------------------------------------------------------------
+
+TaskToolBox* TaskBar::GetTaskToolBox() const
+{
+ if ( !mpTaskToolBox )
+ ((TaskBar*)this)->mpTaskToolBox = ((TaskBar*)this)->CreateTaskToolBox();
+ return mpTaskToolBox;
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusBar* TaskBar::GetStatusBar() const
+{
+ if ( !mpStatusBar )
+ {
+ ((TaskBar*)this)->mpStatusBar = ((TaskBar*)this)->CreateTaskStatusBar();
+ if ( mpStatusBar )
+ mpStatusBar->mpNotifyTaskBar = (TaskBar*)this;
+ }
+ return mpStatusBar;
+}
diff --git a/svtools/source/control/taskbox.cxx b/svtools/source/control/taskbox.cxx
new file mode 100644
index 000000000000..73a9798a12ee
--- /dev/null
+++ b/svtools/source/control/taskbox.cxx
@@ -0,0 +1,406 @@
+/*************************************************************************
+ *
+ * $RCSfile: taskbox.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+#ifndef _SV_SYSTEM_HXX
+#include <vcl/system.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <vcl/help.hxx>
+#endif
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+#define TASKBOX_TASKOFF 3
+
+// =======================================================================
+
+struct ImplTaskItem
+{
+ Image maImage;
+ XubString maText;
+};
+
+DECLARE_LIST( ImplTaskItemList, ImplTaskItem* );
+
+// =======================================================================
+
+TaskToolBox::TaskToolBox( Window* pParent, WinBits nWinStyle ) :
+ ToolBox( pParent, nWinStyle | WB_SCROLL | WB_3DLOOK )
+{
+ mpItemList = new ImplTaskItemList;
+ mnMaxTextWidth = 0;
+ mnActiveItemId = 0;
+ mnTaskItem = 0;
+ mnSmallItem = TOOLBOX_ITEM_NOTFOUND;
+ mbMinActivate = FALSE;
+
+ SetAlign( WINDOWALIGN_BOTTOM );
+ SetButtonType( BUTTON_SYMBOLTEXT );
+}
+
+// -----------------------------------------------------------------------
+
+TaskToolBox::~TaskToolBox()
+{
+ ImplTaskItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ActivateTaskItem( USHORT nItemId, BOOL bMinActivate )
+{
+ if ( nItemId )
+ {
+ if ( nItemId != mnActiveItemId )
+ {
+ if ( mnActiveItemId )
+ CheckItem( mnActiveItemId, FALSE );
+ CheckItem( nItemId );
+ mnActiveItemId = nItemId;
+ }
+ else
+ {
+ if ( !bMinActivate )
+ return;
+
+ mbMinActivate = TRUE;
+ }
+
+ mnTaskItem = nItemId-1;
+ ActivateTask();
+ mnTaskItem = 0;
+ mbMinActivate = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ActivateTask()
+{
+ maActivateTaskHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ContextMenu()
+{
+ maContextMenuHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( !rMEvt.IsRight() )
+ ToolBox::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::Resize()
+{
+ mnOldItemCount = mpItemList->Count();
+ mnUpdatePos = (USHORT)mnOldItemCount;
+ mnUpdateNewPos = TOOLBOX_ITEM_NOTFOUND;
+ ImplFormat();
+ ToolBox::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::Command( const CommandEvent& rCEvt )
+{
+ if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
+ {
+ USHORT nItemId = GetItemId( rCEvt.GetMousePosPixel() );
+// Dies machen wir nicht mehr, da es von zu vielen als stoerend empfunden wurde
+// ActivateTaskItem( nItemId );
+ mnTaskItem = nItemId-1;
+
+ maContextMenuPos = OutputToScreenPixel( rCEvt.GetMousePosPixel() );
+ ContextMenu();
+ maContextMenuPos = Point();
+ mnTaskItem = 0;
+ }
+ else
+ ToolBox::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ USHORT nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
+
+ if ( nItemId )
+ {
+ ImplTaskItem* pItem = mpItemList->GetObject( nItemId-1 );
+ if ( pItem )
+ {
+ if ( pItem->maText != GetItemText( nItemId ) )
+ {
+ Rectangle aItemRect = GetItemRect( nItemId );
+ if ( rHEvt.GetMode() & HELPMODE_QUICK )
+ Help::ShowQuickHelp( this, aItemRect, pItem->maText );
+ else
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, pItem->maText );
+ }
+ else
+ Help::ShowQuickHelp( this, Rectangle(), String() );
+ return;
+ }
+ }
+ }
+
+ ToolBox::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskToolBox::QueryDrop( DropEvent& rDEvt )
+{
+ if ( !rDEvt.IsLeaveWindow() )
+ {
+ USHORT nItemId = GetItemId( rDEvt.GetPosPixel() );
+ if ( nItemId )
+ ActivateTaskItem( nItemId );
+ }
+ return ToolBox::QueryDrop( rDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::Select()
+{
+ USHORT nItemId = GetCurItemId();
+ ActivateTaskItem( nItemId, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::ImplFormat()
+{
+ if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
+ {
+ // Eintraege aus der Liste entfernen
+ while ( mpItemList->Count() > mnUpdatePos )
+ delete mpItemList->Remove( (ULONG)mnUpdatePos );
+ mnUpdateNewPos = mnUpdatePos;
+ }
+
+ // Maximale Itemgroesse berechnen
+ long nOldMaxTextWidth = mnMaxTextWidth;
+ mnMaxTextWidth = 70;
+ if ( mpItemList->Count() )
+ {
+ long nWinSize = GetOutputSizePixel().Width()-8;
+ long nItemSize = mpItemList->GetObject(0)->maImage.GetSizePixel().Width()+7+TASKBOX_TASKOFF+2;
+ nWinSize -= mpItemList->Count()*nItemSize;
+ if ( nWinSize > 0 )
+ nWinSize /= mpItemList->Count();
+ else
+ nWinSize = 0;
+ if ( nWinSize < mnMaxTextWidth )
+ mnMaxTextWidth = nWinSize;
+ if ( (mnMaxTextWidth < nOldMaxTextWidth) ||
+ ((mnMaxTextWidth-nOldMaxTextWidth > 3) &&
+ (mnSmallItem != TOOLBOX_ITEM_NOTFOUND)) )
+ {
+ mnSmallItem = TOOLBOX_ITEM_NOTFOUND;
+ mnUpdateNewPos = 0;
+ }
+ }
+
+ // Eintraege aus der ToolBox entfernen, die ersetzt werden
+ USHORT nBtnPos = (mnUpdateNewPos*2);
+ while ( nBtnPos < GetItemCount() )
+ RemoveItem( nBtnPos );
+ if ( mnUpdateNewPos <= (mnActiveItemId-1) )
+ mnActiveItemId = 0;
+
+ // Neue Eintrage einfuegen
+ USHORT i = mnUpdateNewPos;
+ while ( i < mpItemList->Count() )
+ {
+ ImplTaskItem* pItem = mpItemList->GetObject( i );
+
+ // Textlaenge berechnen
+ XubString aText = pItem->maText;
+ if ( !aText.Len() )
+ aText = ' ';
+ long nTxtWidth = GetTextWidth( aText );
+ if ( nTxtWidth > mnMaxTextWidth )
+ {
+ if ( mnSmallItem == TOOLBOX_ITEM_NOTFOUND )
+ mnSmallItem = i;
+ // 3 == Len of "..."
+ aText.AppendAscii( "..." );
+ do
+ {
+ aText.Erase( aText.Len()-3-1, 1 );
+ nTxtWidth = GetTextWidth( aText );
+ }
+ while ( (nTxtWidth > mnMaxTextWidth) && (aText.Len() > 3) );
+ }
+
+ USHORT nItemId = i+1;
+ if ( aText.EqualsAscii( "..." ) )
+ InsertItem( nItemId, pItem->maImage, TIB_LEFT );
+ else
+ InsertItem( nItemId, pItem->maImage, aText, TIB_LEFT );
+ InsertSeparator( TOOLBOX_APPEND, TASKBOX_TASKOFF );
+ i++;
+ }
+
+ if ( mnUpdateNewPos != 0 )
+ mnMaxTextWidth = nOldMaxTextWidth;
+
+ if ( mnNewActivePos+1 != mnActiveItemId )
+ {
+ if ( mnActiveItemId )
+ CheckItem( mnActiveItemId, FALSE );
+ mnActiveItemId = mnNewActivePos+1;
+ CheckItem( mnActiveItemId );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::StartUpdateTask()
+{
+ mnOldItemCount = mpItemList->Count();
+ mnUpdatePos = 0;
+ mnUpdateNewPos = TOOLBOX_ITEM_NOTFOUND;
+ mnNewActivePos = 0xFFFE;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::UpdateTask( const Image& rImage, const String& rText,
+ BOOL bActive )
+{
+ ImplTaskItem* pItem = mpItemList->GetObject( mnUpdatePos );
+ if ( pItem )
+ {
+ if ( (pItem->maText != rText) || (pItem->maImage != rImage) )
+ {
+ // Eintraege aus der Liste entfernen
+ while ( mpItemList->Count() > mnUpdatePos )
+ delete mpItemList->Remove( (ULONG)mnUpdatePos );
+ pItem = NULL;
+ }
+ }
+
+ if ( !pItem )
+ {
+ if ( mnUpdatePos < mnUpdateNewPos )
+ mnUpdateNewPos = mnUpdatePos;
+
+ pItem = new ImplTaskItem;
+ pItem->maImage = rImage;
+ pItem->maText = rText;
+ mpItemList->Insert( pItem, LIST_APPEND );
+ }
+
+ if ( bActive )
+ mnNewActivePos = mnUpdatePos;
+
+ mnUpdatePos++;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskToolBox::EndUpdateTask()
+{
+ if ( mnUpdateNewPos == TOOLBOX_ITEM_NOTFOUND )
+ {
+ // Eintraege aus der Liste entfernen
+ while ( mpItemList->Count() > mnUpdatePos )
+ delete mpItemList->Remove( (ULONG)mnUpdatePos );
+ mnUpdateNewPos = mnUpdatePos;
+ }
+
+ ImplFormat();
+}
+
diff --git a/svtools/source/control/taskmisc.cxx b/svtools/source/control/taskmisc.cxx
new file mode 100644
index 000000000000..1438417d2a88
--- /dev/null
+++ b/svtools/source/control/taskmisc.cxx
@@ -0,0 +1,416 @@
+/*************************************************************************
+ *
+ * $RCSfile: taskmisc.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_HELP_HXX
+#include <vcl/help.hxx>
+#endif
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+TaskButtonBar::TaskButtonBar( Window* pParent, WinBits nWinStyle ) :
+ ToolBox( pParent, nWinStyle | WB_3DLOOK )
+{
+ SetAlign( WINDOWALIGN_BOTTOM );
+ SetButtonType( BUTTON_SYMBOLTEXT );
+}
+
+// -----------------------------------------------------------------------
+
+TaskButtonBar::~TaskButtonBar()
+{
+}
+
+// -----------------------------------------------------------------------
+
+void TaskButtonBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ ToolBox::RequestHelp( rHEvt );
+}
+
+// =======================================================================
+
+WindowArrange::WindowArrange()
+{
+ mpWinList = new List;
+}
+
+// -----------------------------------------------------------------------
+
+WindowArrange::~WindowArrange()
+{
+ delete mpWinList;
+}
+
+// -----------------------------------------------------------------------
+
+static USHORT ImplCeilSqareRoot( USHORT nVal )
+{
+ USHORT i;
+
+ // Ueberlauf verhindern
+ if ( nVal > 0xFE * 0xFE )
+ return 0xFE;
+
+ for ( i=0; i*i < nVal; i++ )
+ {}
+
+ return i;
+}
+
+// -----------------------------------------------------------------------
+
+static void ImplPosSizeWindow( Window* pWindow,
+ long nX, long nY, long nWidth, long nHeight )
+{
+ if ( nWidth < 32 )
+ nWidth = 32;
+ if ( nHeight < 24 )
+ nHeight = 24;
+ pWindow->SetPosSizePixel( nX, nY, nWidth, nHeight );
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplTile( const Rectangle& rRect )
+{
+ USHORT nCount = (USHORT)mpWinList->Count();
+ if ( nCount < 3 )
+ {
+ ImplVert( rRect );
+ return;
+ }
+
+ USHORT i;
+ USHORT j;
+ USHORT nCols;
+ USHORT nRows;
+ USHORT nActRows;
+ USHORT nOffset;
+ long nOverWidth;
+ long nOverHeight;
+ Window* pWindow;
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectY = nY;
+ long nRectWidth = nWidth;
+ long nRectHeight = nHeight;
+ long nTempWidth;
+ long nTempHeight;
+
+ nCols = ImplCeilSqareRoot( nCount );
+ nOffset = (nCols*nCols) - nCount;
+ if ( nOffset >= nCols )
+ {
+ nRows = nCols -1;
+ nOffset -= nCols;
+ }
+ else
+ nRows = nCols;
+
+ nWidth /= nCols;
+ if ( nWidth < 1 )
+ nWidth = 1;
+ nOverWidth = nRectWidth-(nWidth*nCols);
+
+ pWindow = (Window*)mpWinList->First();
+ for ( i = 0; i < nCols; i++ )
+ {
+ if ( i < nOffset )
+ nActRows = nRows - 1;
+ else
+ nActRows = nRows;
+
+ nTempWidth = nWidth;
+ if ( nOverWidth > 0 )
+ {
+ nTempWidth++;
+ nOverWidth--;
+ }
+
+ nHeight = nRectHeight / nActRows;
+ if ( nHeight < 1 )
+ nHeight = 1;
+ nOverHeight = nRectHeight-(nHeight*nActRows);
+ for ( j = 0; j < nActRows; j++ )
+ {
+ // Ueberhang verteilen
+ nTempHeight = nHeight;
+ if ( nOverHeight > 0 )
+ {
+ nTempHeight++;
+ nOverHeight--;
+ }
+ ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nTempHeight );
+ nY += nTempHeight;
+
+ pWindow = (Window*)mpWinList->Next();
+ if ( !pWindow )
+ break;
+ }
+
+ nX += nWidth;
+ nY = nRectY;
+
+ if ( !pWindow )
+ break;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplHorz( const Rectangle& rRect )
+{
+ long nCount = (long)mpWinList->Count();
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectHeight = nHeight;
+ long nOver;
+ long nTempHeight;
+ Window* pWindow;
+
+ nHeight /= nCount;
+ if ( nHeight < 1 )
+ nHeight = 1;
+ nOver = nRectHeight - (nCount*nHeight);
+ pWindow = (Window*)mpWinList->First();
+ while ( pWindow )
+ {
+ nTempHeight = nHeight;
+ if ( nOver > 0 )
+ {
+ nTempHeight++;
+ nOver--;
+ }
+ ImplPosSizeWindow( pWindow, nX, nY, nWidth, nTempHeight );
+ nY += nTempHeight;
+
+ pWindow = (Window*)mpWinList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplVert( const Rectangle& rRect )
+{
+ long nCount = (long)mpWinList->Count();
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectWidth = nWidth;
+ long nOver;
+ long nTempWidth;
+ Window* pWindow;
+
+ nWidth /= nCount;
+ if ( nWidth < 1 )
+ nWidth = 1;
+ nOver = nRectWidth - (nCount*nWidth);
+ pWindow = (Window*)mpWinList->First();
+ while ( pWindow )
+ {
+ nTempWidth = nWidth;
+ if ( nOver > 0 )
+ {
+ nTempWidth++;
+ nOver--;
+ }
+ ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nHeight );
+ nX += nTempWidth;
+
+ pWindow = (Window*)mpWinList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::ImplCascade( const Rectangle& rRect )
+{
+ long nX = rRect.Left();
+ long nY = rRect.Top();
+ long nWidth = rRect.GetWidth();
+ long nHeight = rRect.GetHeight();
+ long nRectWidth = nWidth;
+ long nRectHeight = nHeight;
+ long nOff;
+ long nCascadeWins;
+ long nLeftBorder;
+ long nTopBorder;
+ long nRightBorder;
+ long nBottomBorder;
+ long nStartOverWidth;
+ long nStartOverHeight;
+ long nOverWidth;
+ long nOverHeight;
+ long nTempX;
+ long nTempY;
+ long nTempWidth;
+ long nTempHeight;
+ long i;
+ Window* pWindow;
+ Window* pTempWindow;
+
+ // Border-Fenster suchen um den Versatz zu ermitteln
+ pTempWindow = (Window*)mpWinList->First();
+ pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ while ( !nTopBorder )
+ {
+ Window* pBrdWin = pTempWindow->GetWindow( WINDOW_REALPARENT );
+ if ( !pBrdWin || (pBrdWin->GetWindow( WINDOW_CLIENT ) != pTempWindow) )
+ break;
+ pTempWindow = pBrdWin;
+ pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
+ }
+ if ( !nTopBorder )
+ nTopBorder = 22;
+ nOff = nTopBorder;
+
+ nCascadeWins = nRectHeight / 3 / nOff;
+ if ( !nCascadeWins )
+ nCascadeWins = 1;
+ nWidth -= nCascadeWins*nOff;
+ nHeight -= nCascadeWins*nOff;
+ if ( nWidth < 1 )
+ nWidth = 1;
+ if ( nHeight < 1 )
+ nHeight = 1;
+
+ nStartOverWidth = nRectWidth-(nWidth+(nCascadeWins*nOff));
+ nStartOverHeight = nRectHeight-(nHeight+(nCascadeWins*nOff));
+
+ i = 0;
+ pWindow = (Window*)mpWinList->First();
+ while ( pWindow )
+ {
+ if ( !i )
+ {
+ nOverWidth = nStartOverWidth;
+ nOverHeight = nStartOverHeight;
+ }
+
+ // Position
+ nTempX = nX + (i*nOff);
+ nTempY = nY + (i*nOff);
+
+ // Ueberhang verteilen
+ nTempWidth = nWidth;
+ if ( nOverWidth > 0 )
+ {
+ nTempWidth++;
+ nOverWidth--;
+ }
+ nTempHeight = nHeight;
+ if ( nOverHeight > 0 )
+ {
+ nTempHeight++;
+ nOverHeight--;
+ }
+
+ ImplPosSizeWindow( pWindow, nTempX, nTempY, nTempWidth, nTempHeight );
+
+ if ( i < nCascadeWins )
+ i++;
+ else
+ i = 0;
+
+ pWindow = (Window*)mpWinList->Next();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void WindowArrange::Arrange( USHORT nType, const Rectangle& rRect )
+{
+ if ( !mpWinList->Count() )
+ return;
+
+ switch ( nType )
+ {
+ case WINDOWARRANGE_TILE:
+ ImplTile( rRect );
+ break;
+ case WINDOWARRANGE_HORZ:
+ ImplHorz( rRect );
+ break;
+ case WINDOWARRANGE_VERT:
+ ImplVert( rRect );
+ break;
+ case WINDOWARRANGE_CASCADE:
+ ImplCascade( rRect );
+ break;
+ }
+}
+
diff --git a/svtools/source/control/taskstat.cxx b/svtools/source/control/taskstat.cxx
new file mode 100644
index 000000000000..4c83b4bd09e9
--- /dev/null
+++ b/svtools/source/control/taskstat.cxx
@@ -0,0 +1,769 @@
+/*************************************************************************
+ *
+ * $RCSfile: taskstat.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define _TASKBAR_CXX
+
+#ifndef _TOOLS_LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifndef _SV_IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+#ifndef _SV_SYSTEM_HXX
+#include <vcl/system.hxx>
+#endif
+#ifndef _SV_HELP_HXX
+#include <vcl/help.hxx>
+#endif
+#ifndef _SV_SVAPP_HXX
+#include <vcl/svapp.hxx>
+#endif
+
+#include <taskbar.hxx>
+
+// =======================================================================
+
+#define TASKSTATUSBAR_CLOCXOFFX 3
+#define TASKSTATUSBAR_IMAGEOFFX 1
+
+// =======================================================================
+
+struct ImplTaskSBFldItem
+{
+ TaskStatusFieldItem maItem;
+ USHORT mnId;
+ long mnOffX;
+};
+
+DECLARE_LIST( ImplTaskSBItemList, ImplTaskSBFldItem* );
+
+// =======================================================================
+
+BOOL ITaskStatusNotify::MouseButtonDown( USHORT nItemd, const MouseEvent& rMEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::MouseButtonUp( USHORT nItemd, const MouseEvent& rMEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::MouseMove( USHORT nItemd, const MouseEvent& rMEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::Command( USHORT nItemd, const CommandEvent& rCEvt )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::QueryDrop( USHORT nItemd, DropEvent& rDEvt, BOOL& bRet )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::Drop( USHORT nItemd, const DropEvent& rDEvt, BOOL& bRet )
+{
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ITaskStatusNotify::UpdateHelp( USHORT nItemd )
+{
+ return FALSE;
+}
+
+// =======================================================================
+
+TaskStatusFieldItem::TaskStatusFieldItem()
+{
+ mpNotify = NULL;
+ mnFlags = 0;
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusFieldItem::TaskStatusFieldItem( const TaskStatusFieldItem& rItem ) :
+ mpNotify( rItem.mpNotify ),
+ maImage( rItem.maImage ),
+ maQuickHelpText( rItem.maQuickHelpText ),
+ maHelpText( rItem.maHelpText ),
+ mnFlags( rItem.mnFlags )
+{
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusFieldItem::TaskStatusFieldItem( ITaskStatusNotify* pNotify,
+ const Image& rImage,
+ const XubString& rQuickHelpText,
+ const XubString& rHelpText,
+ USHORT nFlags ) :
+ mpNotify( pNotify ),
+ maImage( rImage ),
+ maQuickHelpText( rQuickHelpText ),
+ maHelpText( rHelpText ),
+ mnFlags( nFlags )
+{
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusFieldItem::~TaskStatusFieldItem()
+{
+}
+
+// -----------------------------------------------------------------------
+
+const TaskStatusFieldItem& TaskStatusFieldItem::operator=( const TaskStatusFieldItem& rItem )
+{
+ mpNotify = rItem.mpNotify;
+ maImage = rItem.maImage;
+ maQuickHelpText = rItem.maQuickHelpText;
+ maHelpText = rItem.maHelpText;
+ mnFlags = rItem.mnFlags;
+ return *this;
+}
+
+// =======================================================================
+
+TaskStatusBar::TaskStatusBar( Window* pParent, WinBits nWinStyle ) :
+ StatusBar( pParent, nWinStyle | WB_3DLOOK ),
+ maTime( 0, 0, 0 )
+{
+ mpFieldItemList = NULL;
+ mpNotifyTaskBar = NULL;
+ mpNotify = NULL;
+ mnClockWidth = 0;
+ mnItemWidth = 0;
+ mnFieldWidth = 0;
+ mnFieldFlags = 0;
+ mbFlashItems = FALSE;
+ mbOutInterval = FALSE;
+
+ maTimer.SetTimeoutHdl( LINK( this, TaskStatusBar, ImplTimerHdl ) );
+}
+
+// -----------------------------------------------------------------------
+
+TaskStatusBar::~TaskStatusBar()
+{
+ if ( mpFieldItemList )
+ {
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpFieldItemList->Next();
+ }
+
+ delete mpFieldItemList;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( TaskStatusBar, ImplTimerHdl, Timer*, EMPTYARG )
+{
+ BOOL bUpdate = ImplUpdateClock();
+ if ( ImplUpdateFlashItems() )
+ bUpdate = TRUE;
+ if ( bUpdate )
+ SetItemData( TASKSTATUSBAR_STATUSFIELDID, NULL );
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+ImplTaskSBFldItem* TaskStatusBar::ImplGetFieldItem( USHORT nItemId ) const
+{
+ if ( !mpFieldItemList )
+ return NULL;
+
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return pItem;
+
+ pItem = mpFieldItemList->Next();
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ImplTaskSBFldItem* TaskStatusBar::ImplGetFieldItem( const Point& rPos, BOOL& rFieldRect ) const
+{
+ if ( GetItemId( rPos ) == TASKSTATUSBAR_STATUSFIELDID )
+ {
+ rFieldRect = TRUE;
+
+ if ( mpFieldItemList )
+ {
+ long nX = rPos.X()-GetItemRect( TASKSTATUSBAR_STATUSFIELDID ).Left();
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ if ( nX < pItem->mnOffX+pItem->maItem.GetImage().GetSizePixel().Width() )
+ return pItem;
+
+ pItem = mpFieldItemList->Next();
+ }
+ }
+ }
+ else
+ rFieldRect = FALSE;
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::ImplUpdateClock()
+{
+ if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
+ {
+ Time aTime;
+ maTimer.SetTimeout( ((long)60000)-((aTime.GetSec()*1000)+(aTime.Get100Sec()*10)) );
+ if ( (aTime.GetMin() != maTime.GetMin()) ||
+ (aTime.GetHour() != maTime.GetHour()) )
+ {
+ maTime = aTime;
+ maTimeText = maIntn.GetTime( aTime, FALSE, FALSE );
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::ImplUpdateFlashItems()
+{
+ if ( mbFlashItems )
+ {
+ if ( mbOutInterval )
+ {
+ maTimer.SetTimeout( 900 );
+ mbOutInterval = FALSE;
+ }
+ else
+ {
+ maTimer.SetTimeout( 700 );
+ mbOutInterval = TRUE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::ImplUpdateField( BOOL bItems )
+{
+ maTimer.Stop();
+
+ if ( bItems )
+ {
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ mnItemWidth = 0;
+ mbFlashItems = FALSE;
+ mbOutInterval = FALSE;
+ while ( pItem )
+ {
+ mnItemWidth += TASKSTATUSBAR_IMAGEOFFX;
+ pItem->mnOffX = mnItemWidth;
+ mnItemWidth += pItem->maItem.GetImage().GetSizePixel().Width();
+ if ( pItem->maItem.GetFlags() & TASKSTATUSFIELDITEM_FLASH )
+ mbFlashItems = TRUE;
+
+ pItem = mpFieldItemList->Next();
+ }
+ }
+ else
+ {
+ if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
+ {
+ XubString aStr = maIntn.GetTime( Time( 23, 59, 59 ), FALSE, FALSE );
+ mnClockWidth = GetTextWidth( aStr )+(TASKSTATUSBAR_CLOCXOFFX*2);
+ }
+ else
+ mnClockWidth = 0;
+ }
+
+ long nNewWidth = mnItemWidth+mnClockWidth;
+ if ( mnItemWidth && !mnClockWidth )
+ nNewWidth += TASKSTATUSBAR_IMAGEOFFX;
+ if ( nNewWidth != mnFieldWidth )
+ {
+ RemoveItem( TASKSTATUSBAR_STATUSFIELDID );
+
+ if ( mnItemWidth || mnClockWidth )
+ {
+ mnFieldWidth = nNewWidth;
+ long nOffset = GetItemOffset( TASKSTATUSBAR_STATUSFIELDID );
+ USHORT nItemPos = GetItemPos( TASKSTATUSBAR_STATUSFIELDID );
+ InsertItem( TASKSTATUSBAR_STATUSFIELDID, nNewWidth, SIB_RIGHT | SIB_IN | SIB_USERDRAW, nOffset, nItemPos );
+ }
+ else
+ mnFieldWidth = 0;
+
+ if ( mpNotifyTaskBar )
+ mpNotifyTaskBar->Resize();
+ }
+ else
+ SetItemData( TASKSTATUSBAR_STATUSFIELDID, NULL );
+
+ if ( mbFlashItems || (mnFieldFlags & TASKSTATUSFIELD_CLOCK) )
+ {
+ ImplUpdateClock();
+ mbOutInterval = TRUE;
+ ImplUpdateFlashItems();
+ maTimer.Start();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->MouseButtonDown( nItemId, rMEvt );
+
+ if ( bBaseClass )
+ StatusBar::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->MouseButtonUp( nItemId, rMEvt );
+
+ if ( bBaseClass )
+ StatusBar::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::MouseMove( const MouseEvent& rMEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rMEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->MouseMove( nItemId, rMEvt );
+
+ if ( bBaseClass )
+ StatusBar::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::Command( const CommandEvent& rCEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rCEvt.GetMousePosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->Command( nItemId, rCEvt );
+
+ if ( bBaseClass )
+ StatusBar::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::QueryDrop( DropEvent& rDEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ BOOL bRet = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rDEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->QueryDrop( nItemId, rDEvt, bRet );
+
+ if ( bBaseClass )
+ {
+ StatusBar::QueryDrop( rDEvt );
+ return TRUE;
+ }
+ else
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::Drop( const DropEvent& rDEvt )
+{
+ BOOL bFieldRect;
+ BOOL bBaseClass = FALSE;
+ BOOL bRet = FALSE;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( rDEvt.GetPosPixel(), bFieldRect );
+
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( bFieldRect )
+ nItemId = TASKSTATUSBAR_CLOCKID;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ bBaseClass = pNotify->Drop( nItemId, rDEvt, bRet );
+
+ if ( bBaseClass )
+ return StatusBar::Drop( rDEvt );
+ else
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::RequestHelp( const HelpEvent& rHEvt )
+{
+ BOOL bFieldRect;
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), bFieldRect );
+ if ( bFieldRect )
+ {
+ ITaskStatusNotify* pNotify = mpNotify;
+ USHORT nItemId = 0;
+
+ if ( pItem )
+ {
+ pNotify = pItem->maItem.GetNotifyObject();
+ nItemId = pItem->mnId;
+ }
+
+ if ( pNotify )
+ pNotify->UpdateHelp( nItemId );
+
+ if ( rHEvt.GetMode() & (HELPMODE_BALLOON | HELPMODE_QUICK) )
+ {
+ Rectangle aItemRect = GetItemRect( TASKSTATUSBAR_STATUSFIELDID );
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ if ( pItem )
+ {
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ {
+ XubString aStr = pItem->maItem.GetHelpText();
+ if ( !aStr.Len() )
+ aStr = pItem->maItem.GetQuickHelpText();
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ }
+ else
+ Help::ShowQuickHelp( this, aItemRect, pItem->maItem.GetQuickHelpText() );
+ }
+ else
+ {
+ XubString aStr = maIntn.GetLongDate( Date() );
+ if ( rHEvt.GetMode() & HELPMODE_BALLOON )
+ Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
+ else
+ Help::ShowQuickHelp( this, aItemRect, aStr );
+ }
+ return;
+ }
+ else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
+ {
+ if ( pItem )
+ {
+ ULONG nHelpId = pItem->maItem.GetHelpId();
+ if ( nHelpId )
+ {
+ // Wenn eine Hilfe existiert, dann ausloesen
+ Help* pHelp = Application::GetHelp();
+ if ( pHelp )
+ pHelp->Start( nHelpId );
+ return;
+ }
+ }
+ }
+ }
+
+ StatusBar::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::UserDraw( const UserDrawEvent& rUDEvt )
+{
+ if ( rUDEvt.GetItemId() == TASKSTATUSBAR_STATUSFIELDID )
+ {
+ OutputDevice* pDev = rUDEvt.GetDevice();
+ Rectangle aRect = rUDEvt.GetRect();
+
+ if ( mpFieldItemList )
+ {
+ ImplTaskSBFldItem* pItem = mpFieldItemList->First();
+ while ( pItem )
+ {
+ if ( !mbOutInterval || !(pItem->maItem.GetFlags() & TASKSTATUSFIELDITEM_FLASH) )
+ {
+ const Image& rImage = pItem->maItem.GetImage();
+ Size aImgSize = rImage.GetSizePixel();
+ pDev->DrawImage( Point( aRect.Left()+pItem->mnOffX,
+ aRect.Top()+((aRect.GetHeight()-aImgSize.Width())/2) ),
+ rImage );
+ }
+
+ pItem = mpFieldItemList->Next();
+ }
+ }
+
+ if ( mnFieldFlags & TASKSTATUSFIELD_CLOCK )
+ {
+ long nX = mnItemWidth+TASKSTATUSBAR_CLOCXOFFX;
+ Point aPos = GetItemTextPos( TASKSTATUSBAR_STATUSFIELDID );
+ aPos.X() = aRect.Left()+nX;
+ pDev->DrawText( aPos, maTimeText );
+ }
+ }
+ else
+ StatusBar::UserDraw( rUDEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::InsertStatusField( long nOffset, USHORT nPos,
+ USHORT nFlags )
+{
+ mnFieldFlags = nFlags;
+ ImplUpdateField( FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::SetFieldFlags( USHORT nFlags )
+{
+ if ( mnFieldFlags != nFlags )
+ {
+ mnFieldFlags = nFlags;
+ ImplUpdateField( FALSE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::AddStatusFieldItem( USHORT nItemId, const TaskStatusFieldItem& rItem,
+ USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "TaskStatusBar::AddStatusFieldItem() - Item is 0" );
+ DBG_ASSERT( !ImplGetFieldItem( nItemId ), "TaskStatusBar::AddStatusFieldItem() - Item-Id already exist" );
+
+ if ( !mpFieldItemList )
+ mpFieldItemList = new ImplTaskSBItemList;
+
+ ImplTaskSBFldItem* pItem = new ImplTaskSBFldItem;
+ pItem->maItem = rItem;
+ pItem->mnId = nItemId;
+ pItem->mnOffX = 0;
+ mpFieldItemList->Insert( pItem, (ULONG)nPos );
+
+ ImplUpdateField( TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::ModifyStatusFieldItem( USHORT nItemId, const TaskStatusFieldItem& rItem )
+{
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
+ if ( pItem )
+ {
+ BOOL bUpdate = (pItem->maItem.GetImage() != rItem.GetImage()) ||
+ (pItem->maItem.GetFlags() != rItem.GetFlags());
+ pItem->maItem = rItem;
+ if ( bUpdate )
+ ImplUpdateField( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void TaskStatusBar::RemoveStatusFieldItem( USHORT nItemId )
+{
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
+ if ( pItem )
+ {
+ mpFieldItemList->Remove( pItem );
+ delete pItem;
+ ImplUpdateField( TRUE );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+BOOL TaskStatusBar::GetStatusFieldItem( USHORT nItemId, TaskStatusFieldItem& rItem ) const
+{
+ ImplTaskSBFldItem* pItem = ImplGetFieldItem( nItemId );
+ if ( pItem )
+ {
+ rItem = pItem->maItem;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx
new file mode 100644
index 000000000000..79f0acb6a098
--- /dev/null
+++ b/svtools/source/control/valueset.cxx
@@ -0,0 +1,2461 @@
+/*************************************************************************
+ *
+ * $RCSfile: valueset.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): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _LIST_HXX
+#include <tools/list.hxx>
+#endif
+#ifndef _DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+#ifdef VCL
+#ifndef _SV_DECOVIEW_HXX
+#include <vcl/decoview.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _IMAGE_HXX
+#include <vcl/image.hxx>
+#endif
+#ifndef _SCRBAR_HXX
+#include <vcl/scrbar.hxx>
+#endif
+#ifndef _HELP_HXX
+#include <vcl/help.hxx>
+#endif
+
+#define _SV_VALUESET_CXX
+#define private public
+#include <valueset.hxx>
+
+// =======================================================================
+
+#define ITEM_OFFSET 4
+#define ITEM_OFFSET_DOUBLE 6
+#define NAME_OFFSET 2
+#define NAME_OFFSET_FLAT 1
+#define SCRBAR_OFFSET 2
+#define VALUESET_ITEM_NONEITEM 0xFFFE
+
+#define VALUESET_SCROLL_OFFSET 4
+
+enum ValueSetItemType { VALUESETITEM_NONE, VALUESETITEM_IMAGE,
+ VALUESETITEM_COLOR, VALUESETITEM_USERDRAW,
+ VALUESETITEM_SPACE };
+
+struct ValueSetItem
+{
+ USHORT mnId;
+ USHORT mnBits;
+ ValueSetItemType meType;
+ Image maImage;
+ Color maColor;
+ XubString maText;
+ void* mpData;
+ Rectangle maRect;
+
+ ValueSetItem();
+ ~ValueSetItem();
+};
+
+DECLARE_LIST( ValueItemList, ValueSetItem* );
+
+// =======================================================================
+
+ValueSetItem::ValueSetItem()
+{
+ mnBits = 0;
+ mpData = NULL;
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem::~ValueSetItem()
+{
+}
+
+// =======================================================================
+
+void ValueSet::ImplInit( WinBits nWinStyle )
+{
+ Size aWinSize = GetSizePixel();
+ mpItemList = new ValueItemList;
+ mpNoneItem = NULL;
+ mpScrBar = NULL;
+ mnTextOffset = 0;
+ mnVisLines = 0;
+ mnLines = 0;
+ mnUserItemWidth = 0;
+ mnUserItemHeight = 0;
+ mnFirstLine = 0;
+ mnOldItemId = 0;
+ mnSelItemId = 0;
+ mnHighItemId = 0;
+ mnDropPos = VALUESET_ITEM_NOTFOUND;
+ mnCols = 0;
+ mnCurCol = 0;
+ mnUserCols = 0;
+ mnUserVisLines = 0;
+ mnSpacing = 0;
+ mnFrameStyle = 0;
+ mbFormat = TRUE;
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+ mbNoSelection = TRUE;
+ mbDrawSelection = TRUE;
+ mbBlackSel = FALSE;
+ mbDoubleSel = FALSE;
+ mbScroll = FALSE;
+ mbDropPos = FALSE;
+
+ ImplInitSettings( TRUE, TRUE, TRUE );
+}
+
+// -----------------------------------------------------------------------
+
+ValueSet::ValueSet( Window* pParent, WinBits nWinStyle ) :
+ Control( pParent, nWinStyle ),
+ maVirDev( *this ),
+ maColor( COL_TRANSPARENT )
+{
+ ImplInit( nWinStyle );
+}
+
+// -----------------------------------------------------------------------
+
+ValueSet::ValueSet( Window* pParent, const ResId& rResId ) :
+ Control( pParent, rResId ),
+ maVirDev( *this ),
+ maColor( COL_TRANSPARENT )
+{
+ ImplInit( rResId.aWinBits );
+}
+
+// -----------------------------------------------------------------------
+
+ValueSet::~ValueSet()
+{
+ if ( mpScrBar )
+ delete mpScrBar;
+
+ if ( mpNoneItem )
+ delete mpNoneItem;
+
+ ValueSetItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+ delete mpItemList;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplInitSettings( BOOL bFont,
+ BOOL bForeground, BOOL bBackground )
+{
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+
+ if ( bFont )
+ {
+ Font aFont;
+ aFont = rStyleSettings.GetAppFont();
+ 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 if ( GetStyle() & WB_FLATVALUESET )
+ aColor = rStyleSettings.GetWindowColor();
+ else
+ aColor = rStyleSettings.GetFaceColor();
+ SetBackground( aColor );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplInitScrollBar()
+{
+ if ( GetStyle() & WB_VSCROLL )
+ {
+ if ( !mpScrBar )
+ {
+ mpScrBar = new ScrollBar( this, WB_VSCROLL | WB_DRAG );
+ mpScrBar->SetScrollHdl( LINK( this, ValueSet, ImplScrollHdl ) );
+ }
+ else
+ {
+ // Wegen Einstellungsaenderungen passen wir hier die Breite an
+ long nScrBarWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
+ mpScrBar->SetPosSizePixel( 0, 0, nScrBarWidth, 0, WINDOW_POSSIZE_WIDTH );
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplFormatItem( ValueSetItem* pItem )
+{
+ if ( pItem->meType == VALUESETITEM_SPACE )
+ return;
+
+ Rectangle aRect = pItem->maRect;
+ WinBits nStyle = GetStyle();
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( nStyle & WB_FLATVALUESET )
+ {
+ if ( nStyle & WB_DOUBLEBORDER )
+ {
+ aRect.Left() += 2;
+ aRect.Top() += 2;
+ aRect.Right() -= 2;
+ aRect.Bottom() -= 2;
+ }
+ else
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ }
+ }
+ else
+ {
+ DecorationView aView( &maVirDev );
+ aRect = aView.DrawFrame( aRect, mnFrameStyle );
+ }
+ }
+
+ if ( pItem == mpNoneItem )
+ pItem->maText = GetText();
+
+ if ( (aRect.GetHeight() > 0) && (aRect.GetWidth() > 0) )
+ {
+ if ( pItem == mpNoneItem )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ maVirDev.SetFont( GetFont() );
+ maVirDev.SetTextColor( rStyleSettings.GetWindowTextColor() );
+ maVirDev.SetTextFillColor();
+ maVirDev.SetFillColor( rStyleSettings.GetWindowColor() );
+ maVirDev.DrawRect( aRect );
+ Point aTxtPos( aRect.Left()+2, aRect.Top() );
+ long nTxtWidth = GetTextWidth( pItem->maText );
+ if ( nStyle & WB_RADIOSEL )
+ {
+ aTxtPos.X() += 4;
+ aTxtPos.Y() += 4;
+ }
+ if ( (aTxtPos.X()+nTxtWidth) > aRect.Right() )
+ {
+ maVirDev.SetClipRegion( Region( aRect ) );
+ maVirDev.DrawText( aTxtPos, pItem->maText );
+ maVirDev.SetClipRegion();
+ }
+ else
+ maVirDev.DrawText( aTxtPos, pItem->maText );
+ }
+ else if ( pItem->meType == VALUESETITEM_COLOR )
+ {
+ maVirDev.SetFillColor( pItem->maColor );
+ maVirDev.DrawRect( aRect );
+ }
+ else
+ {
+ if ( IsColor() )
+ maVirDev.SetFillColor( maColor );
+ else
+ maVirDev.SetFillColor( GetSettings().GetStyleSettings().GetWindowColor() );
+ maVirDev.DrawRect( aRect );
+
+ if ( pItem->meType == VALUESETITEM_USERDRAW )
+ {
+ UserDrawEvent aUDEvt( &maVirDev, aRect, pItem->mnId );
+ UserDraw( aUDEvt );
+ }
+ else
+ {
+ Size aImageSize = pItem->maImage.GetSizePixel();
+ Size aRectSize = aRect.GetSize();
+ Point aPos( aRect.Left(), aRect.Top() );
+ aPos.X() += (aRectSize.Width()-aImageSize.Width())/2;
+ aPos.Y() += (aRectSize.Height()-aImageSize.Height())/2;
+ if ( (aImageSize.Width() > aRectSize.Width()) ||
+ (aImageSize.Height() > aRectSize.Height()) )
+ {
+ maVirDev.SetClipRegion( Region( aRect ) );
+ maVirDev.DrawImage( aPos, pItem->maImage );
+ maVirDev.SetClipRegion();
+ }
+ else
+ maVirDev.DrawImage( aPos, pItem->maImage );
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Format()
+{
+ Size aWinSize = GetOutputSizePixel();
+ Size aOrgWinSize = aWinSize;
+ ULONG nItemCount = mpItemList->Count();
+ WinBits nStyle = GetStyle();
+ long nTxtHeight = GetTextHeight();
+ long nStartX;
+ long nY;
+ long nNameOff;
+ long nOff;
+ long nSpace;
+ long nNoneSpace;
+ ScrollBar* pDelScrBar = NULL;
+
+ // Scrolling beruecksichtigen
+ if ( nStyle & WB_VSCROLL )
+ ImplInitScrollBar();
+ else
+ {
+ if ( mpScrBar )
+ {
+ // ScrollBar erst spaeter zerstoeren, damit keine rekursiven
+ // Aufrufe entstehen koennen
+ pDelScrBar = mpScrBar;
+ mpScrBar = NULL;
+ }
+ }
+
+ // Item-Offset berechnen
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ if ( nStyle & WB_DOUBLEBORDER )
+ nOff = ITEM_OFFSET_DOUBLE;
+ else
+ nOff = ITEM_OFFSET;
+ }
+ else
+ nOff = 0;
+ nSpace = mnSpacing;
+
+ // Groesse beruecksichtigen, wenn NameField vorhanden
+ if ( nStyle & WB_NAMEFIELD )
+ {
+ long nNameOffset = (nStyle & WB_FLATVALUESET) ? NAME_OFFSET_FLAT : NAME_OFFSET;
+ aWinSize.Height() -= nTxtHeight+(nNameOffset*2);
+ nNameOff = nNameOffset+2+nSpace;
+ }
+ else
+ nNameOff = 0;
+
+ // Offset und Groesse beruecksichtigen, wenn NoneField vorhanden
+ if ( nStyle & WB_NONEFIELD )
+ {
+ nY = nTxtHeight+nOff;
+ nNoneSpace = nSpace;
+ if ( nStyle & WB_RADIOSEL )
+ nY += 8;
+ }
+ else
+ {
+ nY = 0;
+ nNoneSpace = 0;
+ }
+
+ // Breite vom ScrollBar berechnen
+ long nScrBarWidth = 0;
+ if ( mpScrBar )
+ nScrBarWidth = mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
+
+ // Spaltenanzahl berechnen
+ if ( !mnUserCols )
+ {
+ if ( mnUserItemWidth )
+ {
+ mnCols = (USHORT)((aWinSize.Width()-nScrBarWidth+nSpace) / (mnUserItemWidth+nSpace));
+ if ( !mnCols )
+ mnCols = 1;
+ }
+ else
+ mnCols = 1;
+ }
+ else
+ mnCols = mnUserCols;
+
+ // Zeilenanzahl berechnen
+ mbScroll = FALSE;
+ mnLines = (long)mpItemList->Count() / mnCols;
+ if ( mpItemList->Count() % mnCols )
+ mnLines++;
+ else if ( !mnLines )
+ mnLines = 1;
+
+ long nCalcHeight = aWinSize.Height()-nY-nNameOff;
+ if ( mnUserVisLines )
+ mnVisLines = mnUserVisLines;
+ else if ( mnUserItemHeight )
+ {
+ mnVisLines = (nCalcHeight-nNoneSpace+nSpace) / (mnUserItemHeight+nSpace);
+ if ( !mnVisLines )
+ mnVisLines = 1;
+ }
+ else
+ mnVisLines = mnLines;
+ if ( mnLines > mnVisLines )
+ mbScroll = TRUE;
+ if ( mnLines <= mnVisLines )
+ mnFirstLine = 0;
+ else
+ {
+ if ( mnFirstLine > (USHORT)(mnLines-mnVisLines) )
+ mnFirstLine = (USHORT)(mnLines-mnVisLines);
+ }
+
+ // Itemgroessen berechnen
+ long nColSpace = (mnCols-1)*nSpace;
+ long nLineSpace = ((mnVisLines-1)*nSpace)+nNoneSpace;
+ long nItemWidth;
+ long nItemHeight;
+ if ( mnUserItemWidth && !mnUserCols )
+ {
+ nItemWidth = mnUserItemWidth;
+ if ( nItemWidth > aWinSize.Width()-nScrBarWidth-nColSpace )
+ nItemWidth = aWinSize.Width()-nScrBarWidth-nColSpace;
+ }
+ else
+ nItemWidth = (aWinSize.Width()-nScrBarWidth-nColSpace) / mnCols;
+ if ( mnUserItemHeight && !mnUserVisLines )
+ {
+ nItemHeight = mnUserItemHeight;
+ if ( nItemHeight > nCalcHeight-nNoneSpace )
+ nItemHeight = nCalcHeight-nNoneSpace;
+ }
+ else
+ {
+ nCalcHeight -= nLineSpace;
+ nItemHeight = nCalcHeight / mnVisLines;
+ }
+
+ // Windowgroessen runden und virtuelles Device anlegen
+ aWinSize.Width() = (nItemWidth*mnCols)+nColSpace+nScrBarWidth;
+ aWinSize.Height() = (nItemHeight*mnVisLines)+nY+nNameOff+nLineSpace;
+ nStartX = (aOrgWinSize.Width()-aWinSize.Width())/2;
+ maVirDev.SetSettings( GetSettings() );
+ maVirDev.SetBackground( GetBackground() );
+ maVirDev.SetOutputSizePixel( Size( aOrgWinSize.Width(),
+ aWinSize.Height() ), TRUE );
+
+ // Bei zu kleinen Items machen wir nichts
+ long nMinHeight = 2;
+ if ( nStyle & WB_ITEMBORDER )
+ nMinHeight = 4;
+ if ( (nItemWidth <= 0) || (nItemHeight <= nMinHeight) || !nItemCount )
+ {
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpItemList->GetObject( i );
+ pItem->maRect.SetEmpty();
+ }
+
+ if ( nStyle & WB_NONEFIELD )
+ {
+ if ( mpNoneItem )
+ {
+ mpNoneItem->maRect.SetEmpty();
+ mpNoneItem->maText = GetText();
+ }
+ }
+ else
+ {
+ if ( mpNoneItem )
+ {
+ delete mpNoneItem;
+ mpNoneItem = NULL;
+ }
+ }
+
+ if ( mpScrBar )
+ mpScrBar->Hide();
+ }
+ else
+ {
+ // Frame-Style ermitteln
+ if ( nStyle & WB_DOUBLEBORDER )
+ mnFrameStyle = FRAME_DRAW_DOUBLEIN;
+ else
+ mnFrameStyle = FRAME_DRAW_IN;
+
+ // Selektionsfarben und -breiten ermitteln
+ // Gegebenenfalls die Farben anpassen, damit man die Selektion besser
+ // erkennen kann
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Color aHighColor( rStyleSettings.GetHighlightColor() );
+ if ( ((aHighColor.GetRed() > 0x80) || (aHighColor.GetGreen() > 0x80) ||
+ (aHighColor.GetBlue() > 0x80)) ||
+ ((aHighColor.GetRed() == 0x80) && (aHighColor.GetGreen() == 0x80) &&
+ (aHighColor.GetBlue() == 0x80)) )
+ mbBlackSel = TRUE;
+ else
+ mbBlackSel = FALSE;
+
+ // Wenn die Items groesser sind, dann die Selektion doppelt so breit
+ // zeichnen
+ if ( (nStyle & WB_DOUBLEBORDER) &&
+ ((nItemWidth >= 25) && (nItemHeight >= 20)) )
+ mbDoubleSel = TRUE;
+ else
+ mbDoubleSel = FALSE;
+
+ // Trennlinie zum Namefield zeichnen
+ if ( nStyle & WB_NAMEFIELD )
+ {
+ if ( !(nStyle & WB_FLATVALUESET) )
+ {
+ Point aPos1( nStartX+ITEM_OFFSET, aWinSize.Height()-2 );
+ Point aPos2( nStartX+aWinSize.Width()-ITEM_OFFSET-1,
+ aWinSize.Height()-2 );
+ if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
+ {
+ maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
+ maVirDev.DrawLine( aPos1, aPos2 );
+ aPos1.Y()++;
+ aPos2.Y()++;
+ maVirDev.SetLineColor( rStyleSettings.GetLightColor() );
+ }
+ else
+ maVirDev.SetLineColor( rStyleSettings.GetWindowTextColor() );
+ maVirDev.DrawLine( aPos1, aPos2 );
+ }
+
+ // TextOffset befindet sich unter der Kante
+ long nNameOffset = (nStyle & WB_FLATVALUESET) ? NAME_OFFSET_FLAT : NAME_OFFSET;
+ mnTextOffset = aWinSize.Height()+nNameOffset;
+ }
+
+ // Items berechnen und zeichnen
+ maVirDev.SetLineColor();
+ long x = nStartX;
+ long y = nY+nNoneSpace;
+ ULONG nFirstItem = mnFirstLine * mnCols;
+ ULONG nLastItem = nFirstItem + (mnVisLines * mnCols);
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpItemList->GetObject( i );
+
+ if ( (i >= nFirstItem) && (i < nLastItem) )
+ {
+ pItem->maRect.Left() = x;
+ pItem->maRect.Top() = y;
+ pItem->maRect.Right() = pItem->maRect.Left()+nItemWidth-1;
+ pItem->maRect.Bottom() = pItem->maRect.Top()+nItemHeight-1;
+
+ ImplFormatItem( pItem );
+
+ if ( !((i+1) % mnCols) )
+ {
+ x = nStartX;
+ y += nItemHeight+nSpace;
+ }
+ else
+ x += nItemWidth+nSpace;
+ }
+ else
+ pItem->maRect.SetEmpty();
+ }
+
+ // NoSelection-Field erzeugen und anzeigen
+ if ( nStyle & WB_NONEFIELD )
+ {
+ if ( !mpNoneItem )
+ mpNoneItem = new ValueSetItem;
+
+ mpNoneItem->mnId = 0;
+ mpNoneItem->meType = VALUESETITEM_NONE;
+ mpNoneItem->maRect.Left() = nStartX;
+ mpNoneItem->maRect.Right() = mpNoneItem->maRect.Left()+aWinSize.Width()-1;
+ mpNoneItem->maRect.Bottom() = nY-1;
+
+ ImplFormatItem( mpNoneItem );
+ }
+ else
+ {
+ if ( mpNoneItem )
+ {
+ delete mpNoneItem;
+ mpNoneItem = NULL;
+ }
+ }
+
+ // ScrollBar anordnen, Werte setzen und anzeigen
+ if ( mpScrBar )
+ {
+ Point aPos( nStartX+(nItemWidth*mnCols)+nColSpace+SCRBAR_OFFSET,
+ nY+nNoneSpace+1 );
+ Size aSize( nScrBarWidth-SCRBAR_OFFSET,
+ ((nItemHeight+nSpace)*mnVisLines)-2-nSpace );
+ mpScrBar->SetPosSizePixel( aPos, aSize );
+ mpScrBar->SetRangeMax( mnLines );
+ mpScrBar->SetVisibleSize( mnVisLines );
+ mpScrBar->SetThumbPos( (long)mnFirstLine );
+ long nPageSize = mnVisLines;
+ if ( nPageSize < 1 )
+ nPageSize = 1;
+ mpScrBar->SetPageSize( nPageSize );
+ mpScrBar->Show();
+ }
+ }
+
+ // Jetzt haben wir formatiert und warten auf das naechste
+ mbFormat = FALSE;
+
+ // ScrollBar loeschen
+ if ( pDelScrBar )
+ delete pDelScrBar;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDrawItemText( const XubString& rText )
+{
+ if ( !(GetStyle() & WB_NAMEFIELD) )
+ return;
+
+ Size aWinSize = GetOutputSizePixel();
+ long nTxtWidth = GetTextWidth( rText );
+
+ // Rechteck loeschen und Text ausgeben
+ if ( GetStyle() & WB_FLATVALUESET )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ DrawRect( Rectangle( Point( 0, mnTextOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
+ SetTextColor( rStyleSettings.GetButtonTextColor() );
+ }
+ else
+ Erase( Rectangle( Point( 0, mnTextOffset ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
+ DrawText( Point( (aWinSize.Width()-nTxtWidth) / 2, mnTextOffset ), rText );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDrawSelect()
+{
+ if ( !IsReallyVisible() )
+ return;
+
+ BOOL bFocus = HasFocus();
+ BOOL bDrawSel;
+
+ if ( (mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight) )
+ bDrawSel = FALSE;
+ else
+ bDrawSel = TRUE;
+
+ if ( !bFocus &&
+ ((mbNoSelection && !mbHighlight) || (!mbDrawSelection && mbHighlight)) )
+ {
+ XubString aEmptyStr;
+ ImplDrawItemText( aEmptyStr );
+ return;
+ }
+
+ USHORT nItemId = mnSelItemId;
+
+ if ( mbHighlight )
+ nItemId = mnHighItemId;
+
+ ValueSetItem* pItem;
+ if ( nItemId )
+ pItem = mpItemList->GetObject( GetItemPos( nItemId ) );
+ else
+ {
+ if ( mpNoneItem )
+ pItem = mpNoneItem;
+ else
+ {
+ pItem = ImplGetFirstItem();
+ if ( !bFocus || !pItem )
+ return;
+ }
+ }
+
+ if ( pItem->maRect.IsEmpty() )
+ return;
+
+ // Selection malen
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ Rectangle aRect = pItem->maRect;
+ Control::SetFillColor();
+
+ // Selectionsausgabe festlegen
+ WinBits nStyle = GetStyle();
+ if ( nStyle & WB_RADIOSEL )
+ {
+ aRect.Left() += 3;
+ aRect.Top() += 3;
+ aRect.Right() -= 3;
+ aRect.Bottom() -= 3;
+ if ( nStyle & WB_DOUBLEBORDER )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ }
+
+ if ( bFocus )
+ ShowFocus( aRect );
+
+ if ( bDrawSel )
+ {
+ SetLineColor( rStyleSettings.GetHighlightColor() );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ DrawRect( aRect );
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ DrawRect( aRect );
+ }
+ }
+ else
+ {
+ if ( bDrawSel )
+ {
+ if ( mbBlackSel )
+ SetLineColor( Color( COL_BLACK ) );
+ else
+ SetLineColor( rStyleSettings.GetHighlightColor() );
+ DrawRect( aRect );
+ }
+ if ( mbDoubleSel )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( bDrawSel )
+ DrawRect( aRect );
+ }
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ Rectangle aRect2 = aRect;
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( bDrawSel )
+ DrawRect( aRect );
+ if ( mbDoubleSel )
+ {
+ aRect.Left()++;
+ aRect.Top()++;
+ aRect.Right()--;
+ aRect.Bottom()--;
+ if ( bDrawSel )
+ DrawRect( aRect );
+ }
+
+ if ( bDrawSel )
+ {
+ if ( mbBlackSel )
+ SetLineColor( Color( COL_WHITE ) );
+ else
+ SetLineColor( rStyleSettings.GetHighlightTextColor() );
+ }
+ else
+ SetLineColor( Color( COL_LIGHTGRAY ) );
+ DrawRect( aRect2 );
+
+ if ( bFocus )
+ ShowFocus( aRect2 );
+ }
+
+ ImplDrawItemText( pItem->maText );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplHideSelect( USHORT nItemId )
+{
+ Rectangle aRect;
+
+ if ( nItemId )
+ aRect = mpItemList->GetObject( GetItemPos( nItemId ) )->maRect;
+ else
+ {
+ if ( mpNoneItem )
+ aRect = mpNoneItem->maRect;
+ }
+
+ if ( !aRect.IsEmpty() )
+ {
+ HideFocus();
+ Point aPos = aRect.TopLeft();
+ Size aSize = aRect.GetSize();
+ DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplHighlightItem( USHORT nItemId, BOOL bIsSelection )
+{
+ if ( mnHighItemId != nItemId )
+ {
+ // Alten merken, um vorherige Selektion zu entfernen
+ USHORT nOldItem = mnHighItemId;
+ mnHighItemId = nItemId;
+
+ // Wenn keiner selektiert ist, dann Selektion nicht malen
+ if ( !bIsSelection && mbNoSelection )
+ mbDrawSelection = FALSE;
+
+ // Neu ausgeben und alte Selection wegnehmen
+ ImplHideSelect( nOldItem );
+ ImplDrawSelect();
+ mbDrawSelection = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDrawDropPos( BOOL bShow )
+{
+ if ( (mnDropPos != VALUESET_ITEM_NOTFOUND) && mpItemList->Count() )
+ {
+ USHORT nItemPos = mnDropPos;
+ USHORT nItemId1;
+ USHORT nItemId2 = 0;
+ BOOL bRight;
+ if ( nItemPos >= mpItemList->Count() )
+ {
+ nItemPos = (USHORT)(mpItemList->Count()-1);
+ bRight = TRUE;
+ }
+ else
+ bRight = FALSE;
+
+ nItemId1 = GetItemId( nItemPos );
+ if ( (nItemId1 != mnSelItemId) && (nItemId1 != mnHighItemId) )
+ nItemId1 = 0;
+ Rectangle aRect2 = mpItemList->GetObject( nItemPos )->maRect;
+ Rectangle aRect1;
+ if ( bRight )
+ {
+ aRect1 = aRect2;
+ aRect2.SetEmpty();
+ }
+ else if ( nItemPos > 0 )
+ {
+ aRect1 = mpItemList->GetObject( nItemPos-1 )->maRect;
+ nItemId2 = GetItemId( nItemPos-1 );
+ if ( (nItemId2 != mnSelItemId) && (nItemId2 != mnHighItemId) )
+ nItemId2 = 0;
+ }
+
+ // Items ueberhaupt sichtbar (nur Erstes/Letztes)
+ if ( !aRect1.IsEmpty() || !aRect2.IsEmpty() )
+ {
+ if ( nItemId1 )
+ ImplHideSelect( nItemId1 );
+ if ( nItemId2 )
+ ImplHideSelect( nItemId2 );
+
+ if ( bShow )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ long nX;
+ long nY;
+ SetLineColor( rStyleSettings.GetButtonTextColor() );
+ if ( !aRect1.IsEmpty() )
+ {
+ Point aPos = aRect1.RightCenter();
+ nX = aPos.X()-2;
+ nY = aPos.Y();
+ for ( USHORT i = 0; i < 4; i++ )
+ DrawLine( Point( nX-i, nY-i ), Point( nX-i, nY+i ) );
+ }
+ if ( !aRect2.IsEmpty() )
+ {
+ Point aPos = aRect2.LeftCenter();
+ nX = aPos.X()+2;
+ nY = aPos.Y();
+ for ( USHORT i = 0; i < 4; i++ )
+ DrawLine( Point( nX+i, nY-i ), Point( nX+i, nY+i ) );
+ }
+ }
+ else
+ {
+ if ( !aRect1.IsEmpty() )
+ {
+ Point aPos = aRect1.TopLeft();
+ Size aSize = aRect1.GetSize();
+ DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+ }
+ if ( !aRect2.IsEmpty() )
+ {
+ Point aPos = aRect2.TopLeft();
+ Size aSize = aRect2.GetSize();
+ DrawOutDev( aPos, aSize, aPos, aSize, maVirDev );
+ }
+ }
+
+ if ( nItemId1 || nItemId2 )
+ ImplDrawSelect();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplDraw()
+{
+ if ( mbFormat )
+ Format();
+
+ HideFocus();
+
+ Point aDefPos;
+ Size aSize = maVirDev.GetOutputSizePixel();
+
+ if ( mpScrBar )
+ {
+ Point aScrPos = mpScrBar->GetPosPixel();
+ Size aScrSize = mpScrBar->GetSizePixel();
+ Point aTempPos( 0, aScrPos.Y() );
+ Size aTempSize( aSize.Width(), aScrPos.Y() );
+
+ DrawOutDev( aDefPos, aTempSize, aDefPos, aTempSize, maVirDev );
+ aTempSize.Width() = aScrPos.X()-1;
+ aTempSize.Height() = aScrSize.Height();
+ DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
+ aTempPos.Y() = aScrPos.Y()+aScrSize.Height();
+ aTempSize.Width() = aSize.Width();
+ aTempSize.Height() = aSize.Height()-aTempPos.Y();
+ DrawOutDev( aTempPos, aTempSize, aTempPos, aTempSize, maVirDev );
+ }
+ else
+ DrawOutDev( aDefPos, aSize, aDefPos, aSize, maVirDev );
+
+ ImplDrawSelect();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ValueSet::ImplScroll( const Point& rPos )
+{
+ Size aOutSize = GetOutputSizePixel();
+ long nScrBarWidth;
+
+ if ( mpScrBar )
+ nScrBarWidth = mpScrBar->GetSizePixel().Width();
+ else
+ nScrBarWidth = 0;
+
+ if ( !mbScroll || (rPos.X() < 0) || (rPos.X() > aOutSize.Width()-nScrBarWidth) )
+ return FALSE;
+
+ long nScrollOffset;
+ USHORT nOldLine = mnFirstLine;
+ const Rectangle& rTopRect = mpItemList->GetObject( mnFirstLine*mnCols )->maRect;
+ if ( rTopRect.GetHeight() <= 16 )
+ nScrollOffset = VALUESET_SCROLL_OFFSET/2;
+ else
+ nScrollOffset = VALUESET_SCROLL_OFFSET;
+ if ( (mnFirstLine > 0) && (rPos.Y() >= 0) )
+ {
+ long nTopPos = rTopRect.Top();
+ if ( (rPos.Y() >= nTopPos) && (rPos.Y() <= nTopPos+nScrollOffset) )
+ mnFirstLine--;
+ }
+ if ( (mnFirstLine == nOldLine) &&
+ (mnFirstLine < (USHORT)(mnLines-mnVisLines)) && (rPos.Y() < aOutSize.Height()) )
+ {
+ long nBottomPos = mpItemList->GetObject( (mnFirstLine+mnVisLines-1)*mnCols )->maRect.Bottom();
+ if ( (rPos.Y() >= nBottomPos-nScrollOffset) && (rPos.Y() <= nBottomPos) )
+ mnFirstLine++;
+ }
+
+ if ( mnFirstLine != nOldLine )
+ {
+ mbFormat = TRUE;
+ ImplDraw();
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::ImplGetItem( const Point& rPos, BOOL bMove )
+{
+ if ( mpNoneItem )
+ {
+ if ( mpNoneItem->maRect.IsInside( rPos ) )
+ return VALUESET_ITEM_NONEITEM;
+ }
+
+ ULONG nItemCount = mpItemList->Count();
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpItemList->GetObject( i );
+ if ( pItem->maRect.IsInside( rPos ) )
+ return (USHORT)i;
+ }
+
+ // Wenn Spacing gesetzt ist, wird der vorher selektierte
+ // Eintrag zurueckgegeben, wenn die Maus noch nicht das Fenster
+ // verlassen hat
+ if ( bMove && mnSpacing && mnHighItemId )
+ {
+ Point aDefPos;
+ Rectangle aWinRect( aDefPos, maVirDev.GetOutputSizePixel() );
+ if ( aWinRect.IsInside( rPos ) )
+ return GetItemPos( mnHighItemId );
+ }
+
+ return VALUESET_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem* ValueSet::ImplGetItem( USHORT nPos )
+{
+ if ( nPos == VALUESET_ITEM_NONEITEM )
+ return mpNoneItem;
+ else
+ return mpItemList->GetObject( nPos );
+}
+
+// -----------------------------------------------------------------------
+
+ValueSetItem* ValueSet::ImplGetFirstItem()
+{
+ USHORT nItemCount = (USHORT)mpItemList->Count();
+ USHORT i = 0;
+
+ while ( i < nItemCount )
+ {
+ ValueSetItem* pItem = mpItemList->GetObject( i );
+ if ( pItem->meType != VALUESETITEM_SPACE )
+ return pItem;
+ i++;
+ }
+
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ValueSet,ImplScrollHdl, ScrollBar*, pScrollBar )
+{
+ USHORT nNewFirstLine = (USHORT)pScrollBar->GetThumbPos();
+ if ( nNewFirstLine != mnFirstLine )
+ {
+ mnFirstLine = nNewFirstLine;
+ mbFormat = TRUE;
+ ImplDraw();
+ }
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ValueSet,ImplTimerHdl, Timer*, pTimer )
+{
+ ImplTracking( GetPointerPosPixel(), TRUE );
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplTracking( const Point& rPos, BOOL bRepeat )
+{
+ if ( bRepeat || mbSelection )
+ {
+ if ( ImplScroll( rPos ) )
+ {
+ if ( mbSelection )
+ {
+ maTimer.SetTimeoutHdl( LINK( this, ValueSet, ImplTimerHdl ) );
+ maTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
+ maTimer.Start();
+ }
+ }
+ }
+
+ ValueSetItem* pItem = ImplGetItem( ImplGetItem( rPos ) );
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
+ ImplHighlightItem( pItem->mnId );
+ else
+ ImplHighlightItem( mnSelItemId, FALSE );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::ImplEndTracking( const Point& rPos, BOOL bCancel )
+{
+ ValueSetItem* pItem;
+
+ // Bei Abbruch, den alten Status wieder herstellen
+ if ( bCancel )
+ pItem = NULL;
+ else
+ pItem = ImplGetItem( ImplGetItem( rPos ) );
+
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
+ {
+ SelectItem( pItem->mnId );
+ if ( !mbSelection && !(GetStyle() & WB_NOPOINTERFOCUS) )
+ GrabFocus();
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+ Select();
+ }
+ else
+ {
+ ImplHighlightItem( mnSelItemId, FALSE );
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::MouseButtonDown( const MouseEvent& rMEvt )
+{
+ if ( rMEvt.IsLeft() )
+ {
+ ValueSetItem* pItem = ImplGetItem( ImplGetItem( rMEvt.GetPosPixel() ) );
+ if ( mbSelection )
+ {
+ mbHighlight = TRUE;
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) )
+ {
+ mnOldItemId = mnSelItemId;
+ mnHighItemId = mnSelItemId;
+ ImplHighlightItem( pItem->mnId );
+ }
+
+ return;
+ }
+ else
+ {
+ if ( pItem && (pItem->meType != VALUESETITEM_SPACE) && !rMEvt.IsMod2() )
+ {
+ if ( (pItem->mnBits & VIB_NODOUBLECLICK) || (rMEvt.GetClicks() == 1) )
+ {
+ mnOldItemId = mnSelItemId;
+ mbHighlight = TRUE;
+ mnHighItemId = mnSelItemId;
+ ImplHighlightItem( pItem->mnId );
+ StartTracking( STARTTRACK_SCROLLREPEAT );
+ }
+ else if ( rMEvt.GetClicks() == 2 )
+ DoubleClick();
+
+ return;
+ }
+ }
+ }
+
+ Control::MouseButtonDown( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::MouseButtonUp( const MouseEvent& rMEvt )
+{
+ // Wegen SelectionMode
+ if ( rMEvt.IsLeft() && mbSelection )
+ ImplEndTracking( rMEvt.GetPosPixel(), FALSE );
+ else
+ Control::MouseButtonUp( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::MouseMove( const MouseEvent& rMEvt )
+{
+ // Wegen SelectionMode
+ if ( mbSelection )
+ ImplTracking( rMEvt.GetPosPixel(), FALSE );
+ Control::MouseMove( rMEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Tracking( const TrackingEvent& rTEvt )
+{
+ Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
+
+ if ( rTEvt.IsTrackingEnded() )
+ ImplEndTracking( aMousePos, rTEvt.IsTrackingCanceled() );
+ else
+ ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::KeyInput( const KeyEvent& rKEvt )
+{
+ USHORT nLastItem = (USHORT)mpItemList->Count();
+ USHORT nItemPos = VALUESET_ITEM_NOTFOUND;
+ USHORT nCurPos;
+ USHORT nCalcPos;
+
+ if ( !nLastItem || !ImplGetFirstItem() )
+ {
+ Control::KeyInput( rKEvt );
+ return;
+ }
+ else
+ nLastItem--;
+
+ if ( mnSelItemId )
+ nCurPos = GetItemPos( mnSelItemId );
+ else
+ nCurPos = VALUESET_ITEM_NONEITEM;
+ nCalcPos = nCurPos;
+
+ switch ( rKEvt.GetKeyCode().GetCode() )
+ {
+ case KEY_HOME:
+ if ( mpNoneItem )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ {
+ nItemPos = 0;
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE )
+ nItemPos++;
+ }
+ break;
+
+ case KEY_END:
+ nItemPos = nLastItem;
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE )
+ {
+ if ( nItemPos == 0 )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ nItemPos--;
+ }
+ break;
+
+ case KEY_LEFT:
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ nItemPos = nLastItem;
+ else if ( !nCalcPos )
+ {
+ if ( mpNoneItem )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ nItemPos = nLastItem;
+ }
+ else
+ nItemPos = nCalcPos-1;
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ break;
+
+ case KEY_RIGHT:
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ nItemPos = 0;
+ else if ( nCalcPos == nLastItem )
+ {
+ if ( mpNoneItem )
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ else
+ nItemPos = 0;
+ }
+ else
+ nItemPos = nCalcPos+1;
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ break;
+
+ case KEY_UP:
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ {
+ if ( nLastItem+1 <= mnCols )
+ nItemPos = mnCurCol;
+ else
+ {
+ nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+mnCurCol;
+ if ( nItemPos+mnCols <= nLastItem )
+ nItemPos += mnCols;
+ }
+ }
+ else if ( nCalcPos >= mnCols )
+ nItemPos = nCalcPos-mnCols;
+ else
+ {
+ if ( mpNoneItem )
+ {
+ mnCurCol = nCalcPos%mnCols;
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ }
+ else
+ {
+ if ( nLastItem+1 <= mnCols )
+ nItemPos = nCalcPos;
+ else
+ {
+ nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+nCalcPos;
+ if ( nItemPos+mnCols <= nLastItem )
+ nItemPos += mnCols;
+ }
+ }
+ }
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ break;
+
+ case KEY_DOWN:
+ do
+ {
+ if ( nCalcPos == VALUESET_ITEM_NONEITEM )
+ nItemPos = mnCurCol;
+ else if ( nCalcPos+mnCols <= nLastItem )
+ nItemPos = nCalcPos+mnCols;
+ else
+ {
+ if ( mpNoneItem )
+ {
+ mnCurCol = nCalcPos%mnCols;
+ nItemPos = VALUESET_ITEM_NONEITEM;
+ }
+ else
+ nItemPos = nCalcPos%mnCols;
+ }
+ nCalcPos = nItemPos;
+ }
+ while ( ImplGetItem( nItemPos )->meType == VALUESETITEM_SPACE );
+ break;
+
+ default:
+ Control::KeyInput( rKEvt );
+ break;
+ }
+
+ if ( nItemPos != VALUESET_ITEM_NOTFOUND )
+ {
+ USHORT nItemId;
+ if ( nItemPos != VALUESET_ITEM_NONEITEM )
+ nItemId = GetItemId( nItemPos );
+ else
+ nItemId = 0;
+ if ( nItemId != mnSelItemId )
+ {
+ SelectItem( nItemId );
+ Select();
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Command( const CommandEvent& rCEvt )
+{
+ if ( (rCEvt.GetCommand() == COMMAND_WHEEL) ||
+ (rCEvt.GetCommand() == COMMAND_STARTAUTOSCROLL) ||
+ (rCEvt.GetCommand() == COMMAND_AUTOSCROLL) )
+ {
+ if ( HandleScrollCommand( rCEvt, NULL, mpScrBar ) )
+ return;
+ }
+
+ Control::Command( rCEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Paint( const Rectangle& rRect )
+{
+ if ( GetStyle() & WB_FLATVALUESET )
+ {
+ const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
+ SetLineColor();
+ SetFillColor( rStyleSettings.GetFaceColor() );
+ long nOffY = maVirDev.GetOutputSizePixel().Height();
+ Size aWinSize = GetOutputSizePixel();
+ DrawRect( Rectangle( Point( 0, nOffY ), Point( aWinSize.Width(), aWinSize.Height() ) ) );
+ }
+
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::GetFocus()
+{
+ ImplDrawSelect();
+ Control::GetFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::LoseFocus()
+{
+ if ( mbNoSelection && mnSelItemId )
+ ImplHideSelect( mnSelItemId );
+ else
+ HideFocus();
+ Control::LoseFocus();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Resize()
+{
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ Control::Resize();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::RequestHelp( const HelpEvent& rHEvt )
+{
+ if ( (rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON)) == HELPMODE_QUICK )
+ {
+ Point aPos = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
+ ULONG nItemCount = mpItemList->Count();
+ for ( ULONG i = 0; i < nItemCount; i++ )
+ {
+ ValueSetItem* pItem = mpItemList->GetObject( i );
+ if ( pItem->maRect.IsInside( aPos ) )
+ {
+ Rectangle aItemRect = pItem->maRect;
+ Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
+ aItemRect.Left() = aPt.X();
+ aItemRect.Top() = aPt.Y();
+ aPt = OutputToScreenPixel( aItemRect.BottomRight() );
+ aItemRect.Right() = aPt.X();
+ aItemRect.Bottom() = aPt.Y();
+ Help::ShowQuickHelp( this, aItemRect, GetItemText( pItem->mnId ) );
+ return;
+ }
+ }
+ }
+
+ Control::RequestHelp( rHEvt );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::StateChanged( StateChangedType nType )
+{
+ Control::StateChanged( nType );
+
+ if ( nType == STATE_CHANGE_INITSHOW )
+ {
+ if ( mbFormat )
+ Format();
+ }
+ else if ( nType == STATE_CHANGE_UPDATEMODE )
+ {
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+ else if ( nType == STATE_CHANGE_TEXT )
+ {
+ if ( mpNoneItem && !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( mpNoneItem );
+ Invalidate( mpNoneItem->maRect );
+ }
+ }
+ 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();
+ }
+ else if ( nType == STATE_CHANGE_STYLE )
+ {
+ mbFormat = TRUE;
+ ImplInitSettings( FALSE, FALSE, TRUE );
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::DataChanged( const DataChangedEvent& rDCEvt )
+{
+ Control::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();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Select()
+{
+ maSelectHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::DoubleClick()
+{
+ maDoubleClickHdl.Call( this );
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::UserDraw( const UserDrawEvent& )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Image& rImage, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem;
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_IMAGE;
+ pItem->maImage = rImage;
+ mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Color& rColor, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem;
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_COLOR;
+ pItem->maColor = rColor;
+ mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Image& rImage,
+ const XubString& rText, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem;
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_IMAGE;
+ pItem->maImage = rImage;
+ pItem->maText = rText;
+ mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, const Color& rColor,
+ const XubString& rText, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem;
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_COLOR;
+ pItem->maColor = rColor;
+ pItem->maText = rText;
+ mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertItem( USHORT nItemId, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertItem(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertItem(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem;
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_USERDRAW;
+ mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::InsertSpace( USHORT nItemId, USHORT nPos )
+{
+ DBG_ASSERT( nItemId, "ValueSet::InsertSpace(): ItemId == 0" );
+ DBG_ASSERT( GetItemPos( nItemId ) == VALUESET_ITEM_NOTFOUND,
+ "ValueSet::InsertSpace(): ItemId already exists" );
+
+ ValueSetItem* pItem = new ValueSetItem;
+ pItem->mnId = nItemId;
+ pItem->meType = VALUESETITEM_SPACE;
+ mpItemList->Insert( pItem, (ULONG)nPos );
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::RemoveItem( USHORT nItemId )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ delete mpItemList->Remove( nPos );
+
+ // Variablen zuruecksetzen
+ if ( (mnHighItemId == nItemId) || (mnSelItemId == nItemId) )
+ {
+ mnCurCol = 0;
+ mnOldItemId = 0;
+ mnHighItemId = 0;
+ mnSelItemId = 0;
+ mbNoSelection = TRUE;
+ }
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::CopyItems( const ValueSet& rValueSet )
+{
+ ValueSetItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+
+ pItem = rValueSet.mpItemList->First();
+ while ( pItem )
+ {
+ mpItemList->Insert( new ValueSetItem( *pItem ) );
+ pItem = rValueSet.mpItemList->Next();
+ }
+
+ // Variablen zuruecksetzen
+ mnFirstLine = 0;
+ mnCurCol = 0;
+ mnOldItemId = 0;
+ mnHighItemId = 0;
+ mnSelItemId = 0;
+ mbNoSelection = TRUE;
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::Clear()
+{
+ ValueSetItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ delete pItem;
+ pItem = mpItemList->Next();
+ }
+ mpItemList->Clear();
+
+ // Variablen zuruecksetzen
+ mnFirstLine = 0;
+ mnCurCol = 0;
+ mnOldItemId = 0;
+ mnHighItemId = 0;
+ mnSelItemId = 0;
+ mbNoSelection = TRUE;
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemCount() const
+{
+ return (USHORT)mpItemList->Count();
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemPos( USHORT nItemId ) const
+{
+ ValueSetItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->mnId == nItemId )
+ return (USHORT)mpItemList->GetCurPos();
+ pItem = mpItemList->Next();
+ }
+
+ return VALUESET_ITEM_NOTFOUND;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemId( USHORT nPos ) const
+{
+ ValueSetItem* pItem = mpItemList->GetObject( nPos );
+
+ if ( pItem )
+ return pItem->mnId;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemId( const Point& rPos ) const
+{
+ ValueSetItem* pItem = mpItemList->First();
+ while ( pItem )
+ {
+ if ( pItem->maRect.IsInside( rPos ) )
+ return pItem->mnId;
+
+ pItem = mpItemList->Next();
+ }
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+Rectangle ValueSet::GetItemRect( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maRect;
+ else
+ return Rectangle();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetColCount( USHORT nNewCols )
+{
+ if ( mnUserCols != nNewCols )
+ {
+ mnUserCols = nNewCols;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetLineCount( USHORT nNewLines )
+{
+ if ( mnUserVisLines != nNewLines )
+ {
+ mnUserVisLines = nNewLines;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemWidth( long nNewItemWidth )
+{
+ if ( mnUserItemWidth != nNewItemWidth )
+ {
+ mnUserItemWidth = nNewItemWidth;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemHeight( long nNewItemHeight )
+{
+ if ( mnUserItemHeight != nNewItemHeight )
+ {
+ mnUserItemHeight = nNewItemHeight;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetFirstLine( USHORT nNewLine )
+{
+ if ( mnFirstLine != nNewLine )
+ {
+ mnFirstLine = nNewLine;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SelectItem( USHORT nItemId )
+{
+ USHORT nPos;
+
+ if ( nItemId )
+ {
+ nPos = GetItemPos( nItemId );
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+ if ( mpItemList->GetObject( nPos )->meType == VALUESETITEM_SPACE )
+ return;
+ }
+
+ if ( (mnSelItemId != nItemId) || mbNoSelection )
+ {
+ USHORT nOldItem = mnSelItemId;
+ mnSelItemId = nItemId;
+ mbNoSelection = FALSE;
+
+ BOOL bNewOut;
+ BOOL bNewLine;
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ bNewOut = TRUE;
+ else
+ bNewOut = FALSE;
+ bNewLine = FALSE;
+
+ // Gegebenenfalls in den sichtbaren Bereich scrollen
+ if ( mbScroll && nItemId )
+ {
+ USHORT nNewLine = (USHORT)(nPos / mnCols);
+ if ( nNewLine < mnFirstLine )
+ {
+ mnFirstLine = nNewLine;
+ bNewLine = TRUE;
+ }
+ else if ( nNewLine > (USHORT)(mnFirstLine+mnVisLines-1) )
+ {
+ mnFirstLine = (USHORT)(nNewLine-mnVisLines+1);
+ bNewLine = TRUE;
+ }
+ }
+
+ if ( bNewOut )
+ {
+ if ( bNewLine )
+ {
+ // Falls sich der sichtbare Bereich geaendert hat,
+ // alles neu ausgeben
+ mbFormat = TRUE;
+ ImplDraw();
+ }
+ else
+ {
+ // alte Selection wegnehmen und neue ausgeben
+ ImplHideSelect( nOldItem );
+ ImplDrawSelect();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetNoSelection()
+{
+ mbNoSelection = TRUE;
+ mbHighlight = FALSE;
+ mbSelection = FALSE;
+
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemBits( USHORT nItemId, USHORT nItemBits )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ mpItemList->GetObject( nPos )->mnBits = nItemBits;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::GetItemBits( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mnBits;
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemImage( USHORT nItemId, const Image& rImage )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpItemList->GetObject( nPos );
+ pItem->meType = VALUESETITEM_IMAGE;
+ pItem->maImage = rImage;
+
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( pItem );
+ Invalidate( pItem->maRect );
+ }
+ else
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Image ValueSet::GetItemImage( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maImage;
+ else
+ return Image();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemColor( USHORT nItemId, const Color& rColor )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpItemList->GetObject( nPos );
+ pItem->meType = VALUESETITEM_COLOR;
+ pItem->maColor = rColor;
+
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( pItem );
+ Invalidate( pItem->maRect );
+ }
+ else
+ mbFormat = TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Color ValueSet::GetItemColor( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maColor;
+ else
+ return Color();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemData( USHORT nItemId, void* pData )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpItemList->GetObject( nPos );
+ pItem->mpData = pData;
+
+ if ( pItem->meType == VALUESETITEM_USERDRAW )
+ {
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ ImplFormatItem( pItem );
+ Invalidate( pItem->maRect );
+ }
+ else
+ mbFormat = TRUE;
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void* ValueSet::GetItemData( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->mpData;
+ else
+ return NULL;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetItemText( USHORT nItemId, const XubString& rText )
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ ValueSetItem* pItem = mpItemList->GetObject( nPos );
+ pItem->maText = rText;
+
+ if ( !mbFormat && IsReallyVisible() && IsUpdateMode() )
+ {
+ USHORT nTempId = mnSelItemId;
+
+ if ( mbHighlight )
+ nTempId = mnHighItemId;
+
+ if ( nTempId == nItemId )
+ ImplDrawItemText( pItem->maText );
+ }
+}
+
+// -----------------------------------------------------------------------
+
+XubString ValueSet::GetItemText( USHORT nItemId ) const
+{
+ USHORT nPos = GetItemPos( nItemId );
+
+ if ( nPos != VALUESET_ITEM_NOTFOUND )
+ return mpItemList->GetObject( nPos )->maText;
+ else
+ return XubString();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetColor( const Color& rColor )
+{
+ maColor = rColor;
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ ImplDraw();
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::SetExtraSpacing( USHORT nNewSpacing )
+{
+ if ( GetStyle() & WB_ITEMBORDER )
+ {
+ mnSpacing = nNewSpacing;
+
+ mbFormat = TRUE;
+ if ( IsReallyVisible() && IsUpdateMode() )
+ Invalidate();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::StartSelection()
+{
+ mnOldItemId = mnSelItemId;
+ mbHighlight = TRUE;
+ mbSelection = TRUE;
+ mnHighItemId = mnSelItemId;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::EndSelection()
+{
+ if ( mbHighlight )
+ {
+ if ( IsTracking() )
+ EndTracking( ENDTRACK_CANCEL );
+
+ ImplHighlightItem( mnSelItemId );
+ mbHighlight = FALSE;
+ }
+ mbSelection = FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL ValueSet::StartDrag( const CommandEvent& rCEvt, Region& rRegion )
+{
+ if ( rCEvt.GetCommand() != COMMAND_STARTDRAG )
+ return FALSE;
+
+ // Gegebenenfalls eine vorhandene Aktion abbrechen
+ EndSelection();
+
+ // Testen, ob angeklickte Seite selektiert ist. Falls dies nicht
+ // der Fall ist, setzen wir ihn als aktuellen Eintrag. Falls Drag and
+ // Drop auch mal ueber Tastatur ausgeloest werden kann, testen wir
+ // dies nur bei einer Mausaktion.
+ USHORT nSelId;
+ if ( rCEvt.IsMouseEvent() )
+ nSelId = GetItemId( rCEvt.GetMousePosPixel() );
+ else
+ nSelId = mnSelItemId;
+
+ // Falls kein Eintrag angeklickt wurde, starten wir kein Dragging
+ if ( !nSelId )
+ return FALSE;
+
+ // Testen, ob Seite selektiertiert ist. Falls nicht, als aktuelle
+ // Seite setzen und Select rufen.
+ if ( nSelId != mnSelItemId )
+ {
+ SelectItem( nSelId );
+ Update();
+ Select();
+ }
+
+#ifdef MAC
+ Region aRegion( GetItemRect( nSelId ) );
+#else
+ Region aRegion;
+#endif
+
+ // Region zuweisen
+ rRegion = aRegion;
+
+ return TRUE;
+}
+
+// -----------------------------------------------------------------------
+
+Size ValueSet::CalcWindowSizePixel( const Size& rItemSize, USHORT nDesireCols,
+ USHORT nDesireLines )
+{
+ long nCalcCols = (long)nDesireCols;
+ long nCalcLines = (long)nDesireLines;
+
+ if ( !nCalcCols )
+ {
+ if ( mnUserCols )
+ nCalcCols = (long)mnUserCols;
+ else
+ nCalcCols = 1;
+ }
+
+ if ( !nCalcLines )
+ {
+ nCalcLines = mnVisLines;
+
+ if ( mbFormat )
+ {
+ if ( mnUserVisLines )
+ nCalcLines = mnUserVisLines;
+ else
+ {
+ nCalcLines = (long)mpItemList->Count() / nCalcCols;
+ if ( mpItemList->Count() % nCalcCols )
+ nCalcLines++;
+ else if ( !nCalcLines )
+ nCalcLines = 1;
+ }
+ }
+ }
+
+ Size aSize( rItemSize.Width()*nCalcCols, rItemSize.Height()*nCalcLines );
+ WinBits nStyle = GetStyle();
+ long nTxtHeight = GetTextHeight();
+ long nSpace;
+ long n;
+
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ if ( nStyle & WB_DOUBLEBORDER )
+ n = ITEM_OFFSET_DOUBLE;
+ else
+ n = ITEM_OFFSET;
+
+ aSize.Width() += n*nCalcCols;
+ aSize.Height() += n*nCalcLines;
+ }
+ else
+ n = 0;
+
+ if ( mnSpacing )
+ {
+ nSpace = mnSpacing;
+ aSize.Width() += mnSpacing*(nCalcCols-1);
+ aSize.Height() += mnSpacing*(nCalcLines-1);
+ }
+ else
+ nSpace = 0;
+
+ if ( nStyle & WB_NAMEFIELD )
+ {
+ long nNameOffset = (nStyle & WB_FLATVALUESET) ? NAME_OFFSET_FLAT : NAME_OFFSET;
+ aSize.Height() += nTxtHeight + (nNameOffset*3) + 2 + nSpace;
+ }
+
+ if ( nStyle & WB_NONEFIELD )
+ {
+ aSize.Height() += nTxtHeight + n + nSpace;
+ if ( nStyle & WB_RADIOSEL )
+ aSize.Height() += 8;
+ }
+
+ // Evt. ScrollBar-Breite aufaddieren
+ aSize.Width() += GetScrollWidth();
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+Size ValueSet::CalcItemSizePixel( const Size& rItemSize, BOOL bOut ) const
+{
+ Size aSize = rItemSize;
+
+ WinBits nStyle = GetStyle();
+ if ( nStyle & WB_ITEMBORDER )
+ {
+ long n;
+
+ if ( nStyle & WB_DOUBLEBORDER )
+ n = ITEM_OFFSET_DOUBLE;
+ else
+ n = ITEM_OFFSET;
+
+ if ( bOut )
+ {
+ aSize.Width() += n;
+ aSize.Height() += n;
+ }
+ else
+ {
+ aSize.Width() -= n;
+ aSize.Height() -= n;
+ }
+ }
+
+ return aSize;
+}
+
+// -----------------------------------------------------------------------
+
+long ValueSet::GetScrollWidth() const
+{
+ if ( GetStyle() & WB_VSCROLL )
+ {
+ ((ValueSet*)this)->ImplInitScrollBar();
+ return mpScrBar->GetSizePixel().Width()+SCRBAR_OFFSET;
+ }
+ else
+ return 0;
+}
+
+// -----------------------------------------------------------------------
+
+USHORT ValueSet::ShowDropPos( const Point& rPos )
+{
+ mbDropPos = TRUE;
+
+ // Gegebenenfalls scrollen
+ ImplScroll( rPos );
+
+ // DropPosition ermitteln
+ USHORT nPos = ImplGetItem( rPos, TRUE );
+ if ( nPos == VALUESET_ITEM_NONEITEM )
+ nPos = 0;
+ else if ( nPos == VALUESET_ITEM_NOTFOUND )
+ {
+ Size aOutSize = GetOutputSizePixel();
+ if ( GetStyle() & WB_NAMEFIELD )
+ aOutSize.Height() = mnTextOffset;
+ if ( (rPos.X() >= 0) && (rPos.X() < aOutSize.Width()) &&
+ (rPos.Y() >= 0) && (rPos.Y() < aOutSize.Height()) )
+ nPos = (USHORT)mpItemList->Count();
+ }
+ else
+ {
+ // Im letzten viertel, dann wird ein Item spaeter eingefuegt
+ Rectangle aRect = mpItemList->GetObject( nPos )->maRect;
+ if ( rPos.X() > aRect.Left()+aRect.GetWidth()-(aRect.GetWidth()/4) )
+ nPos++;
+ }
+
+ if ( nPos != mnDropPos )
+ {
+ ImplDrawDropPos( FALSE );
+ mnDropPos = nPos;
+ ImplDrawDropPos( TRUE );
+ }
+
+ return mnDropPos;
+}
+
+// -----------------------------------------------------------------------
+
+void ValueSet::HideDropPos()
+{
+ if ( mbDropPos )
+ {
+ ImplDrawDropPos( FALSE );
+ mbDropPos = FALSE;
+ }
+}