Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


Hello Noel,

I'm sending the inputwin.cxx with the changes I've made in
ScInputBargroup. Do not push it as of now. I'd be making some more
changes as mentioned in above mail before it can be pushed.

On Mon, Jul 4, 2011 at 3:53 PM, Anurag Jain <anuragjainfzd@gmail.com> wrote:
Hello Noel,

Yes I have made some changes as you mentioned this weekend. There are
certain thing I'm not getting properly.

1: I'm able to toggle the height of ScMultiBar and ScInputBarGroup on
button click. But the increment happens inside the ScInputWindow i.e.
the excess window size do not appear. It toggles inside the
ScInputWindow. To make it look the height of complete panel should be
varied.So in order to do that will it be a good idea to add a
ScInputWindow object in ScInputBarGroup and use it to vary the whole
panel's height ?

2: Also one more thing, when button is clicked twice , the position
window, and other formula images all disappears leaving a blank on
left side of panel. I guess the ScInputBarGroup changes its vertical
position. I tried resetting it always to (nLeft,0) but the LO did not
start for some reason. As of now I'm trying to fix that. I'll discuss
about these problems today in IRC and things required to be improved a
little bit before putting it in master branch.

On Mon, Jul 4, 2011 at 3:29 PM, Noel Power <nopower@novell.com> wrote:
Hi Anurag,
As discussed on IRC I had hoped to see the patch you promised to send. The
one that rename's your class, restores ScTextWnd and removes  the
unnecessary changes and does some cleanup of the existing code, is there
some problem? everything ok? I need those changes to integrate your code
into master.
On 26/06/11 18:23, Anurag Jain wrote:

yes as soon as I get things placed in right place I'll be working on
switching from single line to multiline mode on the button click.

Is there any update regarding with size switching, any chance of a patch for
the above?, it would be great to get those changes in addition to the work
above into master ( would give people a better idea and feel for what you
are doing, without the resize changes the visual difference with the work
sofar isn't so obvious )
So, time is fast running out on this, I need the patches already promised
asap, if you can provide the extra parts that's even better.

Thanks
Noel


Thanks and regards.

--
Anurag Jain
Final yr B.Tech CSE
SASTRA University
Thanjavur(T.N.)-613402




Thanks ans regards
-- 
Anurag Jain
Final yr B.Tech CSE
SASTRA University
Thanjavur(T.N.)-613402
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include <algorithm>

#include<stdio.h>

#include "scitems.hxx"
#include <editeng/eeitem.hxx>

#include <sfx2/app.hxx>
#include <editeng/adjitem.hxx>
#include <editeng/editview.hxx>
#include <editeng/editstat.hxx>
#include <editeng/frmdiritem.hxx>
#include <editeng/lspcitem.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/event.hxx>
#include <sfx2/imgmgr.hxx>
#include <stdlib.h>             // qsort
#include <editeng/scriptspaceitem.hxx>
#include <editeng/scripttypeitem.hxx>
#include <vcl/cursor.hxx>
#include <vcl/help.hxx>
#include <svl/stritem.hxx>

#include "inputwin.hxx"
#include "scmod.hxx"
#include "uiitems.hxx"
#include "global.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include "globstr.hrc"
#include "editutil.hxx"
#include "inputhdl.hxx"
#include "tabvwsh.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "appoptio.hxx"
#include "rangenam.hxx"
#include <formula/compiler.hrc>
#include "dbdata.hxx"
#include "rangeutl.hxx"
#include "docfunc.hxx"
#include "funcdesc.hxx"
#include <editeng/fontitem.hxx>
#include <com/sun/star/accessibility/XAccessible.hpp>
#include "AccessibleEditObject.hxx"
#include "AccessibleText.hxx"

#define TEXT_STARTPOS           5
#define THESIZE                         1000000 //!!! langt... :-)
#define TBX_WINDOW_HEIGHT       22 // in Pixeln - fuer alle Systeme gleich?

enum ScNameInputType
{
    SC_NAME_INPUT_CELL,
    SC_NAME_INPUT_RANGE,
    SC_NAME_INPUT_NAMEDRANGE,
    SC_NAME_INPUT_DATABASE,
    SC_NAME_INPUT_ROW,
    SC_NAME_INPUT_SHEET,
    SC_NAME_INPUT_DEFINE,
    SC_NAME_INPUT_BAD_NAME,
    SC_NAME_INPUT_BAD_SELECTION
};


//==================================================================
//      class ScInputWindowWrapper
//==================================================================

SFX_IMPL_CHILDWINDOW(ScInputWindowWrapper,FID_INPUTLINE_STATUS)

ScInputWindowWrapper::ScInputWindowWrapper( Window*          pParentP,
                                            sal_uInt16                   nId,
                                            SfxBindings*         pBindings,
                                            SfxChildWinInfo* /* pInfo */ )
    :   SfxChildWindow( pParentP, nId )
{
    ScInputWindow* pWin=new ScInputWindow( pParentP, pBindings );
    pWindow = pWin;

    pWin->Show();

    pWin->SetSizePixel( pWin->CalcWindowSizePixel() );

    eChildAlignment = SFX_ALIGN_LOWESTTOP;
    pBindings->Invalidate( FID_TOGGLEINPUTLINE );
}

//      GetInfo fliegt wieder raus, wenn es ein SFX_IMPL_TOOLBOX gibt !!!!

SfxChildWinInfo ScInputWindowWrapper::GetInfo() const
{
    SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
    return aInfo;
}

//==================================================================

#define IMAGE(id) pImgMgr->SeekImage(id)

//==================================================================
//      class ScInputWindow
//==================================================================

ScInputWindow::ScInputWindow( Window* pParent, SfxBindings* pBind ) :
// mit WB_CLIPCHILDREN, sonst Flicker
        ToolBox         ( pParent, WinBits(WB_BORDER|WB_3DLOOK|WB_CLIPCHILDREN) ),
        aWndPos         ( this ),
//      maScrollBar     ( this,  WB_VERT | WB_DRAG ),
        aBarGroup       ( this),
        pInputHdl               ( NULL ),
        pBindings       ( pBind ),
        aTextOk                 ( ScResId( SCSTR_QHELP_BTNOK ) ),               // not always new 
from Resource
        aTextCancel             ( ScResId( SCSTR_QHELP_BTNCANCEL ) ),
        aTextSum                ( ScResId( SCSTR_QHELP_BTNSUM ) ),
        aTextEqual              ( ScResId( SCSTR_QHELP_BTNEQUAL ) ),
        bIsOkCancelMode ( false )
{
    ScModule*            pScMod  = SC_MOD();
    SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );

    // #i73615# don't rely on SfxViewShell::Current while constructing the input line
    // (also for GetInputHdl below)
    ScTabViewShell* pViewSh = NULL;
    SfxDispatcher* pDisp = pBind->GetDispatcher();
    if ( pDisp )
    {
        SfxViewFrame* pViewFrm = pDisp->GetFrame();
        if ( pViewFrm )
            pViewSh = PTR_CAST( ScTabViewShell, pViewFrm->GetViewShell() );
    }
    DBG_ASSERT( pViewSh, "no view shell for input window" );

    // Position window, 3 buttons, input window
    InsertWindow    ( 1, &aWndPos, 0,                                                               
  0 );
    InsertSeparator (                                                                               
                      1 );
    InsertItem      ( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ), 0, 2 );
    InsertItem      ( SID_INPUT_SUM,      IMAGE( SID_INPUT_SUM ), 0,      3 );
    InsertItem      ( SID_INPUT_EQUAL,    IMAGE( SID_INPUT_EQUAL ), 0,    4 );
    InsertSeparator (                                                                               
                  5 );
    InsertWindow    ( 7, &aBarGroup, 0,                              6 );

    printf("Ctor ScInputWindow\n");
    aWndPos        .SetQuickHelpText( ScResId( SCSTR_QHELP_POSWND ) );
    aWndPos    .SetHelpId               ( HID_INSWIN_POS );

    //  kein SetHelpText, die Hilfetexte kommen aus der Hilfe

    SetItemText ( SID_INPUT_FUNCTION, ScResId( SCSTR_QHELP_BTNCALC ) );
    SetHelpId   ( SID_INPUT_FUNCTION, HID_INSWIN_CALC );

    SetItemText ( SID_INPUT_SUM, aTextSum );
    SetHelpId   ( SID_INPUT_SUM, HID_INSWIN_SUMME );

    SetItemText ( SID_INPUT_EQUAL, aTextEqual );
    SetHelpId   ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );

    SetHelpId( HID_SC_INPUTWIN );       // fuer die ganze Eingabezeile

    aWndPos             .Show();
    aBarGroup   .Show();

    pInputHdl = SC_MOD()->GetInputHdl( pViewSh, false );    // use own handler even if ref-handler 
is set
    if (pInputHdl)
        pInputHdl->SetInputWindow( this );

    if ( pInputHdl && pInputHdl->GetFormString().Len() )
    {
        //      Umschalten waehrend der Funktionsautopilot aktiv ist
        //      -> Inhalt des Funktionsautopiloten wieder anzeigen
        //!     auch Selektion (am InputHdl gemerkt) wieder anzeigen

        aBarGroup.SetTextString( pInputHdl->GetFormString() );
    }
    else if ( pInputHdl && pInputHdl->IsInputMode() )
    {
        //      wenn waehrend des Editierens die Eingabezeile weg war
        //      (Editieren einer Formel, dann umschalten zu fremdem Dokument/Hilfe),
        //      wieder den gerade editierten Text aus dem InputHandler anzeigen

        aBarGroup.SetTextString( pInputHdl->GetEditString() );  // Text anzeigen
        if ( pInputHdl->IsTopMode() )
            pInputHdl->SetMode( SC_INPUT_TABLE );               // Focus kommt eh nach unten
    }
    else if ( pViewSh )
        pViewSh->UpdateInputHandler( sal_True ); // unbedingtes Update

    pImgMgr->RegisterToolBox( this );
    SetAccessibleName(ScResId(STR_ACC_TOOLBAR_FORMULA));
}

ScInputWindow::~ScInputWindow()
{
    sal_Bool bDown = ( ScGlobal::pSysLocale == NULL );    // after Clear?

    //  if any view's input handler has a pointer to this input window, reset it
    //  (may be several ones, #74522#)
    //  member pInputHdl is not used here

    if ( !bDown )
    {
        TypeId aScType = TYPE(ScTabViewShell);
        SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
        while ( pSh )
        {
            ScInputHandler* pHdl = ((ScTabViewShell*)pSh)->GetInputHandler();
            if ( pHdl && pHdl->GetInputWindow() == this )
            {
                pHdl->SetInputWindow( NULL );
                pHdl->StopInputWinEngine( false );  // reset pTopView pointer
            }
            pSh = SfxViewShell::GetNext( *pSh, &aScType );
        }
    }

    SfxImageManager::GetImageManager( SC_MOD() )->ReleaseToolBox( this );
}

void ScInputWindow::SetInputHandler( ScInputHandler* pNew )
{
    //  wird im Activate der View gerufen...

    if ( pNew != pInputHdl )
    {
        //      Bei Reload (letzte Version) ist pInputHdl der Input-Handler der alten,
        //      geloeschten ViewShell, darum hier auf keinen Fall anfassen!

        pInputHdl = pNew;
        if (pInputHdl)
            pInputHdl->SetInputWindow( this );
    }
}

bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const
{
    bool bSubTotal = false;
    ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
    if ( pViewSh )
    {
        ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
        size_t nRangeCount (pRangeList->size());
        size_t nRangeIndex (0);
        while (!bSubTotal && nRangeIndex < nRangeCount)
        {
            const ScRange* pRange = (*pRangeList)[nRangeIndex];
            if( pRange )
            {
                SCTAB nTabEnd(pRange->aEnd.Tab());
                SCTAB nTab(pRange->aStart.Tab());
                while (!bSubTotal && nTab <= nTabEnd)
                {
                    SCROW nRowEnd(pRange->aEnd.Row());
                    SCROW nRow(pRange->aStart.Row());
                    while (!bSubTotal && nRow <= nRowEnd)
                    {
                        if (pDoc->RowFiltered(nRow, nTab))
                            bSubTotal = true;
                        else
                            ++nRow;
                    }
                    ++nTab;
                }
            }
            ++nRangeIndex;
        }

        const ScDBCollection::NamedDBs& rDBs = pDoc->GetDBCollection()->getNamedDBs();
        ScDBCollection::NamedDBs::const_iterator itr = rDBs.begin(), itrEnd = rDBs.end();
        for (; !bSubTotal && itr != itrEnd; ++itr)
        {
            const ScDBData& rDB = *itr;
            if (!rDB.HasAutoFilter())
                continue;

            nRangeIndex = 0;
            while (!bSubTotal && nRangeIndex < nRangeCount)
            {
                const ScRange* pRange = (*pRangeList)[nRangeIndex];
                if( pRange )
                {
                    ScRange aDBArea;
                    rDB.GetArea(aDBArea);
                    if (aDBArea.Intersects(*pRange))
                        bSubTotal = true;
                }
                ++nRangeIndex;
            }
        }
    }
    return bSubTotal;
}

void ScInputWindow::Select()
{
    ScModule* pScMod = SC_MOD();
    ToolBox::Select();

    switch ( GetCurItemId() )
    {
        case SID_INPUT_FUNCTION:
            {
                //!     new method at ScModule to query if function autopilot is open
                SfxViewFrame* pViewFrm = SfxViewFrame::Current();
                if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
                {
                    pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
                                              SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );

                    //  die Toolbox wird sowieso disabled, also braucht auch nicht umgeschaltet
                    //  zu werden, egal ob's geklappt hat oder nicht
//                                      SetOkCancelMode();
                }
            }
            break;

        case SID_INPUT_CANCEL:
            pScMod->InputCancelHandler();
            SetSumAssignMode();
            break;

        case SID_INPUT_OK:
            pScMod->InputEnterHandler();
            SetSumAssignMode();
            aBarGroup.Invalidate();             // sonst bleibt Selektion stehen
            break;

        case SID_INPUT_SUM:
            {
                ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
                if ( pViewSh )
                {
                    const ScMarkData& rMark = pViewSh->GetViewData()->GetMarkData();
                    if ( rMark.IsMarked() || rMark.IsMultiMarked() )
                    {
                        ScRangeList aMarkRangeList;
                        rMark.FillRangeListWithMarks( &aMarkRangeList, false );
                        ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();

                        // check if one of the marked ranges is empty
                        bool bEmpty = false;
                        const size_t nCount = aMarkRangeList.size();
                        for ( size_t i = 0; i < nCount; ++i )
                        {
                            const ScRange aRange( *aMarkRangeList[i] );
                            if ( pDoc->IsBlockEmpty( aRange.aStart.Tab(),
                                    aRange.aStart.Col(), aRange.aStart.Row(),
                                    aRange.aEnd.Col(), aRange.aEnd.Row() ) )
                            {
                                bEmpty = true;
                                break;
                            }
                        }

                        if ( bEmpty )
                        {
                            ScRangeList aRangeList;
                            const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
                            if ( bDataFound )
                            {
                                ScAddress aAddr = aRangeList.back()->aEnd;
                                aAddr.IncRow();
                                const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
                                pViewSh->EnterAutoSum( aRangeList, bSubTotal, aAddr );
                            }
                        }
                        else
                        {
                            const sal_Bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
                            for ( size_t i = 0; i < nCount; ++i )
                            {
                                const ScRange aRange( *aMarkRangeList[i] );
                                const bool bSetCursor = ( i == nCount - 1 ? true : false );
                                const bool bContinue = ( i != 0  ? true : false );
                                if ( !pViewSh->AutoSum( aRange, bSubTotal, bSetCursor, bContinue ) )
                                {
                                    pViewSh->MarkRange( aRange, false, false );
                                    pViewSh->SetCursor( aRange.aEnd.Col(), aRange.aEnd.Row() );
                                    const ScRangeList aRangeList;
                                    ScAddress aAddr = aRange.aEnd;
                                    aAddr.IncRow();
                                    const String aFormula = pViewSh->GetAutoSumFormula(
                                        aRangeList, bSubTotal, aAddr );
                                    SetFuncString( aFormula );
                                    break;
                                }
                            }
                        }
                    }
                    else                                                                        // 
nur in Eingabezeile einfuegen
                    {
                        ScRangeList aRangeList;
                        const sal_Bool bDataFound = pViewSh->GetAutoSumArea( aRangeList );
                        const sal_Bool bSubTotal( UseSubTotal( &aRangeList ) );
                        ScAddress aAddr = pViewSh->GetViewData()->GetCurPos();
                        const String aFormula = pViewSh->GetAutoSumFormula( aRangeList, bSubTotal, 
aAddr );
                        SetFuncString( aFormula );

                        if ( bDataFound && pScMod->IsEditMode() )
                        {
                            ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
                            if ( pHdl )
                            {
                                pHdl->InitRangeFinder( aFormula );

                                //!     SetSelection am InputHandler ???
                                //!     bSelIsRef setzen ???
                                const xub_StrLen nOpen = aFormula.Search('(');
                                const xub_StrLen nLen = aFormula.Len();
                                if ( nOpen != STRING_NOTFOUND && nLen > nOpen )
                                {
                                    sal_uInt8 nAdd(1);
                                    if (bSubTotal)
                                        nAdd = 3;
                                    ESelection aSel(0,nOpen+nAdd,0,nLen-1);
                                    EditView* pTableView = pHdl->GetTableView();
                                    if (pTableView)
                                        pTableView->SetSelection(aSel);
                                    EditView* pTopView = pHdl->GetTopView();
                                    if (pTopView)
                                        pTopView->SetSelection(aSel);
                                }
                            }
                        }
                    }
                }
            }
            break;

        case SID_INPUT_EQUAL:
        {
            aBarGroup.StartEditEngine();
            if ( pScMod->IsEditMode() )                 // nicht, wenn z.B. geschuetzt
            {
                aBarGroup.GainFocus();
                aBarGroup.SetTextString( '=' );

                EditView* pView = aBarGroup.GetEditView();
                if (pView)
                {
                    pView->SetSelection( ESelection(0,1, 0,1) );
                    pScMod->InputChanged(pView);
                    SetOkCancelMode();
                    pView->SetEditEngineUpdateMode(sal_True);
                }
            }
            break;
        }
    }
}

void ScInputWindow::Resize()
{
    ToolBox::Resize();
    


    long nWidth = GetSizePixel().Width();
    long nLeft  = aBarGroup.GetPosPixel().X();
    Size aSize  = aBarGroup.GetSizePixel();

    printf("resize ScInputWindow\n");
    aSize.Width() = Max( ((long)(nWidth - nLeft - 10)), (long)0 );
    aSize.Height()= TBX_WINDOW_HEIGHT;
    
    
    aBarGroup.SetSizePixel( aSize );
    aBarGroup.Invalidate();

    

    aBarGroup.Resize();
}

void ScInputWindow::SetFuncString( const String& rString, sal_Bool bDoEdit )
{
    //! new method at ScModule to query if function autopilot is open
    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );
    aBarGroup.StartEditEngine();

    ScModule* pScMod = SC_MOD();
    if ( pScMod->IsEditMode() )
    {
        if ( bDoEdit )
            aBarGroup.GainFocus();
        aBarGroup.SetTextString( rString );
        EditView* pView = aBarGroup.GetEditView();
        if (pView)
        {
            xub_StrLen nLen = rString.Len();

            if ( nLen > 0 )
            {
                nLen--;
                pView->SetSelection( ESelection( 0, nLen, 0, nLen ) );
            }

            pScMod->InputChanged(pView);
            if ( bDoEdit )
                SetOkCancelMode();                      // nicht, wenn gleich hinterher Enter/Cancel

            pView->SetEditEngineUpdateMode(sal_True);
        }
    }
}

void ScInputWindow::SetPosString( const String& rStr )
{
    aWndPos.SetPos( rStr );
}

void ScInputWindow::SetTextString( const String& rString )
{
    int i = rString.Len();
    if (rString.Len() <= 32767)
    {
        aBarGroup.SetTextString(rString);
//        printf("%d ScInputWnd:SetTextString(),  if \n",i);
    }
    else
    {
//        printf("%d ScInputWnd:SetTextString(),  else \n",i);
        String aNew = rString;
        aNew.Erase(32767);
        aBarGroup.SetTextString(aNew);
    }
}

