Files
libreoffice/sc/source/ui/formdlg/dwfunctr.cxx
Stephan Bergmann 1c5613e108 loplugin:cstylecast: deal with remaining pointer casts
Change-Id: I700b727c048aff5c19411fb9d5bd9601b296cb06
2015-06-08 16:27:31 +02:00

1099 lines
34 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <comphelper/string.hxx>
#include <editeng/editview.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/viewsh.hxx>
#include "sc.hrc"
#include "global.hxx"
#include "scresid.hxx"
#include "reffact.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "scmod.hxx"
#include "inputhdl.hxx"
#include "tabvwsh.hxx"
#include "appoptio.hxx"
#include "compiler.hxx"
#include "dwfunctr.hrc"
#include "dwfunctr.hxx"
SFX_IMPL_DOCKINGWINDOW_WITHID( ScFunctionChildWindow, FID_FUNCTION_BOX )
/*************************************************************************
#* Member: ScFunctionChildWindow
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionChildWindow
#*
#* Funktion: Konstruktor der Klasse ScFunctionChildWindow
#* Ableitung vom SfxChildWindow als "Behaelter" fuer
#* Funktions- Fenster in Clac
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
ScFunctionChildWindow::ScFunctionChildWindow( vcl::Window* pParentP,
sal_uInt16 nId,
SfxBindings* pBindings,
SfxChildWinInfo* pInfo ) :
SfxChildWindow( pParentP, nId )
{
VclPtr<ScFunctionDockWin> pWin = VclPtr<ScFunctionDockWin>::Create( pBindings, this,
pParentP, ScResId( FID_FUNCTION_BOX ) );
pWindow = pWin;
eChildAlignment = SfxChildAlignment::RIGHT;
pWin->Initialize( pInfo );
}
/*************************************************************************
#* Member: ScFunctionDockWin
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Konstruktor der Klasse ScFunctionDockWin
#*
#* Input: Sfx- Verknuepfungen, Fenster, Resource
#*
#* Output: ---
#*
#************************************************************************/
ScFunctionDockWin::ScFunctionDockWin( SfxBindings* pBindingsP,
SfxChildWindow *pCW, vcl::Window* pParent, const ResId& rResId ) :
SfxDockingWindow( pBindingsP, pCW, pParent, rResId ),
aPrivatSplit ( VclPtr<ScPrivatSplit>::Create( this, ResId( FT_SPLIT, *rResId.GetResMgr() ),SC_SPLIT_VERT) ),
aCatBox ( VclPtr<ListBox>::Create( this, ResId( CB_CAT, *rResId.GetResMgr() ) ) ),
aFuncList ( VclPtr<ListBox>::Create( this, ResId( LB_FUNC, *rResId.GetResMgr() ) ) ),
aDDFuncList ( VclPtr<ListBox>::Create( this, ResId( DDLB_FUNC, *rResId.GetResMgr() ) ) ),
aInsertButton ( VclPtr<ImageButton>::Create( this, ResId( IMB_INSERT, *rResId.GetResMgr() ) ) ),
aFiFuncDesc ( VclPtr<FixedText>::Create( this, ResId( FI_FUNCDESC, *rResId.GetResMgr() ) ) ),
aOldSize (0,0),
pFuncDesc (NULL)
{
FreeResource();
InitLRUList();
SetStyle(GetStyle()|WB_CLIPCHILDREN);
aIdle.SetPriority(SchedulerPriority::LOWER);
aIdle.SetIdleHdl(LINK( this, ScFunctionDockWin, TimerHdl));
if (pCW != NULL)
eSfxNewAlignment=GetAlignment();
else
eSfxNewAlignment=SfxChildAlignment::RIGHT;
eSfxOldAlignment=eSfxNewAlignment;
aFiFuncDesc->SetUpdateMode(true);
pAllFuncList=aFuncList.get();
aDDFuncList->Disable();
aDDFuncList->Hide();
nArgs=0;
nDockMode=0;
bSizeFlag=false;
aCatBox->SetDropDownLineCount(9);
vcl::Font aFont=aFiFuncDesc->GetFont();
aFont.SetColor(Color(COL_BLACK));
aFiFuncDesc->SetFont(aFont);
aFiFuncDesc->SetBackground( GetBackground() ); //! never transparent?
Link<> aLink=LINK( this, ScFunctionDockWin, SelHdl);
aCatBox->SetSelectHdl(aLink);
aFuncList->SetSelectHdl(aLink);
aDDFuncList->SetSelectHdl(aLink);
Link<> a2Link=LINK( this, ScFunctionDockWin, SetSelectionHdl);
aFuncList->SetDoubleClickHdl(a2Link);
aDDFuncList->SetSelectHdl(aLink);
aInsertButton->SetClickHdl(a2Link);
Link<> a3Link=LINK( this, ScFunctionDockWin, SetSplitHdl);
aPrivatSplit->SetCtrModifiedHdl(a3Link);
StartListening( *pBindingsP, true );
Point aTopLeft=aCatBox->GetPosPixel();
OUString aString("ww");
Size aTxtSize( aFiFuncDesc->GetTextWidth(aString), aFiFuncDesc->GetTextHeight() );
nMinWidth=aTxtSize.Width()+aTopLeft.X()
+2*aFuncList->GetPosPixel().X();
nMinHeight=19*aTxtSize.Height();
aCatBox->SelectEntryPos(0);
Range aYRange(3*aTxtSize.Height()+aFuncList->GetPosPixel().Y(),
GetOutputSizePixel().Height()-2*aTxtSize.Height());
aPrivatSplit->SetYRange(aYRange);
SelHdl(aCatBox.get());
bInit = true;
}
/*************************************************************************
#* Member: ScFunctionDockWin
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Destruktor der Klasse ScFunctionDockWin
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
ScFunctionDockWin::~ScFunctionDockWin()
{
disposeOnce();
}
void ScFunctionDockWin::dispose()
{
EndListening( GetBindings() );
aPrivatSplit.disposeAndClear();
aCatBox.disposeAndClear();
aFuncList.disposeAndClear();
aDDFuncList.disposeAndClear();
aInsertButton.disposeAndClear();
aFiFuncDesc.disposeAndClear();
pAllFuncList.clear();
SfxDockingWindow::dispose();
}
/*************************************************************************
#* Member: UpdateFunctionList
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Aktualisiert die Liste der Funktionen ab-
#* haengig von der eingestellten Kategorie.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::InitLRUList()
{
ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
pFuncMgr->fillLastRecentlyUsedFunctions(aLRUList);
sal_Int32 nSelPos = aCatBox->GetSelectEntryPos();
if(nSelPos == 0)
UpdateFunctionList();
}
/*************************************************************************
#* Member: UpdateFunctionList
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Aktualisiert die Liste der zuletzt verwendeten Funktionen.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::UpdateLRUList()
{
if (pFuncDesc && pFuncDesc->nFIndex!=0)
{
ScModule* pScMod = SC_MOD();
pScMod->InsertEntryToLRUList(pFuncDesc->nFIndex);
}
}
/*************************************************************************
#* Member: SetSize
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Groesse fuer die einzelnen Controls einzustellen.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetSize()
{
sal_Int32 nSelEntry=0;
SfxChildAlignment aChildAlign=eSfxOldAlignment;//GetAlignment();
short nNewDockMode;
switch(aChildAlign)
{
case SfxChildAlignment::HIGHESTTOP:
case SfxChildAlignment::TOP:
case SfxChildAlignment::LOWESTTOP:
case SfxChildAlignment::LOWESTBOTTOM:
case SfxChildAlignment::BOTTOM:
case SfxChildAlignment::TOOLBOXTOP:
case SfxChildAlignment::TOOLBOXBOTTOM:
nNewDockMode=1;
if(nDockMode!=nNewDockMode)
{
nDockMode=nNewDockMode;
nSelEntry=aFuncList->GetSelectEntryPos();
aFuncList->Clear();
aFiFuncDesc->SetPosPixel(aFuncList->GetPosPixel());
aDDFuncList->Enable();
aDDFuncList->Show();
aPrivatSplit->Disable();
aPrivatSplit->Hide();
aFuncList->Disable();
aFuncList->Hide();
pAllFuncList=aDDFuncList.get();
SelHdl(aCatBox.get());
aDDFuncList->SelectEntryPos(nSelEntry);
}
break;
default: nNewDockMode=0;
if(nDockMode!=nNewDockMode)
{
nDockMode=nNewDockMode;
nSelEntry=aDDFuncList->GetSelectEntryPos();
aDDFuncList->Clear();
aDDFuncList->Disable();
aDDFuncList->Hide();
aPrivatSplit->Enable();
aPrivatSplit->Show();
aFuncList->Enable();
aFuncList->Show();
pAllFuncList=aFuncList.get();
SelHdl(aCatBox.get());
aFuncList->SelectEntryPos(nSelEntry);
}
break;
}
if(nDockMode==0)
{
SetLeftRightSize();
}
else
{
SetTopBottonSize();
}
}
/*************************************************************************
#* Member: SetLeftRightSize
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Groesse fuer die einzelnen Controls einstellen,
#* wenn Links oder Rechts angedockt wird.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetLeftRightSize()
{
if(!bSizeFlag)
{
bSizeFlag = true;
Size aDiffSize=GetSizePixel();
Size aNewSize=GetOutputSizePixel();
aDiffSize.Width()-=aNewSize.Width();
aDiffSize.Height()-=aNewSize.Height();
OUString aString("ww");
Size aTxtSize( aFuncList->GetTextWidth(aString), aFuncList->GetTextHeight() );
Range aYRange(3*aTxtSize.Height()+aFuncList->GetPosPixel().Y(),
GetOutputSizePixel().Height()-2*aTxtSize.Height());
aPrivatSplit->SetYRange(aYRange);
if(aOldSize.Width()!=aNewSize.Width())
SetMyWidthLeRi(aNewSize);
if(aOldSize.Height()!=aNewSize.Height())
SetMyHeightLeRi(aNewSize);
aOldSize=aNewSize;
aNewSize.Width()+=aDiffSize.Width();
aNewSize.Height()+=aDiffSize.Height();
bSizeFlag=false;
}
}
/*************************************************************************
#* Member: SetTopBottonSize
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Groesse fuer die einzelnen Controls einzustellen.
#* wenn oben oder unten angedockt wird.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetTopBottonSize()
{
if(!bSizeFlag)
{
bSizeFlag = true;
Size aDiffSize=GetSizePixel();
Size aNewSize=GetOutputSizePixel();
aDiffSize.Width()-=aNewSize.Width();
aDiffSize.Height()-=aNewSize.Height();
SetMyWidthToBo(aNewSize);
SetMyHeightToBo(aNewSize);
aNewSize.Width()+=aDiffSize.Width();
aNewSize.Height()+=aDiffSize.Height();
bSizeFlag=false;
}
}
/*************************************************************************
#* Member: SetMyWidthLeRi
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Breite fuer die einzelnen Controls und
#* das Fenster einstellen,wenn Li oder Re
#*
#* Input: neue Fenstergroesse
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetMyWidthLeRi(Size &aNewSize)
{
if((sal_uLong)aNewSize.Width()<nMinWidth) aNewSize.Width()=nMinWidth;
Size aCDSize=aCatBox->GetSizePixel();
Size aFLSize=aFuncList->GetSizePixel();
Size aSplitterSize=aPrivatSplit->GetSizePixel();
Size aFDSize=aFiFuncDesc->GetSizePixel();
Point aCDTopLeft=aCatBox->GetPosPixel();
Point aFLTopLeft=aFuncList->GetPosPixel();
aCDSize.Width()=aNewSize.Width()-aCDTopLeft.X()-aFLTopLeft.X();
aFLSize.Width()=aNewSize.Width()-2*aFLTopLeft.X();
aFDSize.Width()=aFLSize.Width();
aSplitterSize.Width()=aFLSize.Width();
aCatBox->SetSizePixel(aCDSize);
aFuncList->SetSizePixel(aFLSize);
aPrivatSplit->SetSizePixel(aSplitterSize);
aFiFuncDesc->SetSizePixel(aFDSize);
}
/*************************************************************************
#* Member: SetHeight
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Hoehe fuer die einzelnen Controls und
#* das Fenster einstellen bei Li oder Re
#*
#* Input: neue Fenstergroesse
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetMyHeightLeRi(Size &aNewSize)
{
if((sal_uLong)aNewSize.Height()<nMinHeight) aNewSize.Height()=nMinHeight;
Size aFLSize=aFuncList->GetSizePixel();
Size aSplitterSize=aPrivatSplit->GetSizePixel();
Size aFDSize=aFiFuncDesc->GetSizePixel();
Point aFLTopLeft=aFuncList->GetPosPixel();
Point aSplitterTopLeft=aPrivatSplit->GetPosPixel();
Point aFDTopLeft=aFiFuncDesc->GetPosPixel();
long nTxtHeight = aFuncList->GetTextHeight();
short nY=(short)(3*nTxtHeight+
aFuncList->GetPosPixel().Y()+aSplitterSize.Height());
aFDTopLeft.Y()=aNewSize.Height()-aFDSize.Height()-4;
if(nY>aFDTopLeft.Y())
{
aFDSize.Height()-=nY-aFDTopLeft.Y();
aFDTopLeft.Y()=nY;
}
aSplitterTopLeft.Y()=aFDTopLeft.Y()-aSplitterSize.Height()-1;
aFLSize.Height()=aSplitterTopLeft.Y()-aFLTopLeft.Y()-1;
aFuncList->SetSizePixel(aFLSize);
aPrivatSplit->SetPosPixel(aSplitterTopLeft);
aFiFuncDesc->SetPosPixel(aFDTopLeft);
aFiFuncDesc->SetSizePixel(aFDSize);
}
/*************************************************************************
#* Member: SetMyWidthToBo
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Breite fuer die einzelnen Controls und
#* das Fenster einstellen, wenn oben oder
#* unten angedockt werden soll.
#*
#* Input: neue Fenstergroesse
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetMyWidthToBo(Size &aNewSize)
{
if((sal_uLong)aNewSize.Width()<nMinWidth) aNewSize.Width()=nMinWidth;
Size aCDSize=aCatBox->GetSizePixel();
Size aDdFLSize=aDDFuncList->GetSizePixel();
Size aFDSize=aFiFuncDesc->GetSizePixel();
Point aCDTopLeft=aCatBox->GetPosPixel();
Point aDdFLTopLeft=aDDFuncList->GetPosPixel();
Point aFDTopLeft=aFiFuncDesc->GetPosPixel();
aCDSize.Width()=aDdFLTopLeft.X()-aFDTopLeft.X()-aCDTopLeft.X();
aDdFLTopLeft.X()=aCDSize.Width()+aCDTopLeft.X()+aFDTopLeft.X();
aDdFLSize.Width()=aNewSize.Width()-aDdFLTopLeft.X()-aFDTopLeft.X();
aFDSize.Width()=aNewSize.Width()-2*aFDTopLeft.X();
aDDFuncList->SetPosPixel(aDdFLTopLeft);
aDDFuncList->SetSizePixel(aDdFLSize);
aCatBox->SetSizePixel(aCDSize);
aFiFuncDesc->SetSizePixel(aFDSize);
}
/*************************************************************************
#* Member: SetHeight
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Hoehe fuer die einzelnen Controls und
#* das Fenster einstellen, wenn oben oder
#* unten angedockt werden soll.
#*
#* Input: neue Fenstergroesse
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetMyHeightToBo(Size &aNewSize)
{
if((sal_uLong)aNewSize.Height()<nMinHeight) aNewSize.Height()=nMinHeight;
Size aFDSize=aFiFuncDesc->GetSizePixel();
Point aFDTopLeft=aFiFuncDesc->GetPosPixel();
Point aCBTopLeft=aCatBox->GetPosPixel();
aFDSize.Height()=aNewSize.Height()-aFDTopLeft.Y()-aCBTopLeft.Y();
aFiFuncDesc->SetSizePixel(aFDSize);
}
/*************************************************************************
#* Member: SetDescription
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Erklaerungstext fuer die Funktion einstellen.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::SetDescription()
{
aFiFuncDesc->SetText( EMPTY_OUSTRING );
const ScFuncDesc* pDesc =
static_cast<const ScFuncDesc*>(pAllFuncList->GetEntryData(
pAllFuncList->GetSelectEntryPos() ));
if (pDesc)
{
pDesc->initArgumentInfo(); // full argument info is needed
OUStringBuffer aBuf(pAllFuncList->GetSelectEntry());
if(nDockMode==0)
{
aBuf.appendAscii(":\n\n");
}
else
{
aBuf.appendAscii(": ");
}
aBuf.append(pDesc->GetParamList());
if(nDockMode==0)
{
aBuf.appendAscii("\n\n");
}
else
{
aBuf.appendAscii("\n");
}
aBuf.append(*pDesc->pFuncDesc);
aFiFuncDesc->SetText(aBuf.makeStringAndClear());
aFiFuncDesc->StateChanged(StateChangedType::Text);
aFiFuncDesc->Invalidate();
aFiFuncDesc->Update();
}
}
/// override to set new size of the controls
void ScFunctionDockWin::Resizing( Size& rNewSize )
{
if((sal_uLong)rNewSize.Width()<nMinWidth) rNewSize.Width()=nMinWidth;
if((sal_uLong)rNewSize.Height()<nMinHeight) rNewSize.Height()=nMinHeight;
}
/*************************************************************************
#* Member: Close
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Schliessen des Fensters
#*
#* Input: ---
#*
#* Output: TRUE
#*
#************************************************************************/
bool ScFunctionDockWin::Close()
{
SfxBoolItem aItem( FID_FUNCTION_BOX, false );
GetBindings().GetDispatcher()->Execute( FID_FUNCTION_BOX,
SfxCallMode::ASYNCHRON | SfxCallMode::RECORD,
&aItem, 0L );
SfxDockingWindow::Close();
return true;
}
/*************************************************************************
#* Member: CheckAlignment
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Ueberprueft den Andockmodus und stellt die
#* Groessen dementsprechend ein.
#*
#* Input: Das neue Alignment
#*
#* Output: Das uebergebene Alignment
#*
#************************************************************************/
SfxChildAlignment ScFunctionDockWin::CheckAlignment(SfxChildAlignment /* abla */,
SfxChildAlignment aChildAlign)
{
OUString aString("ww");
Size aTxtSize( aFiFuncDesc->GetTextWidth(aString), aFiFuncDesc->GetTextHeight() );
if(!bInit)
{
eSfxOldAlignment=eSfxNewAlignment;
eSfxNewAlignment=aChildAlign;
}
else
{
bInit=false;
eSfxOldAlignment=aChildAlign;
eSfxNewAlignment=aChildAlign;
}
switch(eSfxOldAlignment)
{
case SfxChildAlignment::HIGHESTTOP:
case SfxChildAlignment::TOP:
case SfxChildAlignment::LOWESTTOP:
case SfxChildAlignment::LOWESTBOTTOM:
case SfxChildAlignment::BOTTOM:
case SfxChildAlignment::TOOLBOXTOP:
case SfxChildAlignment::TOOLBOXBOTTOM:
nMinWidth= 0;
nMinHeight=0;
break;
case SfxChildAlignment::NOALIGNMENT:
aString = aCatBox->GetEntry(0);
aString += "www";
aTxtSize = Size( aFiFuncDesc->GetTextWidth(aString),
aFiFuncDesc->GetTextHeight() );
// fall-through
default: Point aTopLeft=aCatBox->GetPosPixel();
nMinWidth=aTxtSize.Width()+aTopLeft.X()
+2*aFuncList->GetPosPixel().X();
nMinHeight=19*aTxtSize.Height();
break;
}
return aChildAlign;
}
/*************************************************************************
#* Member: Close
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Aenderungen erkennen
#*
#* Input: ---
#*
#* Output: TRUE
#*
#************************************************************************/
void ScFunctionDockWin::Notify( SfxBroadcaster&, const SfxHint& /* rHint */ )
{
}
/// override to set new size of the controls
void ScFunctionDockWin::Resize()
{
if ( !IsFloatingMode() ||
!GetFloatingWindow()->IsRollUp() )
{
Size aQSize=GetOutputSizePixel();
Resizing( aQSize);
SetSize();
}
SfxDockingWindow::Resize();
}
/*************************************************************************
#* Member: UpdateFunctionList
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Aktualisiert die Liste der Funktionen ab-
#* haengig von der eingestellten Kategorie.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::UpdateFunctionList()
{
sal_Int32 nSelPos = aCatBox->GetSelectEntryPos();
sal_Int32 nCategory = ( LISTBOX_ENTRY_NOTFOUND != nSelPos )
? (nSelPos-1) : 0;
pAllFuncList->Clear();
pAllFuncList->SetUpdateMode( false );
if ( nSelPos > 0 )
{
ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
const ScFuncDesc* pDesc = pFuncMgr->First( nCategory );
while ( pDesc )
{
pAllFuncList->SetEntryData(
pAllFuncList->InsertEntry( *(pDesc->pFuncName) ),
const_cast<ScFuncDesc *>(pDesc) );
pDesc = pFuncMgr->Next();
}
}
else // LRU-Liste
{
for (::std::vector<const formula::IFunctionDescription*>::iterator iter=aLRUList.begin();
iter != aLRUList.end(); ++iter)
{
const formula::IFunctionDescription* pDesc = *iter;
if (pDesc)
pAllFuncList->SetEntryData( pAllFuncList->InsertEntry( pDesc->getFunctionName()), const_cast<formula::IFunctionDescription *>(pDesc));
}
}
pAllFuncList->SetUpdateMode( true );
if ( pAllFuncList->GetEntryCount() > 0 )
{
pAllFuncList->Enable();
pAllFuncList->SelectEntryPos( 0 );
}
else
{
pAllFuncList->Disable();
}
}
/*************************************************************************
#* Member: DoEnter
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Eingabe ins Dokument uebernehmen. Wird aufgerufen
#* nach betaetigen der Uebernehmen- Schaltflaeche
#* oder einem Doppelklick in die Funktionsliste.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
void ScFunctionDockWin::DoEnter()
{
OUString aFirstArgStr;
OUString aArgStr;
OUString aString=pAllFuncList->GetSelectEntry();
SfxViewShell* pCurSh = SfxViewShell::Current();
nArgs=0;
if(!aString.isEmpty())
{
ScModule* pScMod = SC_MOD();
ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, pCurSh);
ScInputHandler* pHdl = pScMod->GetInputHdl( pViewSh );
if(!pScMod->IsEditMode())
{
pScMod->SetInputMode(SC_INPUT_TABLE);
aString = "=";
aString += pAllFuncList->GetSelectEntry();
if (pHdl)
pHdl->ClearText();
}
const ScFuncDesc* pDesc =
static_cast<const ScFuncDesc*>(pAllFuncList->GetEntryData(
pAllFuncList->GetSelectEntryPos() ));
if (pDesc)
{
pFuncDesc=pDesc;
UpdateLRUList();
nArgs = pDesc->nArgCount;
if(nArgs>0)
{
// NOTE: Theoretically the first parameter could have the
// suppress flag as well, but practically it doesn't.
aFirstArgStr = pDesc->maDefArgNames[0];
aFirstArgStr = comphelper::string::strip(aFirstArgStr, ' ');
aFirstArgStr = aFirstArgStr.replaceAll(" ", "_");
aArgStr = aFirstArgStr;
if ( nArgs != VAR_ARGS && nArgs != PAIRED_VAR_ARGS )
{ // no VarArgs or Fix plus VarArgs, but not VarArgs only
OUString aArgSep("; ");
sal_uInt16 nFix;
if (nArgs >= PAIRED_VAR_ARGS)
nFix = nArgs - PAIRED_VAR_ARGS + 2;
else if (nArgs >= VAR_ARGS)
nFix = nArgs - VAR_ARGS + 1;
else
nFix = nArgs;
for ( sal_uInt16 nArg = 1;
nArg < nFix && !pDesc->pDefArgFlags[nArg].bOptional; nArg++ )
{
if (!pDesc->pDefArgFlags[nArg].bSuppress)
{
aArgStr += aArgSep;
OUString sTmp = pDesc->maDefArgNames[nArg];
sTmp = comphelper::string::strip(sTmp, ' ');
sTmp = sTmp.replaceAll(" ", "_");
aArgStr += sTmp;
}
}
}
}
}
if (pHdl)
{
if (pHdl->GetEditString().isEmpty())
{
aString = "=";
aString += pAllFuncList->GetSelectEntry();
}
EditView *pEdView=pHdl->GetActiveView();
if(pEdView!=NULL) // @ Wegen Absturz bei Namen festlegen
{
if(nArgs>0)
{
pHdl->InsertFunction(aString);
pEdView->InsertText(aArgStr,true);
ESelection aESel=pEdView->GetSelection();
aESel.nEndPos = aESel.nStartPos + aFirstArgStr.getLength();
pEdView->SetSelection(aESel);
pHdl->DataChanged();
}
else
{
aString += "()";
pEdView->InsertText(aString,false);
pHdl->DataChanged();
}
}
}
InitLRUList();
}
if ( pCurSh )
{
vcl::Window* pShellWnd = pCurSh->GetWindow();
if ( pShellWnd )
pShellWnd->GrabFocus();
}
}
/*************************************************************************
#* Handle: SelHdl
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Bei einer Aenderung der Kategorie wird die
#* die Liste der Funktionen aktualisiert.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
IMPL_LINK( ScFunctionDockWin, SelHdl, ListBox*, pLb )
{
if ( pLb == aCatBox.get() )
{
UpdateFunctionList();
SetDescription();
}
if ( pLb == aFuncList.get() || pLb == aDDFuncList.get() )
{
SetDescription();
}
//SetSize();
return 0;
}
/*************************************************************************
#* Handle: SelHdl
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Bei einer Aenderung der Kategorie wird die
#* die Liste der Funktionen aktualisiert.
#*
#* Input: ---
#*
#* Output: ---
#*
#************************************************************************/
IMPL_LINK( ScFunctionDockWin, SetSelectionHdl, void*, pCtrl )
{
if (static_cast<ImageButton *>(pCtrl) == aInsertButton.get() ||
static_cast<ListBox *>(pCtrl) == aFuncList.get())
{
DoEnter(); // Uebernimmt die Eingabe
}
return 0;
}
/*************************************************************************
#* Handle: SetSplitHdl
#*------------------------------------------------------------------------
#*
#* Klasse: ScFunctionDockWin
#*
#* Funktion: Bei einer Aenderung des Split- Controls werden die
#* einzelnen Controls an die neue Groesse angepasst.
#*
#* Input: Zeiger auf Control
#*
#* Output: ---
#*
#************************************************************************/
IMPL_LINK( ScFunctionDockWin, SetSplitHdl, ScPrivatSplit*, pCtrl )
{
if (pCtrl == aPrivatSplit.get())
{
short nDeltaY=aPrivatSplit->GetDeltaY();
Size aFLSize=aFuncList->GetSizePixel();
Size aFDSize=aFiFuncDesc->GetSizePixel();
Point aFDTopLeft=aFiFuncDesc->GetPosPixel();
aFLSize.Height()+=nDeltaY;
aFDSize.Height()-=nDeltaY;
aFDTopLeft.Y()+=nDeltaY;
aFuncList->SetSizePixel(aFLSize);
aFiFuncDesc->SetPosPixel(aFDTopLeft);
aFiFuncDesc->SetSizePixel(aFDSize);
}
return 0;
}
void ScFunctionDockWin::ToggleFloatingMode()
{
aSplitterInitPos = Point();
SfxDockingWindow::ToggleFloatingMode();
eSfxNewAlignment=GetAlignment();
eSfxOldAlignment=eSfxNewAlignment;
aOldSize.Height()=0;
aOldSize.Width()=0;
aIdle.Start();
}
IMPL_LINK_NOARG_TYPED(ScFunctionDockWin, TimerHdl, Idle *, void)
{
CheckAlignment(eSfxOldAlignment,eSfxNewAlignment);
SetSize();
}
void ScFunctionDockWin::Initialize(SfxChildWinInfo *pInfo)
{
OUString aStr;
if(pInfo!=NULL)
{
if ( !pInfo->aExtraString.isEmpty() )
{
sal_Int32 nPos = pInfo->aExtraString.indexOf( "ScFuncList:" );
// Versuche, den Alignment-String "ALIGN:(...)" einzulesen; wenn
// er nicht vorhanden ist, liegt eine "altere Version vor
if ( nPos != -1 )
{
sal_Int32 n1 = pInfo->aExtraString.indexOf('(', nPos);
if ( n1 != -1 )
{
sal_Int32 n2 = pInfo->aExtraString.indexOf(')', n1);
if ( n2 != -1 )
{
// Alignment-String herausschneiden
aStr = pInfo->aExtraString.copy(nPos, n2 - nPos + 1);
pInfo->aExtraString = pInfo->aExtraString.replaceAt(nPos, n2 - nPos + 1, "");
aStr = aStr.copy( n1-nPos+1 );
}
}
}
}
}
SfxDockingWindow::Initialize(pInfo);
if ( !aStr.isEmpty())
{
aSplitterInitPos = aPrivatSplit->GetPosPixel();
aSplitterInitPos.Y() = (sal_uInt16) aStr.toInt32();
sal_Int32 n1 = aStr.indexOf(';');
aStr = aStr.copy( n1+1 );
sal_Int32 nSelPos = aStr.toInt32();
aCatBox->SelectEntryPos(nSelPos);
SelHdl(aCatBox.get());
// if the window has already been shown (from SfxDockingWindow::Initialize if docked),
// set the splitter position now, otherwise it is set in StateChanged with type INITSHOW
UseSplitterInitPos();
}
}
void ScFunctionDockWin::FillInfo(SfxChildWinInfo& rInfo) const
{
SfxDockingWindow::FillInfo(rInfo);
Point aPoint=aPrivatSplit->GetPosPixel();
rInfo.aExtraString += "ScFuncList:(" +
OUString::number(aPoint.Y()) + ";" +
OUString::number(aCatBox->GetSelectEntryPos()) + ")";
}
void ScFunctionDockWin::UseSplitterInitPos()
{
if ( IsVisible() && aPrivatSplit->IsEnabled() && aSplitterInitPos != Point() )
{
aPrivatSplit->MoveSplitTo(aSplitterInitPos);
aSplitterInitPos = Point(); // use only once
}
}
void ScFunctionDockWin::StateChanged( StateChangedType nStateChange )
{
SfxDockingWindow::StateChanged( nStateChange );
if (nStateChange == StateChangedType::InitShow)
{
UseSplitterInitPos(); // set initial splitter position if necessary
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */