/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <svx/rubydialog.hxx>
#include <tools/shl.hxx>
#include <svx/dialmgr.hxx>
#include <svx/dialogs.hrc>
#include <rubydialog.hrc>
#include <sfx2/app.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <svl/eitem.hxx>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/style/XStyle.hpp>
#include <com/sun/star/text/XRubySelection.hpp>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/text/RubyAdjust.hpp>
#include <com/sun/star/view/XSelectionChangeListener.hpp>
#include <com/sun/star/view/XSelectionSupplier.hpp>
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#include <svtools/colorcfg.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::frame;
using namespace com::sun::star::text;
using namespace com::sun::star::beans;
using namespace com::sun::star::style;
using namespace com::sun::star::text;
using namespace com::sun::star::view;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using rtl::OUString;

#define C2U(cChar) rtl::OUString::createFromAscii(cChar)

SFX_IMPL_CHILDWINDOW( SvxRubyChildWindow, SID_RUBY_DIALOG );

static const sal_Char cRubyBaseText[] = "RubyBaseText";
static const sal_Char cRubyText[] = "RubyText";
static const sal_Char cCharacterStyles[] = "CharacterStyles";
static const sal_Char cRubyAdjust[] = "RubyAdjust";
static const sal_Char cRubyIsAbove[] = "RubyIsAbove";
static const sal_Char cDisplayName[] = "DisplayName";
static const sal_Char cRubyCharStyleName[] = "RubyCharStyleName";
static const sal_Char cRubies[] = "Rubies";
/* -----------------------------09.01.01 17:24--------------------------------

 ---------------------------------------------------------------------------*/
SvxRubyChildWindow::SvxRubyChildWindow( Window* _pParent, sal_uInt16 nId,
	SfxBindings* pBindings, SfxChildWinInfo* pInfo) :
	SfxChildWindow(_pParent, nId)
{
	pWindow = new SvxRubyDialog( pBindings, this, _pParent, SVX_RES( RID_SVXDLG_RUBY ) );
	SvxRubyDialog* pDlg = (SvxRubyDialog*) pWindow;

	if ( pInfo->nFlags & SFX_CHILDWIN_ZOOMIN )
		pDlg->RollUp();

	eChildAlignment = SFX_ALIGN_NOALIGNMENT;

    pDlg->Initialize( pInfo );
}
/* -----------------------------10.01.01 13:53--------------------------------

 ---------------------------------------------------------------------------*/
SfxChildWinInfo SvxRubyChildWindow::GetInfo() const
{
	return SfxChildWindow::GetInfo();
}
/* -----------------------------09.01.01 17:17--------------------------------

 ---------------------------------------------------------------------------*/
class SvxRubyData_Impl : public cppu::WeakImplHelper1
                                <  ::com::sun::star::view::XSelectionChangeListener >
{
    Reference<XModel>               xModel;
	Reference<XRubySelection> 		xSelection;
	Sequence<PropertyValues>		aRubyValues;
    Reference<XController>          xController;
    sal_Bool                        bHasSelectionChanged;
    public:
        SvxRubyData_Impl();
        ~SvxRubyData_Impl();

    void    SetController(Reference<XController> xCtrl);
    Reference<XModel>               GetModel()
                                    {
                                        if(!xController.is())
                                            xModel = 0;
                                        else
                                            xModel = xController->getModel();
                                        return xModel;
                                    }
    sal_Bool                        HasSelectionChanged() const{return bHasSelectionChanged;}
    Reference<XRubySelection>       GetRubySelection()
                                    {
                                        xSelection = Reference<XRubySelection>(xController, UNO_QUERY);
                                        return xSelection;
                                    }
    void                            UpdateRubyValues(sal_Bool bAutoUpdate)
                                    {
                                        if(!xSelection.is())
                                            aRubyValues.realloc(0);
                                        else
                                            aRubyValues = xSelection->getRubyList(bAutoUpdate);
										bHasSelectionChanged = sal_False;
                                    }
    Sequence<PropertyValues>&       GetRubyValues() {return aRubyValues;}
    void                            AssertOneEntry();

    virtual void SAL_CALL selectionChanged( const ::com::sun::star::lang::EventObject& aEvent ) throw (RuntimeException);
    virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (RuntimeException);

};
//-----------------------------------------------------------------------------
SvxRubyData_Impl::SvxRubyData_Impl() :
    bHasSelectionChanged(sal_False)
{
}
//-----------------------------------------------------------------------------
SvxRubyData_Impl::~SvxRubyData_Impl()
{
}
//-----------------------------------------------------------------------------
void    SvxRubyData_Impl::SetController(Reference<XController> xCtrl)
{
    if(xCtrl.get() != xController.get())
    {
        try
        {
            Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
            if(xSelSupp.is())
                xSelSupp->removeSelectionChangeListener(this);

            bHasSelectionChanged = sal_True;
            xController = xCtrl;
            xSelSupp = Reference<XSelectionSupplier>(xController, UNO_QUERY);
            if(xSelSupp.is())
                xSelSupp->addSelectionChangeListener(this);
        }
        catch(Exception&)
        {}
    }
}
//-----------------------------------------------------------------------------
void SvxRubyData_Impl::selectionChanged( const EventObject& ) throw (RuntimeException)
{
    bHasSelectionChanged = sal_True;
}
//-----------------------------------------------------------------------------
void SvxRubyData_Impl::disposing( const EventObject&) throw (RuntimeException)
{
    try
    {
        Reference<XSelectionSupplier> xSelSupp(xController, UNO_QUERY);
        if(xSelSupp.is())
            xSelSupp->removeSelectionChangeListener(this);
    }
    catch(Exception&)
    {}
    xController = 0;
}
//-----------------------------------------------------------------------------
void  SvxRubyData_Impl::AssertOneEntry()
{
    //create one entry
    if(!aRubyValues.getLength())
    {
        aRubyValues.realloc(1);
        Sequence<PropertyValue>& rValues = aRubyValues.getArray()[0];
        rValues.realloc(5);
        PropertyValue* pValues = rValues.getArray();
        pValues[0].Name = C2U(cRubyBaseText);
        pValues[1].Name = C2U(cRubyText);
        pValues[2].Name = C2U(cRubyAdjust);
        pValues[3].Name = C2U(cRubyIsAbove);
        pValues[4].Name = C2U(cRubyCharStyleName);
    }
}
/* ---------------------------------------------------------------------------

 ---------------------------------------------------------------------------*/