void ScInputWindow::SetOkCancelMode()
{
    //! new method at ScModule to query if function autopilot is open
    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );

    ScModule* pScMod = SC_MOD();
    SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
    if (!bIsOkCancelMode)
    {
        RemoveItem( 3 ); // SID_INPUT_SUM und SID_INPUT_EQUAL entfernen
        RemoveItem( 3 );
        InsertItem( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ), 0, 3 );
        InsertItem( SID_INPUT_OK,         IMAGE( SID_INPUT_OK ),         0, 4 );
        SetItemText     ( SID_INPUT_CANCEL, aTextCancel );
        SetHelpId       ( SID_INPUT_CANCEL, HID_INSWIN_CANCEL );
        SetItemText     ( SID_INPUT_OK,         aTextOk );
        SetHelpId       ( SID_INPUT_OK,         HID_INSWIN_OK );
        bIsOkCancelMode = sal_True;
    }
}

void ScInputWindow::SetSumAssignMode()
{
    //! new method at ScModule to query if function autopilot is open
    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    EnableButtons( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) );

    ScModule* pScMod = SC_MOD();
    SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
    if (bIsOkCancelMode)
    {
        // SID_INPUT_CANCEL, und SID_INPUT_OK entfernen
        RemoveItem( 3 );
        RemoveItem( 3 );
        InsertItem( SID_INPUT_SUM,       IMAGE( SID_INPUT_SUM ),         0, 3 );
        InsertItem( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ),   0, 4 );
        SetItemText     ( SID_INPUT_SUM,   aTextSum );
        SetHelpId       ( SID_INPUT_SUM,   HID_INSWIN_SUMME );
        SetItemText     ( SID_INPUT_EQUAL, aTextEqual );
        SetHelpId       ( SID_INPUT_EQUAL, HID_INSWIN_FUNC );
        bIsOkCancelMode = false;

        SetFormulaMode(false);          // kein editieren -> keine Formel
    }
}

void ScInputWindow::SetFormulaMode( sal_Bool bSet )
{
    aWndPos.SetFormulaMode(bSet);
    aBarGroup.SetFormulaMode(bSet);
}

void ScInputWindow::SetText( const String& rString )
{
    ToolBox::SetText(rString);
}

String ScInputWindow::GetText() const
{
    return ToolBox::GetText();
}

sal_Bool ScInputWindow::IsInputActive()
{
    return aBarGroup.IsInputActive();
}

EditView* ScInputWindow::GetEditView()
{
    return aBarGroup.GetEditView();
}

void ScInputWindow::MakeDialogEditView()
{
    aBarGroup.MakeDialogEditView();
}

void ScInputWindow::StopEditEngine( sal_Bool bAll )
{
//    aTextWindow.StopEditEngine( bAll );
}

void ScInputWindow::TextGrabFocus()
{
    aBarGroup.GainFocus();
}

void ScInputWindow::TextInvalidate()
{
    aBarGroup.Invalidate();
}

void ScInputWindow::SwitchToTextWin()
{
    // used for shift-ctrl-F2

    aBarGroup.StartEditEngine();
    if ( SC_MOD()->IsEditMode() )
    {
        aBarGroup.GainFocus();
        EditView* pView = aBarGroup.GetEditView();
        if (pView)
        {
            xub_StrLen nLen = pView->GetEditEngine()->GetTextLen(0);
            ESelection aSel( 0, nLen, 0, nLen );
            pView->SetSelection( aSel );                                // set cursor to end of text
        }
    }
}

void ScInputWindow::PosGrabFocus()
{
    aWndPos.GrabFocus();
}

void ScInputWindow::EnableButtons( sal_Bool bEnable )
{
    //  when enabling buttons, always also enable the input window itself
    if ( bEnable && !IsEnabled() )
        Enable();

    EnableItem( SID_INPUT_FUNCTION,                                                                 
      bEnable );
    EnableItem( bIsOkCancelMode ? SID_INPUT_CANCEL : SID_INPUT_SUM,   bEnable );
    EnableItem( bIsOkCancelMode ? SID_INPUT_OK     : SID_INPUT_EQUAL, bEnable );
//      Invalidate();
}

void ScInputWindow::StateChanged( StateChangedType nType )
{
    ToolBox::StateChanged( nType );

    if ( nType == STATE_CHANGE_INITSHOW ) Resize();
}

void ScInputWindow::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        //      update item images
        ScModule*                pScMod  = SC_MOD();
        SfxImageManager* pImgMgr = SfxImageManager::GetImageManager( pScMod );
        // IMAGE macro uses pScMod, pImgMg

        SetItemImage( SID_INPUT_FUNCTION, IMAGE( SID_INPUT_FUNCTION ) );
        if ( bIsOkCancelMode )
        {
            SetItemImage( SID_INPUT_CANCEL, IMAGE( SID_INPUT_CANCEL ) );
            SetItemImage( SID_INPUT_OK,     IMAGE( SID_INPUT_OK ) );
        }
        else
        {
            SetItemImage( SID_INPUT_SUM,   IMAGE( SID_INPUT_SUM ) );
            SetItemImage( SID_INPUT_EQUAL, IMAGE( SID_INPUT_EQUAL ) );
        }
    }

    ToolBox::DataChanged( rDCEvt );
}

//========================================================================
//                  ScInputBarGroup
//========================================================================

ScInputBarGroup::ScInputBarGroup(Window* pParent)
    :   Window          ( pParent, WinBits(WB_HIDE) ),
        aTextWindow      ( this ),
        maScrollBar     ( this,  WB_VERT | WB_DRAG ),
        aButton         ( this, ScResId( 1 )),
        bIsMultiLine    ( false )
{

      aTextWindow.Show();
      aTextWindow.SetQuickHelpText( ScResId( SCSTR_QHELP_INPUTWND ) );
      aTextWindow.SetHelpId             ( HID_INSWIN_INPUT );
      aButton.SetClickHdl       ( LINK( this, ScInputBarGroup, ClickHdl ) );
      aButton.Show();
      aButton.Enable();
      printf("Ctor inputbargroup\n");
}

ScInputBarGroup::~ScInputBarGroup()
{

}
void ScInputBarGroup::SetTextString( const String& rString )
{
    aTextWindow.SetTextString(rString);
}

void ScInputBarGroup::Resize()
{
    long nWidth = GetSizePixel().Width();
    long nLeft  = aTextWindow.GetPosPixel().X();
    Size aSize  = aTextWindow.GetSizePixel();
    aSize.Width() = Max( ((long)(nWidth - nLeft - 40)), (long)0 );
    aSize.Height()=TBX_WINDOW_HEIGHT;
    aTextWindow.SetSizePixel( aSize );
    aTextWindow.Invalidate();
    aButton.SetPosSizePixel(nLeft+aSize.Width(),0,15,22);
    aTextWindow.Resize();
    printf("resize inputbar group\n");
}

void ScInputBarGroup::GainFocus()
{
    aTextWindow.GrabFocus();
}


void ScInputBarGroup::StartEditEngine()
{
    aTextWindow.StartEditEngine();
}

void ScInputBarGroup::MakeDialogEditView()
{
    aTextWindow.MakeDialogEditView();
}


EditView* ScInputBarGroup::GetEditView()
{
    return aTextWindow.GetEditView();
}

bool ScInputBarGroup::IsInputActive()
{
    return aTextWindow.IsInputActive();
}

void ScInputBarGroup::SetFormulaMode(bool bSet)
{
    aTextWindow.SetFormulaMode(bSet);
}

IMPL_LINK( ScInputBarGroup, ClickHdl, PushButton*, pBtn )
{

if(!bIsMultiLine)
{
    bIsMultiLine=true;
    long nWidth = GetSizePixel().Width();
    long nLeft  = aTextWindow.GetPosPixel().X();
    Size aSize  = aTextWindow.GetSizePixel();
    aSize.Width() = Max( ((long)(nWidth - nLeft - 40)), (long)0 );
    aSize.Height()=5*TBX_WINDOW_HEIGHT;
    SetSizePixel(Size(nWidth,5*TBX_WINDOW_HEIGHT));
    aTextWindow.SetSizePixel( aSize );
    aTextWindow.Invalidate();
    printf("pressed\n");
}
else 
{
    bIsMultiLine=false;
    Resize();
    printf("pressed again\n");
}
    

return 0;
}

//========================================================================
//                                                      Multi Textbar
//========================================================================

ScMultibar::ScMultibar( Window* pParent )
    :   Window           ( pParent, WinBits(WB_HIDE | WB_BORDER) ),
        DragSourceHelper( this ),
        pEditEngine      ( NULL ),
        pEditView        ( NULL ),
        bIsInsertMode( sal_True ),
        bFormulaMode ( false ),
        bInputMode   ( false )
{
    EnableRTL( false );         // EditEngine can't be used with VCL EnableRTL

    bIsRTL = GetSettings().GetLayoutRTL();

    //  always use application font, so a font with cjk chars can be installed
    Font aAppFont = GetFont();
    aTextFont = aAppFont;
    aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) );  // AppFont ist in Pixeln

    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

    Color aBgColor= rStyleSettings.GetWindowColor();
    Color aTxtColor= rStyleSettings.GetWindowTextColor();

    aTextFont.SetTransparent ( sal_True );
    aTextFont.SetFillColor   ( aBgColor );
    //aTextFont.SetColor                 ( COL_FIELDTEXT );
    aTextFont.SetColor           (aTxtColor);
    aTextFont.SetWeight          ( WEIGHT_NORMAL );

    Size aSize(1,TBX_WINDOW_HEIGHT);
    Size aMinEditSize( Edit::GetMinimumEditSize() );
    if( aMinEditSize.Height() > aSize.Height() )
        aSize.Height() = aMinEditSize.Height();
    SetSizePixel                ( aSize );
    SetBackground               ( aBgColor );
    SetLineColor                ( COL_BLACK );
    SetMapMode              ( MAP_TWIP );
    SetPointer              ( POINTER_TEXT );
    printf("Ctor scmultibar\n");
}

ScMultibar::~ScMultibar()
{
    while (!maAccTextDatas.empty()) {
        maAccTextDatas.back()->Dispose();
    }
    delete pEditView;
    delete pEditEngine;
}

int ScMultibar::GetLineCount()
{
   if(pEditView)
    {
       return pEditEngine->GetLineCount(0);
    }
}