SvxRubyDialog::SvxRubyDialog( SfxBindings *pBind, SfxChildWindow *pCW,
									Window* _pParent, const ResId& rResId ) :
	SfxModelessDialog( pBind, pCW, _pParent, rResId ),
    aLeftFT(this,               ResId(FT_LEFT,*rResId.GetResMgr() )),
    aLeft1ED(this,              ResId(ED_LEFT_1,*rResId.GetResMgr()  )),
    aRightFT(this,              ResId(FT_RIGHT,*rResId.GetResMgr()  )),
	aRight1ED(this, 			ResId(ED_RIGHT_1,*rResId.GetResMgr() )),
	aLeft2ED(this, 				ResId(ED_LEFT_2,*rResId.GetResMgr()  )),
	aRight2ED(this, 			ResId(ED_RIGHT_2,*rResId.GetResMgr() )),
	aLeft3ED(this, 				ResId(ED_LEFT_3,*rResId.GetResMgr()  )),
	aRight3ED(this, 			ResId(ED_RIGHT_3,*rResId.GetResMgr() )),
	aLeft4ED(this, 				ResId(ED_LEFT_4,*rResId.GetResMgr()  )),
	aRight4ED(this, 			ResId(ED_RIGHT_4,*rResId.GetResMgr() )),
	aScrollSB(this, 			ResId(SB_SCROLL,*rResId.GetResMgr()  )),
	aAutoDetectionCB(this, 		ResId(CB_AUTO_DETECT,*rResId.GetResMgr()	)),
	aAdjustFT(this, 			ResId(FT_ADJUST,*rResId.GetResMgr()		)),
	aAdjustLB(this, 			ResId(LB_ADJUST,*rResId.GetResMgr()		)),
	aPositionFT(this,           ResId(FT_POSITION,*rResId.GetResMgr()     )),
    aPositionLB(this,           ResId(LB_POSITION,*rResId.GetResMgr()     )),
	aCharStyleFT(this,          ResId(FT_CHAR_STYLE,*rResId.GetResMgr()     )),
	aCharStyleLB(this, 			ResId(LB_CHAR_STYLE,*rResId.GetResMgr()		)),
	aStylistPB(this, 			ResId(PB_STYLIST,*rResId.GetResMgr()		)),
	aPreviewFT(this, 			ResId(FT_PREVIEW,*rResId.GetResMgr()		)),
	aPreviewWin(*this, 			ResId(WIN_PREVIEW,*rResId.GetResMgr()		)),
	aApplyPB(this, 				ResId(PB_APPLY,*rResId.GetResMgr()			)),
	aClosePB(this, 				ResId(PB_CLOSE,*rResId.GetResMgr()			)),
	aHelpPB(this, 				ResId(PB_HELP,*rResId.GetResMgr()			)),
	nLastPos(0),
    nCurrentEdit(0),
	bModified(sal_False),
	pBindings(pBind)
{
    xImpl = pImpl = new SvxRubyData_Impl;
    FreeResource();
    //#85638# automatic detection not yet available
    aAutoDetectionCB.Hide();
	aEditArr[0] = &aLeft1ED; aEditArr[1] = &aRight1ED;
	aEditArr[2] = &aLeft2ED; aEditArr[3] = &aRight2ED;
	aEditArr[4] = &aLeft3ED; aEditArr[5] = &aRight3ED;
	aEditArr[6] = &aLeft4ED; aEditArr[7] = &aRight4ED;

	aApplyPB.SetClickHdl(LINK(this, SvxRubyDialog, ApplyHdl_Impl));
	aClosePB.SetClickHdl(LINK(this, SvxRubyDialog, CloseHdl_Impl));
	aStylistPB.SetClickHdl(LINK(this, SvxRubyDialog, StylistHdl_Impl));
	aAutoDetectionCB.SetClickHdl(LINK(this, SvxRubyDialog, AutomaticHdl_Impl));
	aAdjustLB.SetSelectHdl(LINK(this, SvxRubyDialog, AdjustHdl_Impl));
    aPositionLB.SetSelectHdl(LINK(this, SvxRubyDialog, PositionHdl_Impl));
    aCharStyleLB.SetSelectHdl(LINK(this, SvxRubyDialog, CharStyleHdl_Impl));

	Link aScrLk(LINK(this, SvxRubyDialog, ScrollHdl_Impl));
	aScrollSB.SetScrollHdl( aScrLk );
	aScrollSB.SetEndScrollHdl( aScrLk );

	Link aEditLk(LINK(this, SvxRubyDialog, EditModifyHdl_Impl));
    Link aScrollLk(LINK(this, SvxRubyDialog, EditScrollHdl_Impl));
    Link aJumpLk(LINK(this, SvxRubyDialog, EditJumpHdl_Impl));
	for(sal_uInt16 i = 0; i < 8; i++)
    {
		aEditArr[i]->SetModifyHdl(aEditLk);
        aEditArr[i]->SetJumpHdl(aJumpLk);
        if(!i || 7 == i)
            aEditArr[i]->SetScrollHdl(aScrollLk);
    }

	UpdateColors();

	String leftLabelName = aLeftFT.GetText(), rightLabelName = aRightFT.GetText();
	aLeft2ED.SetAccessibleName(leftLabelName);
	aLeft3ED.SetAccessibleName(leftLabelName);
	aLeft4ED.SetAccessibleName(leftLabelName);
	aRight2ED.SetAccessibleName(rightLabelName);
	aRight3ED.SetAccessibleName(rightLabelName);
	aRight4ED.SetAccessibleName(rightLabelName);
}
/* -----------------------------09.01.01 17:17--------------------------------

 ---------------------------------------------------------------------------*/
SvxRubyDialog::~SvxRubyDialog()
{
	ClearCharStyleList();
    EventObject aEvent;
    xImpl->disposing(aEvent);
}
/* -----------------------------01.02.01 10:29--------------------------------

 ---------------------------------------------------------------------------*/
void SvxRubyDialog::ClearCharStyleList()
{
    for(sal_uInt16 i = 0; i < aCharStyleLB.GetEntryCount(); i++)
	{
		void* pData = aCharStyleLB.GetEntryData(i);
		delete (OUString*)pData;
    }
    aCharStyleLB.Clear();
}
/* -----------------------------09.01.01 17:17--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool 	SvxRubyDialog::Close()
{
	pBindings->GetDispatcher()->Execute( SID_RUBY_DIALOG,
		                      SFX_CALLMODE_ASYNCHRON |
							  SFX_CALLMODE_RECORD);
	return sal_True;
}
/* -----------------------------29.01.01 15:26--------------------------------

 ---------------------------------------------------------------------------*/
void SvxRubyDialog::Activate()
{
	SfxModelessDialog::Activate();
	SfxPoolItem* pState = 0;
	SfxItemState	eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
    sal_Bool bEnable = (eState < SFX_ITEM_AVAILABLE) || !pState || !((SfxBoolItem*)pState)->GetValue();
    aStylistPB.Enable(bEnable);
	//get selection from current view frame
	SfxViewFrame* pCurFrm = SfxViewFrame::Current();
    Reference< XController > xCtrl = pCurFrm->GetFrame().GetController();
    pImpl->SetController(xCtrl);
    if(pImpl->HasSelectionChanged())
    {

        Reference< XRubySelection > xRubySel = pImpl->GetRubySelection();
        pImpl->UpdateRubyValues(aAutoDetectionCB.IsChecked());
        EnableControls(xRubySel.is());
        if(xRubySel.is())
        {
            Reference< XModel > xModel = pImpl->GetModel();
            const String sCharStyleSelect = aCharStyleLB.GetSelectEntry();
            ClearCharStyleList();
            Reference<XStyleFamiliesSupplier> xSupplier(xModel, UNO_QUERY);
            if(xSupplier.is())
            {
                try
                {
                    Reference<XNameAccess> xFam = xSupplier->getStyleFamilies();
                    Any aChar = xFam->getByName(C2U(cCharacterStyles));
                    Reference<XNameContainer> xChar;
                    aChar >>= xChar;
                    Reference<XIndexAccess> xCharIdx(xChar, UNO_QUERY);
                    if(xCharIdx.is())
                    {
                        OUString sUIName(C2U(cDisplayName));
                        for(sal_Int32 nStyle = 0; nStyle < xCharIdx->getCount(); nStyle++)
                        {
                            Any aStyle = xCharIdx->getByIndex(nStyle);
                            Reference<XStyle> xStyle;
                            aStyle >>= xStyle;
                            Reference<XPropertySet> xPrSet(xStyle, UNO_QUERY);
                            OUString sName, sCoreName;
                            if(xPrSet.is())
                            {
                                Reference<XPropertySetInfo> xInfo = xPrSet->getPropertySetInfo();
                                if(xInfo->hasPropertyByName(sUIName))
                                {
                                    Any aName = xPrSet->getPropertyValue(sUIName);
                                    aName >>= sName;
                                }
                            }
                            Reference<XNamed> xNamed(xStyle, UNO_QUERY);
                            if(xNamed.is())
                            {
                                sCoreName = xNamed->getName();
                                if(!sName.getLength())
                                    sName = sCoreName;
                            }
                            if(sName.getLength())
                            {
                                sal_uInt16 nPos = aCharStyleLB.InsertEntry(sName);
                                aCharStyleLB.SetEntryData( nPos, new OUString(sCoreName) );

                            }
                        }
                    }
                }
                catch(Exception&)
                {
                    DBG_ERROR("exception in style access");
                }
                if(sCharStyleSelect.Len())
                    aCharStyleLB.SelectEntry(sCharStyleSelect);
            }
            aCharStyleLB.Enable(xSupplier.is());
            aCharStyleFT.Enable(xSupplier.is());
        }
		Update();
		aPreviewWin.Invalidate();
	}
}
/* -----------------------------29.01.01 15:26--------------------------------

 ---------------------------------------------------------------------------*/