void ScMultibar::Paint( const Rectangle& rRec )
{
    // We always use edit engine to draw text at all times.
    if (!pEditEngine)
        InitEditEngine(SfxObjectShell::Current());

    if (pEditView)
    {
        pEditView->Paint(rRec);
    }
}

void ScMultibar::Resize()
{
    if (pEditView)
    {
        Size aSize = GetOutputSizePixel();
        Size bSize = LogicToPixel(Size(0,pEditEngine->GetLineHeight(0,0)));
        int nDiff=(aSize.Height()-bSize.Height())/2;
        Point aPos(TEXT_STARTPOS,nDiff*aSize.Height()/aSize.Height());
        Point aPos2(aSize.Width()-5,(aSize.Height()-nDiff)*aSize.Height()/aSize.Height());
        pEditView->SetOutputArea(
            PixelToLogic(Rectangle(aPos, aPos2)));
    }
    printf("resize scMultiBar\n");
}

void ScMultibar::MouseMove( const MouseEvent& rMEvt )
{
    if (pEditView)
        pEditView->MouseMove( rMEvt );
}

void ScMultibar::MouseButtonDown( const MouseEvent& rMEvt )
{
    if (!HasFocus())
    {
        StartEditEngine();
        if ( SC_MOD()->IsEditMode() )
            GrabFocus();
    }

    if (pEditView)
    {
        pEditView->SetEditEngineUpdateMode( sal_True );
        pEditView->MouseButtonDown( rMEvt );
    }
}

void ScMultibar::MouseButtonUp( const MouseEvent& rMEvt )
{
    if (pEditView)
        if (pEditView->MouseButtonUp( rMEvt ))
        {
            if ( rMEvt.IsMiddle() &&
                     GetSettings().GetMouseSettings().GetMiddleButtonAction() == 
MOUSE_MIDDLE_PASTESELECTION )
            {
                //      EditView may have pasted from selection
                SC_MOD()->InputChanged( pEditView );
            }
            else
                SC_MOD()->InputSelection( pEditView );
        }
}

void ScMultibar::Command( const CommandEvent& rCEvt )
{
    bInputMode = sal_True;
    sal_uInt16 nCommand = rCEvt.GetCommand();
    if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ )
    {
        ScModule* pScMod = SC_MOD();
        ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell();

        // don't modify the font defaults here - the right defaults are
        // already set in StartEditEngine when the EditEngine is created

        // verhindern, dass die EditView beim View-Umschalten wegkommt
        pScMod->SetInEditCommand( true );
        pEditView->Command( rCEvt );
        pScMod->SetInEditCommand( false );

        //      COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
        //      darum in dem Fall kein InputChanged
        //!     erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten

        if ( nCommand == COMMAND_STARTDRAG )
        {
            //  ist auf eine andere View gedraggt worden?
            ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell();
            if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL )
            {
                ScViewData* pViewData = pStartViewSh->GetViewData();
                ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh );
                if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) )
                {
                    pHdl->CancelHandler();
                    pViewData->GetView()->ShowCursor();         // fehlt bei KillEditView, weil 
nicht aktiv
                }
            }
        }
        else if ( nCommand == COMMAND_CURSORPOS )
        {
            //  don't call InputChanged for COMMAND_CURSORPOS
        }
        else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE )
        {
            // #i55929# Font and font size state depends on input language if nothing is selected,
            // so the slots have to be invalidated when the input language is changed.

            SfxViewFrame* pViewFrm = SfxViewFrame::Current();
            if (pViewFrm)
            {
                SfxBindings& rBindings = pViewFrm->GetBindings();
                rBindings.Invalidate( SID_ATTR_CHAR_FONT );
                rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
            }
        }
        else
            SC_MOD()->InputChanged( pEditView );
    }
    else
        Window::Command(rCEvt);         //      sonst soll sich die Basisklasse drum kuemmern...

    bInputMode = false;
}

void ScMultibar::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
{
    if ( pEditView )
    {
        CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
        pEditView->Command( aDragEvent );

        //      handling of d&d to different view (CancelHandler) can't be done here,
        //      because the call returns before d&d is complete.
    }
}

void ScMultibar::KeyInput(const KeyEvent& rKEvt)
{
    bInputMode = sal_True;
    if (!SC_MOD()->InputKeyEvent( rKEvt ))
    {
        sal_Bool bUsed = false;
        ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
        if ( pViewSh )
            bUsed = pViewSh->SfxKeyInput(rKEvt);        // nur Acceleratoren, keine Eingabe
        if (!bUsed)
            Window::KeyInput( rKEvt );
    }
    bInputMode = false;
}

void ScMultibar::GetFocus()
{
    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh )
        pViewSh->SetFormShellAtTop( false );     // focus in input line -> FormShell no longer on 
top
}

void ScMultibar::LoseFocus()
{
}

String ScMultibar::GetText() const
{
    //  ueberladen, um per Testtool an den Text heranzukommen
    if ( pEditEngine )
        return pEditEngine->GetText();
    else
        return GetTextString();
}

void ScMultibar::SetFormulaMode( sal_Bool bSet )
{
    if ( bSet != bFormulaMode )
    {
        bFormulaMode = bSet;
        UpdateAutoCorrFlag();
    }
}

void ScMultibar::UpdateAutoCorrFlag()
{
    if ( pEditEngine )
    {
        sal_uLong nControl = pEditEngine->GetControlWord();
        sal_uLong nOld = nControl;
        if ( bFormulaMode )
            nControl &= ~EE_CNTRL_AUTOCORRECT;          // keine Autokorrektur in Formeln
        else
            nControl |= EE_CNTRL_AUTOCORRECT;           // sonst schon
        if ( nControl != nOld )
            pEditEngine->SetControlWord( nControl );
    }
}

void lcl_ExtendEditFontAttribs( SfxItemSet& rSet )
{
    const SfxPoolItem& rFontItem = rSet.Get( EE_CHAR_FONTINFO );
    rSet.Put( rFontItem, EE_CHAR_FONTINFO_CJK );
    rSet.Put( rFontItem, EE_CHAR_FONTINFO_CTL );
    const SfxPoolItem& rHeightItem = rSet.Get( EE_CHAR_FONTHEIGHT );
    rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CJK );
    rSet.Put( rHeightItem, EE_CHAR_FONTHEIGHT_CTL );
    const SfxPoolItem& rWeightItem = rSet.Get( EE_CHAR_WEIGHT );
    rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
    rSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
    const SfxPoolItem& rItalicItem = rSet.Get( EE_CHAR_ITALIC );
    rSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
    rSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
    const SfxPoolItem& rLangItem = rSet.Get( EE_CHAR_LANGUAGE );
    rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
    rSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
}

void lcl_ModifyRTLDefaults( SfxItemSet& rSet )
{
    rSet.Put( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );

    //  always using rtl writing direction would break formulas
    //rSet.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );

    //  PaperSize width is limited to USHRT_MAX in RTL mode (because of EditEngine's
    //  sal_uInt16 values in EditLine), so the text may be wrapped and line spacing must be
    //  increased to not see the beginning of the next line.
    SvxLineSpacingItem aItem( SVX_LINESPACE_TWO_LINES, EE_PARA_SBL );
    aItem.SetPropLineSpace( 200 );
    rSet.Put( aItem );
}

void lcl_ModifyRTLVisArea( EditView* pEditView )
{
    Rectangle aVisArea = pEditView->GetVisArea();
    Size aPaper = pEditView->GetEditEngine()->GetPaperSize();
    long nDiff = aPaper.Width() - aVisArea.Right();
    aVisArea.Left()  += nDiff;
    aVisArea.Right() += nDiff;
    pEditView->SetVisArea(aVisArea);
}

void ScMultibar::InitEditEngine(SfxObjectShell* pObjSh)
{
    ScFieldEditEngine* pNew;
    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh )
    {
        const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
        pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
    }
    else
        pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True );
    pNew->SetExecuteURL( false );
    pEditEngine = pNew;

    Size barSize=GetOutputSizePixel();

    long barHeight=barSize.Height();
    long textHeight=LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
    long nDiff =  barHeight - textHeight;

    barSize.Height()=nDiff+barHeight;
    barSize.Width() -= 2*TEXT_STARTPOS-4;
    pEditEngine->SetUpdateMode( false );
    pEditEngine->SetPaperSize( PixelToLogic(Size(barSize.Width(),10000)) );
    pEditEngine->SetWordDelimiters(
                    ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );

    UpdateAutoCorrFlag();

    {
        SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
        pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
        lcl_ExtendEditFontAttribs( *pSet );
        // turn off script spacing to match DrawText output
        pSet->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
        if ( bIsRTL )
            lcl_ModifyRTLDefaults( *pSet );
        pEditEngine->SetDefaults( pSet );
    }

    //  Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
    //  die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.

    sal_Bool bFilled = false;
    ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
    if ( pHdl )                 //!     Testen, ob's der richtige InputHdl ist?
        bFilled = pHdl->GetTextAndFields( *pEditEngine );

    pEditEngine->SetUpdateMode( sal_True );

    //  aString ist die Wahrheit...
    if ( bFilled && pEditEngine->GetText() == aString )
        Invalidate();                                           // Repaint fuer (hinterlegte) Felder
    else
        pEditEngine->SetText(aString);          // dann wenigstens den richtigen Text

    pEditView = new EditView( pEditEngine, this );
    pEditView->SetInsertMode(bIsInsertMode);

    // Text aus Clipboard wird als ASCII einzeilig uebernommen
    sal_uLong n = pEditView->GetControlWord();
    pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE     );

    pEditEngine->InsertView( pEditView, EE_APPEND );

    Resize();

    if ( bIsRTL )
        lcl_ModifyRTLVisArea( pEditView );

    pEditEngine->SetModifyHdl(LINK(this, ScMultibar, NotifyHdl));

    if (!maAccTextDatas.empty())
        maAccTextDatas.back()->StartEdit();

    //  as long as EditEngine and DrawText sometimes differ for CTL text,
    //  repaint now to have the EditEngine's version visible
//        SfxObjectShell* pObjSh = SfxObjectShell::Current();
    if ( pObjSh && pObjSh->ISA(ScDocShell) )
    {
        ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();        // any document
        sal_uInt8 nScript = pDoc->GetStringScriptType( aString );
        if ( nScript & SCRIPTTYPE_COMPLEX )
            Invalidate();
    }
}