void	SvxRubyDialog::Deactivate()
{
	SfxModelessDialog::Deactivate();
}
/* -----------------------------30.01.01 15:35--------------------------------

 ---------------------------------------------------------------------------*/
void SvxRubyDialog::SetText(sal_Int32 nPos, Edit& rLeft, Edit& rRight)
{
	OUString sLeft, sRight;
    const Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
    sal_Bool bEnable = aRubyValues.getLength() > nPos;
	if(bEnable)
	{
        const Sequence<PropertyValue> aProps = aRubyValues.getConstArray()[nPos];
		const PropertyValue* pProps = aProps.getConstArray();
		for(sal_Int32 nProp = 0; nProp < aProps.getLength(); nProp++)
		{
			if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyBaseText)))
				pProps[nProp].Value >>= sLeft;
			else if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyText)))
				pProps[nProp].Value >>= sRight;
		}
	}
	else if(!nPos)
        bEnable = sal_True;
	rLeft.Enable(bEnable);
	rRight.Enable(bEnable);
	rLeft.SetText(sLeft);
	rRight.SetText(sRight);
	rLeft.SaveValue();
	rRight.SaveValue();
}
//-----------------------------------------------------------------------------
void SvxRubyDialog::GetText()
{
	long nTempLastPos = GetLastPos();
	for(int i = 0; i < 8; i+=2)
	{
        if(aEditArr[i]->IsEnabled() &&
			(aEditArr[i]->GetText() != aEditArr[i]->GetSavedValue() ||
			aEditArr[i + 1]->GetText() != aEditArr[i + 1]->GetSavedValue()))
		{
            Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
            DBG_ASSERT(aRubyValues.getLength() > (i / 2 + nTempLastPos), "wrong index" );
			SetModified(sal_True);
            Sequence<PropertyValue> &rProps = aRubyValues.getArray()[i / 2 + nTempLastPos];
			PropertyValue* pProps = rProps.getArray();
			for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
			{
				if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyBaseText)))
					pProps[nProp].Value <<= OUString(aEditArr[i]->GetText());
				else if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyText)))
					pProps[nProp].Value <<= OUString(aEditArr[i + 1]->GetText());
			}
		}
	}
}
//-----------------------------------------------------------------------------
void SvxRubyDialog::Update()
{
    const Sequence<PropertyValues>& aRubyValues = pImpl->GetRubyValues();
    sal_Int32 nLen = aRubyValues.getLength();
	aScrollSB.Enable(nLen > 4);
	aScrollSB.SetRange( Range(0, nLen > 4 ? nLen - 4 : 0));
	aScrollSB.SetThumbPos(0);
	SetLastPos(0);
	SetModified(sal_False);

	sal_Int16 nAdjust = -1;
    sal_Int16 nPosition = -1;
	OUString sCharStyleName, sTmp;
	sal_Bool bCharStyleEqual = sal_True;
	for(sal_Int32 nRuby = 0; nRuby < nLen; nRuby++)
	{
        const Sequence<PropertyValue> &rProps = aRubyValues.getConstArray()[nRuby];
        const PropertyValue* pProps = rProps.getConstArray();
		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
		{
			if(nAdjust > -2 &&
				pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyAdjust)))
			{
                sal_Int16 nTmp = sal_Int16();
				pProps[nProp].Value >>= nTmp;
				if(!nRuby)
					nAdjust = nTmp;
				else if(nAdjust != nTmp)
					nAdjust = -2;
			}
            if(nPosition > -2 &&
                pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyIsAbove)))
            {
                sal_Bool bTmp = *(sal_Bool*)pProps[nProp].Value.getValue();
                if(!nRuby)
                    nPosition = bTmp ? 0 : 1;
                else if( (!nPosition && !bTmp) || (nPosition == 1 && bTmp)  )
                    nPosition = -2;
            }
			if(bCharStyleEqual &&
				pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyCharStyleName)))
			{
				pProps[nProp].Value >>= sTmp;
				if(!nRuby)
					sCharStyleName = sTmp;
				else if(sCharStyleName != sTmp)
					bCharStyleEqual = sal_False;
			}
		}
	}
    if(!nLen)
    {
        //enable selection if the ruby list is empty
        nAdjust = 0;
        nPosition = 0;
    }
    if(nAdjust > -1)
		aAdjustLB.SelectEntryPos(nAdjust);
	else
		aAdjustLB.SetNoSelection();
    if(nPosition > -1)
        aPositionLB.SelectEntryPos(nPosition ? 1 : 0);
    if(!nLen || (bCharStyleEqual && !sCharStyleName.getLength()))
        sCharStyleName = C2U(cRubies);
    if(sCharStyleName.getLength())
    {
        for(sal_uInt16 i = 0; i < aCharStyleLB.GetEntryCount(); i++)
        {
            const OUString* pCoreName = (const OUString*)aCharStyleLB.GetEntryData(i);
            if(pCoreName && sCharStyleName == *pCoreName)
            {
                aCharStyleLB.SelectEntryPos(i);
                break;
            }
        }
    }
    else
		aCharStyleLB.SetNoSelection();

	ScrollHdl_Impl(&aScrollSB);
}
/* -----------------------------16.02.01 14:01--------------------------------

 ---------------------------------------------------------------------------*/
void	SvxRubyDialog::GetCurrentText(String& rBase, String& rRuby)
{
	rBase = aEditArr[nCurrentEdit * 2]->GetText();
	rRuby = aEditArr[nCurrentEdit * 2 + 1]->GetText();
}
/* -----------------------------31.01.01 14:09--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, ScrollHdl_Impl, ScrollBar*, pScroll)
{
	long nPos = pScroll->GetThumbPos();
	if(GetLastPos() != nPos)
	{
		GetText();
	}
	SetText(nPos++, aLeft1ED, aRight1ED);
	SetText(nPos++, aLeft2ED, aRight2ED);
	SetText(nPos++, aLeft3ED, aRight3ED);
	SetText(nPos, aLeft4ED, aRight4ED);
	SetLastPos(nPos - 3);
	aPreviewWin.Invalidate();
	return 0;
}
/* -----------------------------30.01.01 14:48--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, ApplyHdl_Impl, PushButton*, EMPTYARG)
{
    const Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
    if(!aRubyValues.getLength())
    {
        AssertOneEntry();
        PositionHdl_Impl(&aPositionLB);
        AdjustHdl_Impl(&aAdjustLB);
        CharStyleHdl_Impl(&aCharStyleLB);
    }
    GetText();
	//reset all edit fields - SaveValue is called
	ScrollHdl_Impl(&aScrollSB);

    Reference<XRubySelection>  xSelection = pImpl->GetRubySelection();
    if(IsModified() && xSelection.is())
    {
        try
        {
            xSelection->setRubyList(aRubyValues, aAutoDetectionCB.IsChecked());
        }
        catch(Exception& )
        {
            DBG_ERROR("Exception caught");
        }
    }
	return 0;
}
/* -----------------------------29.01.01 09:38--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, CloseHdl_Impl, PushButton*, EMPTYARG)
{
	Close();
	return 0;
}
/* -----------------------------29.01.01 15:10--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, StylistHdl_Impl, PushButton*, EMPTYARG)
{
	SfxPoolItem* pState = 0;
	SfxItemState	eState = pBindings->QueryState( SID_STYLE_DESIGNER, pState );
	if(eState <= SFX_ITEM_SET || !pState || !((SfxBoolItem*)pState)->GetValue())
	{
		pBindings->GetDispatcher()->Execute( SID_STYLE_DESIGNER,
		                      SFX_CALLMODE_ASYNCHRON |
							  SFX_CALLMODE_RECORD);
	}
	return 0;
}
/* -----------------------------30.01.01 15:32--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, AutomaticHdl_Impl, CheckBox*, pBox)
{
    pImpl->UpdateRubyValues(pBox->IsChecked());
    Update();
	return 0;
}
/* -----------------------------31.01.01 16:37--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, AdjustHdl_Impl, ListBox*, pBox)
{
    AssertOneEntry();
    sal_Int16 nAdjust = pBox->GetSelectEntryPos();
    Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
    for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
	{
        Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
		PropertyValue* pProps = rProps.getArray();
		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
		{
			if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyAdjust)))
				pProps[nProp].Value <<= nAdjust;
		}
		SetModified(sal_True);
	}
	aPreviewWin.Invalidate();
	return 0;
}
/* -----------------------------01.06.01 10:24--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, PositionHdl_Impl, ListBox*, pBox)
{
    AssertOneEntry();
    sal_Bool bAbove = !pBox->GetSelectEntryPos();
    const Type& rType = ::getBooleanCppuType();
    Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
    for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
	{
        Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
		PropertyValue* pProps = rProps.getArray();
		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
		{
            if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyIsAbove)))
                pProps[nProp].Value.setValue(&bAbove, rType);
		}
		SetModified(sal_True);
	}
	aPreviewWin.Invalidate();
	return 0;
}
/* -----------------------------01.02.01 10:06--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, CharStyleHdl_Impl, ListBox*, EMPTYARG )
{
    AssertOneEntry();
    OUString sStyleName;
	if(LISTBOX_ENTRY_NOTFOUND != aCharStyleLB.GetSelectEntryPos())
		sStyleName = *(OUString*) aCharStyleLB.GetEntryData(aCharStyleLB.GetSelectEntryPos());
    Sequence<PropertyValues>&  aRubyValues = pImpl->GetRubyValues();
    for(sal_Int32 nRuby = 0; nRuby < aRubyValues.getLength(); nRuby++)
	{
        Sequence<PropertyValue> &rProps = aRubyValues.getArray()[nRuby];
		PropertyValue* pProps = rProps.getArray();
		for(sal_Int32 nProp = 0; nProp < rProps.getLength(); nProp++)
		{
			if(pProps[nProp].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(cRubyCharStyleName)))
			{
				pProps[nProp].Value <<= sStyleName;
			}
		}
		SetModified(sal_True);
	}
	return 0;
}
/* -----------------------------16.02.01 08:35--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, EditModifyHdl_Impl, Edit*, pEdit)
{
	for(sal_uInt16 i = 0; i < 8; i++)
	{
		if(pEdit == aEditArr[i])
		{
			nCurrentEdit = i / 2;
			break;
		}
	}
	aPreviewWin.Invalidate();
	return 0;
}
/* -----------------------------17.07.01 09:11--------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, EditScrollHdl_Impl, sal_Int32*, pParam)
{
    long nRet = 0;
    if(aScrollSB.IsEnabled())
    {
        //scroll forward
        if(*pParam > 0 && (aEditArr[7]->HasFocus() || aEditArr[6]->HasFocus() ))
        {
            if(aScrollSB.GetRangeMax() > aScrollSB.GetThumbPos())
            {
                aScrollSB.SetThumbPos(aScrollSB.GetThumbPos() + 1);
                aEditArr[6]->GrabFocus();
                nRet = 1;
            }
        }
        //scroll backward
        else if(aScrollSB.GetThumbPos() && (aEditArr[0]->HasFocus()||aEditArr[1]->HasFocus()) )
        {
            aScrollSB.SetThumbPos(aScrollSB.GetThumbPos() - 1);
            aEditArr[1]->GrabFocus();
            nRet = 1;
        }
        if(nRet)
            ScrollHdl_Impl(&aScrollSB);
    }
    return nRet;
}
/* -----------------------------20.07.2001 15:18------------------------------

 ---------------------------------------------------------------------------*/