void ScMultibar::StartEditEngine()
{
    //  Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren

    SfxObjectShell* pObjSh = SfxObjectShell::Current();
    if ( pObjSh && pObjSh->IsInModalMode() )
        return;

    if ( !pEditView || !pEditEngine )
    {
        InitEditEngine(pObjSh);
    }

    SC_MOD()->SetInputMode( SC_INPUT_TOP );

    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    if (pViewFrm)
        pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
}

IMPL_LINK(ScMultibar, NotifyHdl, EENotify*, EMPTYARG)
{
    if (pEditView && !bInputMode)
    {
        ScInputHandler* pHdl = SC_MOD()->GetInputHdl();

        //      Use the InputHandler's InOwnChange flag to prevent calling InputChanged
        //      while an InputHandler method is modifying the EditEngine content

        if ( pHdl && !pHdl->IsInOwnChange() )
            pHdl->InputChanged( pEditView, sal_True );  // #i20282# InputChanged must know if 
called from modify handler
    }

    return 0;
}

void ScMultibar::StopEditEngine( sal_Bool bAll )
{
    printf("stopping editEngine\n");
#if 0 // Make this a no-op for now.
    if (pEditView)
    {
        if (!maAccTextDatas.empty())
            maAccTextDatas.back()->EndEdit();

        ScModule* pScMod = SC_MOD();

        if (!bAll)
            pScMod->InputSelection( pEditView );
        aString = pEditEngine->GetText();
        bIsInsertMode = pEditView->IsInsertMode();
        sal_Bool bSelection = pEditView->HasSelection();
        pEditEngine->SetModifyHdl(Link());
        DELETEZ(pEditView);
        DELETEZ(pEditEngine);

        if ( pScMod->IsEditMode() && !bAll )
            pScMod->SetInputMode(SC_INPUT_TABLE);

        SfxViewFrame* pViewFrm = SfxViewFrame::Current();
        if (pViewFrm)
            pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );

        if (bSelection)
            Invalidate();                       // damit Selektion nicht stehenbleibt
    }
#endif
}

void ScMultibar::SetTextString( const String& rNewString )
{
    if ( rNewString != aString )
    {
        bInputMode = sal_True;

        //      Position der Aenderung suchen, nur Rest painten

        if (!pEditEngine)
        {
            sal_Bool bPaintAll;
            if ( bIsRTL )
                bPaintAll = sal_True;
            else
            {
                //      test if CTL script type is involved
                sal_uInt8 nOldScript = 0;
                sal_uInt8 nNewScript = 0;
                SfxObjectShell* pObjSh = SfxObjectShell::Current();
                if ( pObjSh && pObjSh->ISA(ScDocShell) )
                {
                    //  any document can be used (used only for its break iterator)
                    ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
                    nOldScript = pDoc->GetStringScriptType( aString );
                    nNewScript = pDoc->GetStringScriptType( rNewString );
                }
                bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & 
SCRIPTTYPE_COMPLEX );
            }

            if ( bPaintAll )
            {
                // if CTL is involved, the whole text has to be redrawn
                Invalidate();
            }
            else
            {
                long nTextSize = 0;
                xub_StrLen nDifPos;
                if (rNewString.Len() > aString.Len())
                    nDifPos = rNewString.Match(aString);
                else
                    nDifPos = aString.Match(rNewString);

                long nSize1 = GetTextWidth(aString);
                long nSize2 = GetTextWidth(rNewString);
                if ( nSize1>0 && nSize2>0 )
                    nTextSize = Max( nSize1, nSize2 );
                else
                    nTextSize = GetOutputSize().Width();                // Ueberlauf

                if (nDifPos == STRING_MATCH)
                    nDifPos = 0;

                                                // -1 wegen Rundung und "A"
                Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0));
                long nStartPos = aLogicStart.X();
                long nInvPos = nStartPos;
                if (nDifPos)
                    nInvPos += GetTextWidth(aString,0,nDifPos);

                sal_uInt16 nFlags = 0;
                if ( nDifPos == aString.Len() )                 // only new characters appended
                    nFlags = INVALIDATE_NOERASE;                // then background is already clear

                Invalidate( Rectangle( nInvPos, 0,
                                        nStartPos+nTextSize, GetOutputSize().Height()-1 ),
                            nFlags );
            }
        }
        else
        {
            pEditEngine->SetText(rNewString);
        }

        aString = rNewString;

        if (!maAccTextDatas.empty())
            maAccTextDatas.back()->TextChanged();

        bInputMode = false;
    }
}

const String& ScMultibar::GetTextString() const
{
    return aString;
}

sal_Bool ScMultibar::IsInputActive()
{
    return HasFocus();
}

EditView* ScMultibar::GetEditView()
{
    return pEditView;
}

void ScMultibar::MakeDialogEditView()
{
    if ( pEditView ) return;

    ScFieldEditEngine* pNew;
    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh )
    {
        const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
        pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
    }
    else
        pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True );
    pNew->SetExecuteURL( false );
    pEditEngine = pNew;

    pEditEngine->SetUpdateMode( false );
    pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' );
    pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );

    SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
    pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
    lcl_ExtendEditFontAttribs( *pSet );
    if ( bIsRTL )
        lcl_ModifyRTLDefaults( *pSet );
    pEditEngine->SetDefaults( pSet );
    pEditEngine->SetUpdateMode( sal_True );

    pEditView   = new EditView( pEditEngine, this );
    pEditEngine->InsertView( pEditView, EE_APPEND );

    Resize();

    if ( bIsRTL )
        lcl_ModifyRTLVisArea( pEditView );

    if (!maAccTextDatas.empty())
        maAccTextDatas.back()->StartEdit();
}

void ScMultibar::ImplInitSettings()
{
    bIsRTL = GetSettings().GetLayoutRTL();

    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

    Color aBgColor= rStyleSettings.GetWindowColor();
    Color aTxtColor= rStyleSettings.GetWindowTextColor();

    aTextFont.SetFillColor   ( aBgColor );
    aTextFont.SetColor           (aTxtColor);
    SetBackground                       ( aBgColor );
    Invalidate();
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 
ScMultibar::CreateAccessible()
{
    return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this,
        rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))),
        rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine);
}

void ScMultibar::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
    OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == 
maAccTextDatas.end(),
        "ScMultibar::InsertAccessibleTextData - passed object already registered" );
    maAccTextDatas.push_back( &rTextData );
}

void ScMultibar::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
    AccTextDataVector::iterator aEnd = maAccTextDatas.end();
    AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData );
    OSL_ENSURE( aIt != aEnd, "ScMultibar::RemoveAccessibleTextData - passed object not registered" 
);
    if( aIt != aEnd )
        maAccTextDatas.erase( aIt );
}

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

void ScMultibar::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        ImplInitSettings();
        Invalidate();
    }
    else
        Window::DataChanged( rDCEvt );
}

//========================================================================
//                                                      Eingabefenster
//========================================================================

ScTextWnd::ScTextWnd( Window* pParent )
    :   Window           ( pParent, WinBits(WB_HIDE | WB_BORDER) ),
        DragSourceHelper( this ),
        pEditEngine      ( NULL ),
        pEditView        ( NULL ),
        bIsInsertMode( sal_True ),
        bFormulaMode ( false ),
        bInputMode   ( false )
{
    EnableRTL( false );         // EditEngine can't be used with VCL EnableRTL

    bIsRTL = GetSettings().GetLayoutRTL();

    //  always use application font, so a font with cjk chars can be installed
    Font aAppFont = GetFont();
    aTextFont = aAppFont;
    aTextFont.SetSize( PixelToLogic( aAppFont.GetSize(), MAP_TWIP ) );  // AppFont ist in Pixeln

    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

    Color aBgColor= rStyleSettings.GetWindowColor();
    Color aTxtColor= rStyleSettings.GetWindowTextColor();

    aTextFont.SetTransparent ( sal_True );
    aTextFont.SetFillColor   ( aBgColor );
    //aTextFont.SetColor                 ( COL_FIELDTEXT );
    aTextFont.SetColor           (aTxtColor);
    aTextFont.SetWeight          ( WEIGHT_NORMAL );

    Size aSize(1,TBX_WINDOW_HEIGHT);
    Size aMinEditSize( Edit::GetMinimumEditSize() );
    if( aMinEditSize.Height() > aSize.Height() )
        aSize.Height() = aMinEditSize.Height();
    SetSizePixel                ( aSize );
    SetBackground               ( aBgColor );
    SetLineColor                ( COL_BLACK );
    SetMapMode              ( MAP_TWIP );
    SetPointer              ( POINTER_TEXT );
}

ScTextWnd::~ScTextWnd()
{
    while (!maAccTextDatas.empty()) {
        maAccTextDatas.back()->Dispose();
    }
    delete pEditView;
    delete pEditEngine;
}

void ScTextWnd::Paint( const Rectangle& rRec )
{
    if (pEditView)
        pEditView->Paint( rRec );
    else
    {
        SetFont( aTextFont );

        long nDiff =  GetOutputSizePixel().Height()
                    - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();
//              if (nDiff<2) nDiff=2;           // mind. 1 Pixel

        long nStartPos = TEXT_STARTPOS;
        if ( bIsRTL )
        {
            //  right-align
            nStartPos += GetOutputSizePixel().Width() - 2*TEXT_STARTPOS -
                        LogicToPixel( Size( GetTextWidth( aString ), 0 ) ).Width();

            //  LayoutMode isn't changed as long as ModifyRTLDefaults doesn't include 
SvxFrameDirectionItem
        }

        DrawText( PixelToLogic( Point( nStartPos, nDiff/2 ) ), aString );
    }
}

void ScTextWnd::Resize()
{
    if (pEditView)
    {
        Size aSize = GetOutputSizePixel();
        long nDiff =  aSize.Height()
                    - LogicToPixel( Size( 0, GetTextHeight() ) ).Height();

        aSize.Width() -= 2 * TEXT_STARTPOS - 1;

        pEditView->SetOutputArea(
            PixelToLogic( Rectangle( Point( TEXT_STARTPOS, (nDiff > 0) ? nDiff/2 : 1 ),
                                     aSize ) ) );
    }
}

void ScTextWnd::MouseMove( const MouseEvent& rMEvt )
{
    if (pEditView)
        pEditView->MouseMove( rMEvt );
}