IMPL_LINK(SvxRubyDialog, EditJumpHdl_Impl, sal_Int32*, pParam)
{
    sal_uInt16 nIndex = USHRT_MAX;
    for(sal_uInt16 i = 0; i < 8; i++)
    {
        if(aEditArr[i]->HasFocus())
            nIndex = i;
    }
    if(nIndex < 8)
    {
        if(*pParam > 0)
        {
            if(nIndex < 6)
                aEditArr[nIndex + 2]->GrabFocus();
            else if( EditScrollHdl_Impl(pParam))
                aEditArr[nIndex]->GrabFocus();
        }
        else
        {
            if(nIndex > 1)
                aEditArr[nIndex - 2]->GrabFocus();
            else if( EditScrollHdl_Impl(pParam))
                aEditArr[nIndex]->GrabFocus();
        }
    }
    return 0;
};
/* -----------------------------19.06.01 11:33--------------------------------

 ---------------------------------------------------------------------------*/
void SvxRubyDialog::AssertOneEntry()
{
    pImpl->AssertOneEntry();
}

// ----------------------------------------------------------------------------

void SvxRubyDialog::UpdateColors( void )
{
	const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
	svtools::ColorConfig		aColorConfig;

	Font					aFnt( aPreviewWin.GetFont() );

	Color					aNewTextCol( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
	Color					aNewFillCol( rStyleSettings.GetWindowColor() );

	if( aNewFillCol != aFnt.GetFillColor() || aNewTextCol != aFnt.GetColor() )
	{
		aFnt.SetFillColor( aNewFillCol );
		aFnt.SetColor( aNewTextCol );
		aPreviewWin.SetFont( aFnt );

		aPreviewWin.Invalidate();
	}
}

// ----------------------------------------------------------------------------

void SvxRubyDialog::DataChanged( const DataChangedEvent& rDCEvt )
{
	SfxModelessDialog::DataChanged( rDCEvt );

	if( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) && ( rDCEvt.GetFlags() & SETTINGS_STYLE ) )
		UpdateColors();
}