void ScTextWnd::MouseButtonDown( const MouseEvent& rMEvt )
{
    if (!HasFocus())
    {
        StartEditEngine();
        if ( SC_MOD()->IsEditMode() )
            GrabFocus();
    }

    if (pEditView)
    {
        pEditView->SetEditEngineUpdateMode( sal_True );
        pEditView->MouseButtonDown( rMEvt );
    }
}

void ScTextWnd::MouseButtonUp( const MouseEvent& rMEvt )
{
    if (pEditView)
        if (pEditView->MouseButtonUp( rMEvt ))
        {
            if ( rMEvt.IsMiddle() &&
                     GetSettings().GetMouseSettings().GetMiddleButtonAction() == 
MOUSE_MIDDLE_PASTESELECTION )
            {
                //      EditView may have pasted from selection
                SC_MOD()->InputChanged( pEditView );
            }
            else
                SC_MOD()->InputSelection( pEditView );
        }
}

void ScTextWnd::Command( const CommandEvent& rCEvt )
{
    bInputMode = sal_True;
    sal_uInt16 nCommand = rCEvt.GetCommand();
    if ( pEditView /* && ( nCommand == COMMAND_STARTDRAG || nCommand == COMMAND_VOICE ) */ )
    {
        ScModule* pScMod = SC_MOD();
        ScTabViewShell* pStartViewSh = ScTabViewShell::GetActiveViewShell();

        // don't modify the font defaults here - the right defaults are
        // already set in StartEditEngine when the EditEngine is created

        // verhindern, dass die EditView beim View-Umschalten wegkommt
        pScMod->SetInEditCommand( true );
        pEditView->Command( rCEvt );
        pScMod->SetInEditCommand( false );

        //      COMMAND_STARTDRAG heiss noch lange nicht, dass der Inhalt geaendert wurde
        //      darum in dem Fall kein InputChanged
        //!     erkennen, ob mit Move gedraggt wurde, oder Drag&Move irgendwie verbieten

        if ( nCommand == COMMAND_STARTDRAG )
        {
            //  ist auf eine andere View gedraggt worden?
            ScTabViewShell* pEndViewSh = ScTabViewShell::GetActiveViewShell();
            if ( pEndViewSh != pStartViewSh && pStartViewSh != NULL )
            {
                ScViewData* pViewData = pStartViewSh->GetViewData();
                ScInputHandler* pHdl = pScMod->GetInputHdl( pStartViewSh );
                if ( pHdl && pViewData->HasEditView( pViewData->GetActivePart() ) )
                {
                    pHdl->CancelHandler();
                    pViewData->GetView()->ShowCursor();         // fehlt bei KillEditView, weil 
nicht aktiv
                }
            }
        }
        else if ( nCommand == COMMAND_CURSORPOS )
        {
            //  don't call InputChanged for COMMAND_CURSORPOS
        }
        else if ( nCommand == COMMAND_INPUTLANGUAGECHANGE )
        {
            // #i55929# Font and font size state depends on input language if nothing is selected,
            // so the slots have to be invalidated when the input language is changed.

            SfxViewFrame* pViewFrm = SfxViewFrame::Current();
            if (pViewFrm)
            {
                SfxBindings& rBindings = pViewFrm->GetBindings();
                rBindings.Invalidate( SID_ATTR_CHAR_FONT );
                rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
            }
        }
        else
            SC_MOD()->InputChanged( pEditView );
    }
    else
        Window::Command(rCEvt);         //      sonst soll sich die Basisklasse drum kuemmern...

    bInputMode = false;
}

void ScTextWnd::StartDrag( sal_Int8 /* nAction */, const Point& rPosPixel )
{
    if ( pEditView )
    {
        CommandEvent aDragEvent( rPosPixel, COMMAND_STARTDRAG, sal_True );
        pEditView->Command( aDragEvent );

        //      handling of d&d to different view (CancelHandler) can't be done here,
        //      because the call returns before d&d is complete.
    }
}

void ScTextWnd::KeyInput(const KeyEvent& rKEvt)
{
    bInputMode = sal_True;
    if (!SC_MOD()->InputKeyEvent( rKEvt ))
    {
        sal_Bool bUsed = false;
        ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
        if ( pViewSh )
            bUsed = pViewSh->SfxKeyInput(rKEvt);        // nur Acceleratoren, keine Eingabe
        if (!bUsed)
            Window::KeyInput( rKEvt );
    }
    bInputMode = false;
}

void ScTextWnd::GetFocus()
{
    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh )
        pViewSh->SetFormShellAtTop( false );     // focus in input line -> FormShell no longer on 
top
}

void ScTextWnd::LoseFocus()
{
}

String ScTextWnd::GetText() const
{
    //  ueberladen, um per Testtool an den Text heranzukommen

    if ( pEditEngine )
        return pEditEngine->GetText();
    else
        return GetTextString();
}

void ScTextWnd::SetFormulaMode( sal_Bool bSet )
{
    if ( bSet != bFormulaMode )
    {
        bFormulaMode = bSet;
        UpdateAutoCorrFlag();
    }
}

void ScTextWnd::UpdateAutoCorrFlag()
{
    if ( pEditEngine )
    {
        sal_uLong nControl = pEditEngine->GetControlWord();
        sal_uLong nOld = nControl;
        if ( bFormulaMode )
            nControl &= ~EE_CNTRL_AUTOCORRECT;          // keine Autokorrektur in Formeln
        else
            nControl |= EE_CNTRL_AUTOCORRECT;           // sonst schon
        if ( nControl != nOld )
            pEditEngine->SetControlWord( nControl );
    }
}



void ScTextWnd::StartEditEngine()
{
    //  Bei "eigener Modalitaet" (Doc-modale Dialoge) nicht aktivieren
    SfxObjectShell* pObjSh = SfxObjectShell::Current();
    if ( pObjSh && pObjSh->IsInModalMode() )
        return;

    if ( !pEditView || !pEditEngine )
    {
        ScFieldEditEngine* pNew;
        ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
        if ( pViewSh )
        {
            const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
            pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
        }
        else
            pNew = new ScFieldEditEngine( EditEngine::CreatePool(),     NULL, sal_True );
        pNew->SetExecuteURL( false );
        pEditEngine = pNew;

        pEditEngine->SetUpdateMode( false );
        pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );
        pEditEngine->SetWordDelimiters(
                        ScEditUtil::ModifyDelimiters( pEditEngine->GetWordDelimiters() ) );

        UpdateAutoCorrFlag();

        {
            SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
            pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
            lcl_ExtendEditFontAttribs( *pSet );
            // turn off script spacing to match DrawText output
            pSet->Put( SvxScriptSpaceItem( false, EE_PARA_ASIANCJKSPACING ) );
            if ( bIsRTL )
                lcl_ModifyRTLDefaults( *pSet );
            pEditEngine->SetDefaults( pSet );
        }

        //      Wenn in der Zelle URL-Felder enthalten sind, muessen die auch in
        //      die Eingabezeile uebernommen werden, weil sonst die Positionen nicht stimmen.

        sal_Bool bFilled = false;
        ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
        if ( pHdl )                     //!     Testen, ob's der richtige InputHdl ist?
            bFilled = pHdl->GetTextAndFields( *pEditEngine );

        pEditEngine->SetUpdateMode( sal_True );

        //      aString ist die Wahrheit...
        if ( bFilled && pEditEngine->GetText() == aString )
            Invalidate();                                               // Repaint fuer 
(hinterlegte) Felder
        else
            pEditEngine->SetText(aString);              // dann wenigstens den richtigen Text

        pEditView = new EditView( pEditEngine, this );
        pEditView->SetInsertMode(bIsInsertMode);

        // Text aus Clipboard wird als ASCII einzeilig uebernommen
        sal_uLong n = pEditView->GetControlWord();
        pEditView->SetControlWord( n | EV_CNTRL_SINGLELINEPASTE );

        pEditEngine->InsertView( pEditView, EE_APPEND );

        Resize();

        if ( bIsRTL )
            lcl_ModifyRTLVisArea( pEditView );

        pEditEngine->SetModifyHdl(LINK(this, ScTextWnd, NotifyHdl));

        if (!maAccTextDatas.empty())
            maAccTextDatas.back()->StartEdit();

        //      as long as EditEngine and DrawText sometimes differ for CTL text,
        //      repaint now to have the EditEngine's version visible
//        SfxObjectShell* pObjSh = SfxObjectShell::Current();
        if ( pObjSh && pObjSh->ISA(ScDocShell) )
        {
            ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();    // any document
            sal_uInt8 nScript = pDoc->GetStringScriptType( aString );
            if ( nScript & SCRIPTTYPE_COMPLEX )
                Invalidate();
        }
    }

    SC_MOD()->SetInputMode( SC_INPUT_TOP );

    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    if (pViewFrm)
        pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );
}

IMPL_LINK(ScTextWnd, NotifyHdl, EENotify*, EMPTYARG)
{
    if (pEditView && !bInputMode)
    {
        ScInputHandler* pHdl = SC_MOD()->GetInputHdl();

        //      Use the InputHandler's InOwnChange flag to prevent calling InputChanged
        //      while an InputHandler method is modifying the EditEngine content

        if ( pHdl && !pHdl->IsInOwnChange() )
            pHdl->InputChanged( pEditView, sal_True );  // #i20282# InputChanged must know if 
called from modify handler
    }

    return 0;
}

void ScTextWnd::StopEditEngine( sal_Bool bAll )
{
    if (pEditView)
    {
        if (!maAccTextDatas.empty())
            maAccTextDatas.back()->EndEdit();

        ScModule* pScMod = SC_MOD();

        if (!bAll)
            pScMod->InputSelection( pEditView );
        aString = pEditEngine->GetText();
        bIsInsertMode = pEditView->IsInsertMode();
        sal_Bool bSelection = pEditView->HasSelection();
        pEditEngine->SetModifyHdl(Link());
        DELETEZ(pEditView);
        DELETEZ(pEditEngine);

        if ( pScMod->IsEditMode() && !bAll )
            pScMod->SetInputMode(SC_INPUT_TABLE);

        SfxViewFrame* pViewFrm = SfxViewFrame::Current();
        if (pViewFrm)
            pViewFrm->GetBindings().Invalidate( SID_ATTR_INSERT );

        if (bSelection)
            Invalidate();                       // damit Selektion nicht stehenbleibt
    }
}