/* -----------------------------29.01.01 15:44--------------------------------

 ---------------------------------------------------------------------------*/
void lcl_MoveBox(long nOffset, Edit& rLeft, Edit& rRight)
{
	Size aLeftSz(rLeft.GetSizePixel());
	Point aRightPos(rRight.GetPosPixel());
	Size aRightSz(rRight.GetSizePixel());
	aLeftSz.Width() += nOffset;
	aRightSz.Width() -= nOffset;
	aRightPos.X() += nOffset;
	rLeft.SetSizePixel(aLeftSz);
	rRight.SetPosSizePixel(aRightPos, aRightSz);

}
/* -----------------------------16.02.01 08:09--------------------------------

 ---------------------------------------------------------------------------*/
RubyPreview::RubyPreview(SvxRubyDialog& rParent, const ResId& rResId) :
		Window(&rParent, rResId),
		rParentDlg(rParent)
{
	SetMapMode(MAP_TWIP);
	Size aWinSize = GetOutputSize();

	Font aFont = GetFont();
	aFont.SetHeight(aWinSize.Height() / 4);
	SetFont(aFont);

	SetBorderStyle( WINDOW_BORDER_MONO );
}
/* -----------------------------29.01.01 14:05--------------------------------

 ---------------------------------------------------------------------------*/
void RubyPreview::Paint( const Rectangle& /* rRect */ )
{
    Font aRubyFont = GetFont();
    Font aSaveFont(aRubyFont);
    aRubyFont.SetHeight(aRubyFont.GetHeight() * 70 / 100);

    Size aWinSize = GetOutputSize();
	Rectangle aRect(Point(0, 0), aWinSize);
	SetLineColor();
	SetFillColor( aSaveFont.GetFillColor() );
	DrawRect(aRect);

	String sBaseText, sRubyText;
	rParentDlg.GetCurrentText(sBaseText, sRubyText);

	long nTextHeight = GetTextHeight();
	long nBaseWidth = GetTextWidth(sBaseText);
    SetFont(aRubyFont);
    long nRubyWidth = GetTextWidth(sRubyText);
    SetFont(aSaveFont);

	sal_uInt16 nAdjust = rParentDlg.aAdjustLB.GetSelectEntryPos();
	//use center if no adjustment is available
	if(nAdjust > 4)
		nAdjust = 1;

    //which part is stretched ?
	sal_Bool bRubyStretch = nBaseWidth >= nRubyWidth;

	long nCenter = aWinSize.Width() / 2;
	long nLeftStart = nCenter - (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));
	long nRightEnd = nCenter + (bRubyStretch ? (nBaseWidth / 2) : (nRubyWidth / 2));

	long nYRuby = aWinSize.Height() / 4 - nTextHeight / 2;
	long nYBase = aWinSize.Height() * 3 / 4 - nTextHeight / 2;

    //use above also if no selection is set
    sal_Bool bAbove = rParentDlg.aPositionLB.GetSelectEntryPos() != 1;
    if(!bAbove)
    {
        long nTmp = nYRuby;
        nYRuby = nYBase;
        nYBase = nTmp;
    }
	long nYOutput, nOutTextWidth;
	String sOutputText;


    if(bRubyStretch)
	{
		DrawText( Point( nLeftStart , nYBase),  sBaseText );
		nYOutput = nYRuby;
		sOutputText = sRubyText;
		nOutTextWidth = nRubyWidth;
        SetFont(aRubyFont);
	}
	else
	{
        SetFont(aRubyFont);
        DrawText( Point( nLeftStart , nYRuby),  sRubyText );
		nYOutput = nYBase;
		sOutputText = sBaseText;
		nOutTextWidth = nBaseWidth;
        SetFont(aSaveFont);
    }

	switch(nAdjust)
	{
		case RubyAdjust_LEFT:
			DrawText( Point( nLeftStart , nYOutput),  sOutputText );
		break;
		case RubyAdjust_RIGHT:
			DrawText( Point( nRightEnd - nOutTextWidth, nYOutput),  sOutputText );
		break;
		case RubyAdjust_INDENT_BLOCK:
		{
			long nCharWidth = GetTextWidth(String::CreateFromAscii("X"));
			if(nOutTextWidth < (nRightEnd - nLeftStart - nCharWidth))
			{
				nCharWidth /= 2;
				nLeftStart += nCharWidth;
				nRightEnd -= nCharWidth;
			}
		}
		// no break!
		case RubyAdjust_BLOCK:
		if(sOutputText.Len() > 1)
		{
			xub_StrLen nCount = sOutputText.Len();
			long nSpace = ((nRightEnd - nLeftStart) - GetTextWidth(sOutputText)) / (nCount - 1);
			for(xub_StrLen i = 0; i < nCount; i++)
			{
				sal_Unicode cChar = sOutputText.GetChar(i);
				DrawText( Point( nLeftStart , nYOutput),  cChar);
				long nCharWidth = GetTextWidth(cChar);
				nLeftStart += nCharWidth + nSpace;
			}
			break;
		}
		//no break;
		case RubyAdjust_CENTER:
			DrawText( Point( nCenter - nOutTextWidth / 2 , nYOutput),  sOutputText );
		break;
	}
    SetFont(aSaveFont);
}
/* -----------------------------16.02.01 15:12--------------------------------

 ---------------------------------------------------------------------------*/
void RubyEdit::GetFocus()
{
	GetModifyHdl().Call(this);
	Edit::GetFocus();
}
/* -----------------------------17.07.01 09:00--------------------------------

 ---------------------------------------------------------------------------*/
long  RubyEdit::PreNotify( NotifyEvent& rNEvt )
{
    long nHandled = 0;
	if ( rNEvt.GetType() == EVENT_KEYINPUT )
	{
        const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
        const KeyCode&  rKeyCode = pKEvt->GetKeyCode();
        sal_uInt16 nMod = rKeyCode.GetModifier();
        sal_uInt16 nCode = rKeyCode.GetCode();
        if( nCode == KEY_TAB && (!nMod || KEY_SHIFT == nMod))
        {
            sal_Int32 nParam = KEY_SHIFT == nMod ? -1 : 1;
            if(aScrollHdl.IsSet() && aScrollHdl.Call(&nParam))
                nHandled = 1;
        }
        else if(KEY_UP == nCode || KEY_DOWN == nCode)
        {
            sal_Int32 nParam = KEY_UP == nCode ? -1 : 1;
            aJumpHdl.Call(&nParam);
        }
	}
	if(!nHandled)
        nHandled = Edit::PreNotify(rNEvt);
	return nHandled;
}