void ScTextWnd::SetTextString( const String& rNewString )
{
    if ( rNewString != aString )
    {
        bInputMode = sal_True;

        //      Position der Aenderung suchen, nur Rest painten

        if (!pEditEngine)
        {
            sal_Bool bPaintAll;
            if ( bIsRTL )
                bPaintAll = sal_True;
            else
            {
                //      test if CTL script type is involved
                sal_uInt8 nOldScript = 0;
                sal_uInt8 nNewScript = 0;
                SfxObjectShell* pObjSh = SfxObjectShell::Current();
                if ( pObjSh && pObjSh->ISA(ScDocShell) )
                {
                    //  any document can be used (used only for its break iterator)
                    ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();
                    nOldScript = pDoc->GetStringScriptType( aString );
                    nNewScript = pDoc->GetStringScriptType( rNewString );
                }
                bPaintAll = ( nOldScript & SCRIPTTYPE_COMPLEX ) || ( nNewScript & 
SCRIPTTYPE_COMPLEX );
            }

            if ( bPaintAll )
            {
                // if CTL is involved, the whole text has to be redrawn
                Invalidate();
            }
            else
            {
                long nTextSize = 0;
                xub_StrLen nDifPos;
                if (rNewString.Len() > aString.Len())
                    nDifPos = rNewString.Match(aString);
                else
                    nDifPos = aString.Match(rNewString);

                long nSize1 = GetTextWidth(aString);
                long nSize2 = GetTextWidth(rNewString);
                if ( nSize1>0 && nSize2>0 )
                    nTextSize = Max( nSize1, nSize2 );
                else
                    nTextSize = GetOutputSize().Width();                // Ueberlauf

                if (nDifPos == STRING_MATCH)
                    nDifPos = 0;

                                                // -1 wegen Rundung und "A"
                Point aLogicStart = PixelToLogic(Point(TEXT_STARTPOS-1,0));
                long nStartPos = aLogicStart.X();
                long nInvPos = nStartPos;
                if (nDifPos)
                    nInvPos += GetTextWidth(aString,0,nDifPos);

                sal_uInt16 nFlags = 0;
                if ( nDifPos == aString.Len() )                 // only new characters appended
                    nFlags = INVALIDATE_NOERASE;                // then background is already clear

                Invalidate( Rectangle( nInvPos, 0,
                                        nStartPos+nTextSize, GetOutputSize().Height()-1 ),
                            nFlags );
            }
        }
        else
        {
            pEditEngine->SetText(rNewString);
        }

        aString = rNewString;

        if (!maAccTextDatas.empty())
            maAccTextDatas.back()->TextChanged();

        bInputMode = false;
    }
}

const String& ScTextWnd::GetTextString() const
{
    return aString;
}

sal_Bool ScTextWnd::IsInputActive()
{
    return HasFocus();
}

EditView* ScTextWnd::GetEditView()
{
    return pEditView;
}

void ScTextWnd::MakeDialogEditView()
{
    if ( pEditView ) return;

    ScFieldEditEngine* pNew;
    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh )
    {
        const ScDocument* pDoc = pViewSh->GetViewData()->GetDocument();
        pNew = new ScFieldEditEngine( pDoc->GetEnginePool(), pDoc->GetEditPool() );
    }
    else
        pNew = new ScFieldEditEngine( EditEngine::CreatePool(), NULL, sal_True );
    pNew->SetExecuteURL( false );
    pEditEngine = pNew;

    pEditEngine->SetUpdateMode( false );
    pEditEngine->SetWordDelimiters( pEditEngine->GetWordDelimiters() += '=' );
    pEditEngine->SetPaperSize( Size( bIsRTL ? USHRT_MAX : THESIZE, 300 ) );

    SfxItemSet* pSet = new SfxItemSet( pEditEngine->GetEmptyItemSet() );
    pEditEngine->SetFontInfoInItemSet( *pSet, aTextFont );
    lcl_ExtendEditFontAttribs( *pSet );
    if ( bIsRTL )
        lcl_ModifyRTLDefaults( *pSet );
    pEditEngine->SetDefaults( pSet );
    pEditEngine->SetUpdateMode( sal_True );

    pEditView   = new EditView( pEditEngine, this );
    pEditEngine->InsertView( pEditView, EE_APPEND );

    Resize();

    if ( bIsRTL )
        lcl_ModifyRTLVisArea( pEditView );

    if (!maAccTextDatas.empty())
        maAccTextDatas.back()->StartEdit();
}

void ScTextWnd::ImplInitSettings()
{
    bIsRTL = GetSettings().GetLayoutRTL();

    const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();

    Color aBgColor= rStyleSettings.GetWindowColor();
    Color aTxtColor= rStyleSettings.GetWindowTextColor();

    aTextFont.SetFillColor   ( aBgColor );
    aTextFont.SetColor           (aTxtColor);
    SetBackground                       ( aBgColor );
    Invalidate();
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > 
ScTextWnd::CreateAccessible()
{
    return new ScAccessibleEditObject(GetAccessibleParentWindow()->GetAccessible(), NULL, this,
        rtl::OUString(String(ScResId(STR_ACC_EDITLINE_NAME))),
        rtl::OUString(String(ScResId(STR_ACC_EDITLINE_DESCR))), EditLine);
}

void ScTextWnd::InsertAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
    OSL_ENSURE( ::std::find( maAccTextDatas.begin(), maAccTextDatas.end(), &rTextData ) == 
maAccTextDatas.end(),
        "ScTextWnd::InsertAccessibleTextData - passed object already registered" );
    maAccTextDatas.push_back( &rTextData );
}

void ScTextWnd::RemoveAccessibleTextData( ScAccessibleEditLineTextData& rTextData )
{
    AccTextDataVector::iterator aEnd = maAccTextDatas.end();
    AccTextDataVector::iterator aIt = ::std::find( maAccTextDatas.begin(), aEnd, &rTextData );
    OSL_ENSURE( aIt != aEnd, "ScTextWnd::RemoveAccessibleTextData - passed object not registered" );
    if( aIt != aEnd )
        maAccTextDatas.erase( aIt );
}

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

void ScTextWnd::DataChanged( const DataChangedEvent& rDCEvt )
{
    if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
         (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    {
        ImplInitSettings();
        Invalidate();
    }
    else
        Window::DataChanged( rDCEvt );
}


//========================================================================
//                                                      Positionsfenster
//========================================================================

ScPosWnd::ScPosWnd( Window* pParent ) :
    ComboBox    ( pParent, WinBits(WB_HIDE | WB_DROPDOWN) ),
    pAccel              ( NULL ),
    nTipVisible ( 0 ),
    bFormulaMode( false )
{
    Size aSize( GetTextWidth( 
String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("GW99999:GW99999")) ),
                GetTextHeight() );
    aSize.Width() += 25;        // ??
    aSize.Height() = CalcWindowSizePixel(11);           // Funktionen: 10 MRU + "andere..."
    SetSizePixel( aSize );

    FillRangeNames();

    StartListening( *SFX_APP() );               // fuer Navigator-Bereichsnamen-Updates
}

ScPosWnd::~ScPosWnd()
{
    EndListening( *SFX_APP() );

    HideTip();

    delete pAccel;
}

void ScPosWnd::SetFormulaMode( sal_Bool bSet )
{
    if ( bSet != bFormulaMode )
    {
        bFormulaMode = bSet;

        if ( bSet )
            FillFunctions();
        else
            FillRangeNames();

        HideTip();
    }
}

void ScPosWnd::SetPos( const String& rPosStr )
{
    if ( aPosStr != rPosStr )
    {
        aPosStr = rPosStr;
        SetText(aPosStr);
    }
}

void ScPosWnd::FillRangeNames()
{
    Clear();

    SfxObjectShell* pObjSh = SfxObjectShell::Current();
    if ( pObjSh && pObjSh->ISA(ScDocShell) )
    {
        ScDocument* pDoc = ((ScDocShell*)pObjSh)->GetDocument();

        //      per Hand sortieren, weil Funktionen nicht sortiert werden:

        ScRangeName* pRangeNames = pDoc->GetRangeName();
        if (!pRangeNames->empty())
        {
            ScRange aDummy;
            std::vector<const ScRangeData*> aSortArray;
            ScRangeName::const_iterator itr = pRangeNames->begin(), itrEnd = pRangeNames->end();
            for (; itr != itrEnd; ++itr)
            {
                if (itr->IsValidReference(aDummy))
                    aSortArray.push_back(&(*itr));
            }

            if (!aSortArray.empty())
            {
#ifndef ICC
                size_t n = aSortArray.size();
                qsort( (void*)&aSortArray[0], n, sizeof(ScRangeData*),
                    &ScRangeData_QsortNameCompare );
#else
                qsort( (void*)&aSortArray[0], n, sizeof(ScRangeData*),
                    ICCQsortNameCompare );
#endif
                for (size_t i = 0; i < n; ++i)
                    InsertEntry(aSortArray[i]->GetName());
            }
        }
    }
    SetText(aPosStr);
}

void ScPosWnd::FillFunctions()
{
    Clear();

    String aFirstName;
    const ScAppOptions& rOpt = SC_MOD()->GetAppOptions();
    sal_uInt16 nMRUCount = rOpt.GetLRUFuncListCount();
    const sal_uInt16* pMRUList = rOpt.GetLRUFuncList();
    if (pMRUList)
    {
        const ScFunctionList* pFuncList = ScGlobal::GetStarCalcFunctionList();
        sal_uLong nListCount = pFuncList->GetCount();
        for (sal_uInt16 i=0; i<nMRUCount; i++)
        {
            sal_uInt16 nId = pMRUList[i];
            for (sal_uLong j=0; j<nListCount; j++)
            {
                const ScFuncDesc* pDesc = pFuncList->GetFunction( j );
                if ( pDesc->nFIndex == nId && pDesc->pFuncName )
                {
                    InsertEntry( *pDesc->pFuncName );
                    if (!aFirstName.Len())
                        aFirstName = *pDesc->pFuncName;
                    break;      // nicht weitersuchen
                }
            }
        }
    }

    //! Eintrag "Andere..." fuer Funktions-Autopilot wieder aufnehmen,
    //! wenn der Funktions-Autopilot mit dem bisher eingegebenen Text arbeiten kann!

//      InsertEntry( ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) );

    SetText(aFirstName);
}

void ScPosWnd::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
    if ( !bFormulaMode )
    {
        //      muss die Liste der Bereichsnamen updgedated werden?

        if ( rHint.ISA(SfxSimpleHint) )
        {
            sal_uLong nHintId = ((SfxSimpleHint&)rHint).GetId();
            if ( nHintId == SC_HINT_AREAS_CHANGED || nHintId == SC_HINT_NAVIGATOR_UPDATEALL)
                FillRangeNames();
        }
        else if ( rHint.ISA(SfxEventHint) )
        {
            sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId();
            if ( nEventId == SFX_EVENT_ACTIVATEDOC )
                FillRangeNames();
        }
    }
}

void ScPosWnd::HideTip()
{
    if ( nTipVisible )
    {
        Help::HideTip( nTipVisible );
        nTipVisible = 0;
    }
}

ScNameInputType lcl_GetInputType( const String& rText )
{
    ScNameInputType eRet = SC_NAME_INPUT_BAD_NAME;      // the more general error

    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if ( pViewSh )
    {
        ScViewData* pViewData = pViewSh->GetViewData();
        ScDocument* pDoc = pViewData->GetDocument();
        SCTAB nTab = pViewData->GetTabNo();
        formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();

        // test in same order as in SID_CURRENTCELL execute

        ScRange aRange;
        ScAddress aAddress;
        ScRangeUtil aRangeUtil;
        SCTAB nNameTab;
        sal_Int32 nNumeric;

        if ( aRange.Parse( rText, pDoc, eConv ) & SCA_VALID )
            eRet = SC_NAME_INPUT_RANGE;
        else if ( aAddress.Parse( rText, pDoc, eConv ) & SCA_VALID )
            eRet = SC_NAME_INPUT_CELL;
        else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_NAMES, eConv ) )
            eRet = SC_NAME_INPUT_NAMEDRANGE;
        else if ( aRangeUtil.MakeRangeFromName( rText, pDoc, nTab, aRange, RUTL_DBASE, eConv ) )
            eRet = SC_NAME_INPUT_DATABASE;
        else if ( ByteString( rText, RTL_TEXTENCODING_ASCII_US ).IsNumericAscii() &&
                  ( nNumeric = rText.ToInt32() ) > 0 && nNumeric <= MAXROW+1 )
            eRet = SC_NAME_INPUT_ROW;
        else if ( pDoc->GetTable( rText, nNameTab ) )
            eRet = SC_NAME_INPUT_SHEET;
        else if ( ScRangeData::IsNameValid( rText, pDoc ) )     // nothing found, create new range?
        {
            if ( pViewData->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
                eRet = SC_NAME_INPUT_DEFINE;
            else
                eRet = SC_NAME_INPUT_BAD_SELECTION;
        }
        else
            eRet = SC_NAME_INPUT_BAD_NAME;
    }

    return eRet;
}

void ScPosWnd::Modify()
{
    ComboBox::Modify();

    HideTip();

    if ( !IsTravelSelect() && !bFormulaMode )
    {
        // determine the action that would be taken for the current input

        ScNameInputType eType = lcl_GetInputType( GetText() );      // uses current view
        sal_uInt16 nStrId = 0;
        switch ( eType )
        {
            case SC_NAME_INPUT_CELL:
                nStrId = STR_NAME_INPUT_CELL;
                break;
            case SC_NAME_INPUT_RANGE:
            case SC_NAME_INPUT_NAMEDRANGE:
                nStrId = STR_NAME_INPUT_RANGE;      // named range or range reference
                break;
            case SC_NAME_INPUT_DATABASE:
                nStrId = STR_NAME_INPUT_DBRANGE;
                break;
            case SC_NAME_INPUT_ROW:
                nStrId = STR_NAME_INPUT_ROW;
                break;
            case SC_NAME_INPUT_SHEET:
                nStrId = STR_NAME_INPUT_SHEET;
                break;
            case SC_NAME_INPUT_DEFINE:
                nStrId = STR_NAME_INPUT_DEFINE;
                break;
            default:
                // other cases (error): no tip help
                break;
        }

        if ( nStrId )
        {
            // show the help tip at the text cursor position

            Window* pWin = GetSubEdit();
            if (!pWin)
                pWin = this;
            Point aPos;
            Cursor* pCur = pWin->GetCursor();
            if (pCur)
                aPos = pWin->LogicToPixel( pCur->GetPos() );
            aPos = pWin->OutputToScreenPixel( aPos );
            Rectangle aRect( aPos, aPos );

            String aText = ScGlobal::GetRscString( nStrId );
            sal_uInt16 nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM;
            nTipVisible = Help::ShowTip(pWin, aRect, aText, nAlign);
        }
    }
}

void ScPosWnd::Select()
{
    ComboBox::Select();         //      in VCL gibt GetText() erst danach den ausgewaehlten Eintrag

    HideTip();

    if (!IsTravelSelect())
        DoEnter();
}

void ScPosWnd::DoEnter()
{
    String aText = GetText();
    if ( aText.Len() )
    {
        if ( bFormulaMode )
        {
            ScModule* pScMod = SC_MOD();
            if ( aText == ScGlobal::GetRscString(STR_FUNCTIONLIST_MORE) )
            {
                //      Funktions-Autopilot
                //!     mit dem bisher eingegebenen Text weiterarbeiten !!!

                //!     new method at ScModule to query if function autopilot is open
                SfxViewFrame* pViewFrm = SfxViewFrame::Current();
                if ( pViewFrm && !pViewFrm->GetChildWindow( SID_OPENDLG_FUNCTION ) )
                    pViewFrm->GetDispatcher()->Execute( SID_OPENDLG_FUNCTION,
                                              SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD );
            }
            else
            {
                ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current() );
                ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
                if (pHdl)
                    pHdl->InsertFunction( aText );
            }
        }
        else
        {
            // depending on the input, select something or create a new named range

            ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
            if ( pViewSh )
            {
                ScViewData* pViewData = pViewSh->GetViewData();
                ScDocShell* pDocShell = pViewData->GetDocShell();
                ScDocument* pDoc = pDocShell->GetDocument();

                ScNameInputType eType = lcl_GetInputType( aText );
                if ( eType == SC_NAME_INPUT_BAD_NAME || eType == SC_NAME_INPUT_BAD_SELECTION )
                {
                    sal_uInt16 nId = ( eType == SC_NAME_INPUT_BAD_NAME ) ? STR_NAME_ERROR_NAME : 
STR_NAME_ERROR_SELECTION;
                    pViewSh->ErrorMessage( nId );
                }
                else if ( eType == SC_NAME_INPUT_DEFINE )
                {
                    ScRangeName* pNames = pDoc->GetRangeName();
                    ScRange aSelection;
                    if ( pNames && !pNames->findByName(aText) &&
                            (pViewData->GetSimpleArea( aSelection ) == SC_MARK_SIMPLE) )
                    {
                        ScRangeName aNewRanges( *pNames );
                        ScAddress aCursor( pViewData->GetCurX(), pViewData->GetCurY(), 
pViewData->GetTabNo() );
                        String aContent;
                        aSelection.Format( aContent, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() 
);
                        ScRangeData* pNew = new ScRangeData( pDoc, aText, aContent, aCursor );
                        if ( aNewRanges.insert(pNew) )
                        {
                            ScDocFunc aFunc(*pDocShell);
                            aFunc.ModifyRangeNames( aNewRanges );
                            pViewSh->UpdateInputHandler(true);
                        }
                        else
                            delete pNew;        // shouldn't happen
                    }
                }
                else
                {
                    // for all selection types, excecute the SID_CURRENTCELL slot.
                    if (eType == SC_NAME_INPUT_CELL || eType == SC_NAME_INPUT_RANGE)
                    {
                        // Note that SID_CURRENTCELL always expects address to
                        // be in Calc A1 format.  Convert the text.
                        ScRange aRange;
                        aRange.ParseAny(aText, pDoc, pDoc->GetAddressConvention());
                        aRange.Format(aText, SCR_ABS_3D, pDoc, ::formula::FormulaGrammar::CONV_OOO);
                    }

                    SfxStringItem aPosItem( SID_CURRENTCELL, aText );
                    SfxBoolItem aUnmarkItem( FN_PARAM_1, sal_True );        // remove existing 
selection

                    pViewSh->GetViewData()->GetDispatcher().Execute( SID_CURRENTCELL,
                                        SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD,
                                        &aPosItem, &aUnmarkItem, 0L );
                }
            }
        }
    }
    else
        SetText( aPosStr );

    ReleaseFocus_Impl();
}

long ScPosWnd::Notify( NotifyEvent& rNEvt )
{
    long nHandled = 0;

    if ( rNEvt.GetType() == EVENT_KEYINPUT )
    {
        const KeyEvent* pKEvt = rNEvt.GetKeyEvent();

        switch ( pKEvt->GetKeyCode().GetCode() )
        {
            case KEY_RETURN:
                DoEnter();
                nHandled = 1;
                break;

            case KEY_ESCAPE:
                if (nTipVisible)
                {
                    // escape when the tip help is shown: only hide the tip
                    HideTip();
                }
                else
                {
                    if (!bFormulaMode)
                        SetText( aPosStr );
                    ReleaseFocus_Impl();
                }
                nHandled = 1;
                break;
        }
    }

    if ( !nHandled )
        nHandled = ComboBox::Notify( rNEvt );

    if ( rNEvt.GetType() == EVENT_LOSEFOCUS )
        HideTip();

    return nHandled;
}

void ScPosWnd::ReleaseFocus_Impl()
{
    HideTip();

    SfxViewShell* pCurSh = SfxViewShell::Current();
    ScInputHandler* pHdl = SC_MOD()->GetInputHdl( PTR_CAST( ScTabViewShell, pCurSh ) );
    if ( pHdl && pHdl->IsTopMode() )
    {
        //      Focus wieder in die Eingabezeile?

        ScInputWindow* pInputWin = pHdl->GetInputWindow();
        if (pInputWin)
        {
            pInputWin->TextGrabFocus();
            return;
        }
    }

    //  Focus auf die aktive View

    if ( pCurSh )
    {
        Window* pShellWnd = pCurSh->GetWindow();

        if ( pShellWnd )
            pShellWnd->GrabFocus();
    }
}






/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.