xref: /aoo41x/main/sc/source/ui/formdlg/formula.cxx (revision b3f79822)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir //----------------------------------------------------------------------------
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
33cdf0e10cSrcweir #include <sfx2/docfile.hxx>
34cdf0e10cSrcweir #include <sfx2/objsh.hxx>
35cdf0e10cSrcweir #include <svl/zforlist.hxx>
36cdf0e10cSrcweir #include <svl/stritem.hxx>
37cdf0e10cSrcweir #include <svtools/svtreebx.hxx>
38cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
39cdf0e10cSrcweir #include <vcl/svapp.hxx>
40cdf0e10cSrcweir #include <vcl/mnemonic.hxx>
41cdf0e10cSrcweir #include <unotools/charclass.hxx>
42cdf0e10cSrcweir #include <tools/urlobj.hxx>
43cdf0e10cSrcweir #include <formula/formulahelper.hxx>
44cdf0e10cSrcweir #include <formula/IFunctionDescription.hxx>
45cdf0e10cSrcweir 
46cdf0e10cSrcweir #include "tokenuno.hxx"
47cdf0e10cSrcweir #include "formula.hxx"
48cdf0e10cSrcweir #include "formdata.hxx"
49cdf0e10cSrcweir #include "globstr.hrc"
50cdf0e10cSrcweir #include "scresid.hxx"
51cdf0e10cSrcweir #include "reffact.hxx"
52cdf0e10cSrcweir #include "document.hxx"
53cdf0e10cSrcweir #include "cell.hxx"
54cdf0e10cSrcweir #include "scmod.hxx"
55cdf0e10cSrcweir #include "inputhdl.hxx"
56cdf0e10cSrcweir #include "tabvwsh.hxx"
57cdf0e10cSrcweir #include "appoptio.hxx"
58cdf0e10cSrcweir #include "docsh.hxx"
59cdf0e10cSrcweir #include "funcdesc.hxx"
60cdf0e10cSrcweir #include "formula/token.hxx"
61cdf0e10cSrcweir #include "tokenarray.hxx"
62cdf0e10cSrcweir #include "sc.hrc"
63cdf0e10cSrcweir #include "servuno.hxx"
64cdf0e10cSrcweir #include "unonames.hxx"
65cdf0e10cSrcweir #include "externalrefmgr.hxx"
66cdf0e10cSrcweir 
67cdf0e10cSrcweir #include <com/sun/star/table/CellAddress.hpp>
68cdf0e10cSrcweir 
69cdf0e10cSrcweir //============================================================================
70cdf0e10cSrcweir using namespace formula;
71cdf0e10cSrcweir using namespace com::sun::star;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir ScDocument*	ScFormulaDlg::pDoc = NULL;
74cdf0e10cSrcweir ScAddress ScFormulaDlg::aCursorPos;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 
78cdf0e10cSrcweir //	--------------------------------------------------------------------------
79cdf0e10cSrcweir //		Initialisierung / gemeinsame Funktionen  fuer Dialog
80cdf0e10cSrcweir //	--------------------------------------------------------------------------
81cdf0e10cSrcweir 
ScFormulaDlg(SfxBindings * pB,SfxChildWindow * pCW,Window * pParent,ScViewData * pViewData,formula::IFunctionManager * _pFunctionMgr)82cdf0e10cSrcweir ScFormulaDlg::ScFormulaDlg( SfxBindings* pB, SfxChildWindow* pCW,
83cdf0e10cSrcweir 									Window* pParent, ScViewData* pViewData,formula::IFunctionManager* _pFunctionMgr )
84cdf0e10cSrcweir     : formula::FormulaDlg( pB, pCW, pParent, true,true,true,this, _pFunctionMgr,this)
85cdf0e10cSrcweir     , m_aHelper(this,pB)
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     m_aHelper.SetWindow(this);
88cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
89cdf0e10cSrcweir     pScMod->InputEnterHandler();
90cdf0e10cSrcweir     ScTabViewShell* pScViewShell = NULL;
91cdf0e10cSrcweir 
92cdf0e10cSrcweir 	// title has to be from the view that opened the dialog,
93cdf0e10cSrcweir 	// even if it's not the current view
94cdf0e10cSrcweir 
95cdf0e10cSrcweir 	SfxObjectShell* pParentDoc = NULL;
96cdf0e10cSrcweir 	if ( pB )
97cdf0e10cSrcweir 	{
98cdf0e10cSrcweir 		SfxDispatcher* pMyDisp = pB->GetDispatcher();
99cdf0e10cSrcweir 		if (pMyDisp)
100cdf0e10cSrcweir 		{
101cdf0e10cSrcweir 			SfxViewFrame* pMyViewFrm = pMyDisp->GetFrame();
102cdf0e10cSrcweir 			if (pMyViewFrm)
103cdf0e10cSrcweir             {
104cdf0e10cSrcweir                 pScViewShell = PTR_CAST( ScTabViewShell, pMyViewFrm->GetViewShell() );
105cdf0e10cSrcweir                 if( pScViewShell )
106cdf0e10cSrcweir 		            pScViewShell->UpdateInputHandler(sal_True);
107cdf0e10cSrcweir 				pParentDoc = pMyViewFrm->GetObjectShell();
108cdf0e10cSrcweir             }
109cdf0e10cSrcweir 		}
110cdf0e10cSrcweir 	}
111cdf0e10cSrcweir 	//if ( !pParentDoc && pScViewShell )					// use current only if above fails
112cdf0e10cSrcweir 	//	pParentDoc = pScViewShell->GetObjectShell();
113cdf0e10cSrcweir 	//if ( pParentDoc )
114cdf0e10cSrcweir 	//	aDocName = pParentDoc->GetTitle();
115cdf0e10cSrcweir 
116cdf0e10cSrcweir     if ( pDoc == NULL )
117cdf0e10cSrcweir         pDoc = pViewData->GetDocument();
118cdf0e10cSrcweir     m_xParser.set(ScServiceProvider::MakeInstance(SC_SERVICE_FORMULAPARS,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
119cdf0e10cSrcweir     uno::Reference< beans::XPropertySet> xSet(m_xParser,uno::UNO_QUERY);
120cdf0e10cSrcweir     xSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COMPILEFAP)),uno::makeAny(sal_True));
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     m_xOpCodeMapper.set(ScServiceProvider::MakeInstance(SC_SERVICE_OPCODEMAPPER,(ScDocShell*)pDoc->GetDocumentShell()),uno::UNO_QUERY);
123cdf0e10cSrcweir 
124cdf0e10cSrcweir     ScInputHandler*	pInputHdl = SC_MOD()->GetInputHdl(pScViewShell);
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 	DBG_ASSERT( pInputHdl, "Missing input handler :-/" );
127cdf0e10cSrcweir 
128cdf0e10cSrcweir 	if ( pInputHdl )
129cdf0e10cSrcweir 		pInputHdl->NotifyChange( NULL );
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 	m_aHelper.enableInput( sal_False );
132cdf0e10cSrcweir 	m_aHelper.EnableSpreadsheets();
133cdf0e10cSrcweir     m_aHelper.Init();
134cdf0e10cSrcweir 	m_aHelper.SetDispatcherLock( sal_True );
135cdf0e10cSrcweir 
136cdf0e10cSrcweir     notifyChange();
137cdf0e10cSrcweir     fill();
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	ScFormEditData* pData = pScMod->GetFormEditData();
140cdf0e10cSrcweir 	if (!pData)
141cdf0e10cSrcweir 	{
142cdf0e10cSrcweir 		//Nun wird es Zeit den Inputhandler festzulegen
143cdf0e10cSrcweir 		pScMod->SetRefInputHdl(pScMod->GetInputHdl());
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 		pDoc = pViewData->GetDocument();
146cdf0e10cSrcweir 		SCCOL nCol = pViewData->GetCurX();
147cdf0e10cSrcweir 		SCROW nRow = pViewData->GetCurY();
148cdf0e10cSrcweir 		SCTAB nTab = pViewData->GetTabNo();
149cdf0e10cSrcweir 		aCursorPos = ScAddress( nCol, nRow, nTab );
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 		pScMod->InitFormEditData();								// neu anlegen
152cdf0e10cSrcweir         pData = pScMod->GetFormEditData();
153cdf0e10cSrcweir 		pData->SetInputHandler(pScMod->GetInputHdl());
154cdf0e10cSrcweir 		pData->SetDocShell(pViewData->GetDocShell());
155cdf0e10cSrcweir 
156cdf0e10cSrcweir 		DBG_ASSERT(pData,"FormEditData ist nicht da");
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         formula::FormulaDlgMode eMode = FORMULA_FORMDLG_FORMULA;			// Default...
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 		//	Formel vorhanden? Dann editieren
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 		String aFormula;
163cdf0e10cSrcweir 		pDoc->GetFormula( nCol, nRow, nTab, aFormula );
164cdf0e10cSrcweir 		sal_Bool bEdit   = ( aFormula.Len() > 1 );
165cdf0e10cSrcweir         sal_Bool bMatrix = sal_False;
166cdf0e10cSrcweir 		if ( bEdit )
167cdf0e10cSrcweir 		{
168cdf0e10cSrcweir             bMatrix = CheckMatrix(aFormula);
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 			xub_StrLen nFStart = 0;
171cdf0e10cSrcweir 			xub_StrLen nFEnd   = 0;
172cdf0e10cSrcweir 			if ( GetFormulaHelper().GetNextFunc( aFormula, sal_False, nFStart, &nFEnd) )
173cdf0e10cSrcweir 			{
174cdf0e10cSrcweir 				pScMod->InputReplaceSelection( aFormula );
175cdf0e10cSrcweir 				pScMod->InputSetSelection( nFStart, nFEnd );
176cdf0e10cSrcweir                 xub_StrLen PrivStart, PrivEnd;
177cdf0e10cSrcweir 				pScMod->InputGetSelection( PrivStart, PrivEnd);
178cdf0e10cSrcweir 
179cdf0e10cSrcweir                 eMode = SetMeText(pScMod->InputGetFormulaStr(),PrivStart, PrivEnd,bMatrix,sal_True,sal_True);
180cdf0e10cSrcweir 				pData->SetFStart( nFStart );
181cdf0e10cSrcweir 			}
182cdf0e10cSrcweir 			else
183cdf0e10cSrcweir 				bEdit = sal_False;
184cdf0e10cSrcweir 		}
185cdf0e10cSrcweir 
186cdf0e10cSrcweir 		if ( !bEdit )
187cdf0e10cSrcweir 		{
188cdf0e10cSrcweir 			String aNewFormula = '=';
189cdf0e10cSrcweir 			if ( aFormula.Len() > 0 && aFormula.GetChar(0) == '=' )
190cdf0e10cSrcweir 				aNewFormula=aFormula;
191cdf0e10cSrcweir 
192cdf0e10cSrcweir 			pScMod->InputReplaceSelection( aNewFormula );
193cdf0e10cSrcweir 			pScMod->InputSetSelection( 1, aNewFormula.Len()+1 );
194cdf0e10cSrcweir             xub_StrLen PrivStart, PrivEnd;
195cdf0e10cSrcweir 			pScMod->InputGetSelection( PrivStart, PrivEnd);
196cdf0e10cSrcweir             SetMeText(pScMod->InputGetFormulaStr(),PrivStart, PrivEnd,bMatrix,sal_False,sal_False);
197cdf0e10cSrcweir 
198cdf0e10cSrcweir 			pData->SetFStart( 1 );		// hinter dem "="
199cdf0e10cSrcweir 		}
200cdf0e10cSrcweir 
201cdf0e10cSrcweir 		pData->SetMode( (sal_uInt16) eMode );
202cdf0e10cSrcweir 		String rStrExp = GetMeText();
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 		pCell = new ScFormulaCell( pDoc, aCursorPos, rStrExp );
205cdf0e10cSrcweir 
206cdf0e10cSrcweir 		Update(rStrExp);
207cdf0e10cSrcweir     } // if (!pData)
208cdf0e10cSrcweir 
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
notifyChange()211cdf0e10cSrcweir void ScFormulaDlg::notifyChange()
212cdf0e10cSrcweir {
213cdf0e10cSrcweir 	ScModule* pScMod = SC_MOD();
214cdf0e10cSrcweir 
215cdf0e10cSrcweir 	ScInputHandler*	pInputHdl = pScMod->GetInputHdl();
216cdf0e10cSrcweir 	if ( pInputHdl )
217cdf0e10cSrcweir 		pInputHdl->NotifyChange( NULL );
218cdf0e10cSrcweir }
219cdf0e10cSrcweir // -----------------------------------------------------------------------------
fill()220cdf0e10cSrcweir void ScFormulaDlg::fill()
221cdf0e10cSrcweir {
222cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
223cdf0e10cSrcweir 	ScFormEditData* pData = pScMod->GetFormEditData();
224cdf0e10cSrcweir     notifyChange();
225cdf0e10cSrcweir 	String rStrExp;
226cdf0e10cSrcweir 	if (pData)
227cdf0e10cSrcweir 	{
228cdf0e10cSrcweir 		//	Daten schon vorhanden -> Zustand wiederherstellen (nach Umschalten)
229cdf0e10cSrcweir 		//	pDoc und aCursorPos nicht neu initialisieren
230cdf0e10cSrcweir 		//pDoc = pViewData->GetDocument();
231cdf0e10cSrcweir 		if(IsInputHdl(pData->GetInputHandler()))
232cdf0e10cSrcweir 		{
233cdf0e10cSrcweir 			pScMod->SetRefInputHdl(pData->GetInputHandler());
234cdf0e10cSrcweir 		}
235cdf0e10cSrcweir 		else
236cdf0e10cSrcweir 		{
237cdf0e10cSrcweir 			PtrTabViewShell pTabViewShell;
238cdf0e10cSrcweir 			ScInputHandler*	pInputHdl = GetNextInputHandler(pData->GetDocShell(),&pTabViewShell);
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 			if ( pInputHdl == NULL ) //DocShell hat keinen InputHandler mehr,
241cdf0e10cSrcweir 			{					//hat der Anwender halt Pech gehabt.
242cdf0e10cSrcweir 				disableOk();
243cdf0e10cSrcweir 				pInputHdl = pScMod->GetInputHdl();
244cdf0e10cSrcweir 			}
245cdf0e10cSrcweir 			else
246cdf0e10cSrcweir 			{
247cdf0e10cSrcweir 				pInputHdl->SetRefViewShell(pTabViewShell);
248cdf0e10cSrcweir 			}
249cdf0e10cSrcweir 			pScMod->SetRefInputHdl(pInputHdl);
250cdf0e10cSrcweir 			pData->SetInputHandler(pInputHdl);
251cdf0e10cSrcweir 		}
252cdf0e10cSrcweir 
253cdf0e10cSrcweir         String aOldFormulaTmp(pScMod->InputGetFormulaStr());
254cdf0e10cSrcweir         pScMod->InputSetSelection( 0, aOldFormulaTmp.Len());
255cdf0e10cSrcweir 
256cdf0e10cSrcweir 		rStrExp=pData->GetUndoStr();
257cdf0e10cSrcweir 		pScMod->InputReplaceSelection(rStrExp);
258cdf0e10cSrcweir 
259cdf0e10cSrcweir         SetMeText(rStrExp);
260cdf0e10cSrcweir 
261cdf0e10cSrcweir 		pCell = new ScFormulaCell( pDoc, aCursorPos, rStrExp );
262cdf0e10cSrcweir 
263cdf0e10cSrcweir         Update();
264cdf0e10cSrcweir 		// Jetzt nochmals zurueckschalten, da evtl. neues Doc geoeffnet wurde!
265cdf0e10cSrcweir 		pScMod->SetRefInputHdl(NULL);
266cdf0e10cSrcweir 	}
267cdf0e10cSrcweir }
268cdf0e10cSrcweir 
~ScFormulaDlg()269cdf0e10cSrcweir __EXPORT ScFormulaDlg::~ScFormulaDlg()
270cdf0e10cSrcweir {
271cdf0e10cSrcweir 	ScModule* pScMod = SC_MOD();
272cdf0e10cSrcweir 	ScFormEditData* pData = pScMod->GetFormEditData();
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 	if (pData) // wird nicht ueber Close zerstoert;
275cdf0e10cSrcweir 	{
276cdf0e10cSrcweir 		//Referenz Inputhandler zuruecksetzen
277cdf0e10cSrcweir 		pScMod->SetRefInputHdl(NULL);
278cdf0e10cSrcweir 	} // if (pData) // wird nicht ueber Close zerstoert;
279cdf0e10cSrcweir 
280cdf0e10cSrcweir 	delete pCell;
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
IsInputHdl(ScInputHandler * pHdl)283cdf0e10cSrcweir sal_Bool ScFormulaDlg::IsInputHdl(ScInputHandler* pHdl)
284cdf0e10cSrcweir {
285cdf0e10cSrcweir 	sal_Bool bAlive = sal_False;
286cdf0e10cSrcweir 
287cdf0e10cSrcweir 	//	gehoert der InputHandler zu irgendeiner ViewShell ?
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 	TypeId aScType = TYPE(ScTabViewShell);
290cdf0e10cSrcweir 	SfxViewShell* pSh = SfxViewShell::GetFirst( &aScType );
291cdf0e10cSrcweir 	while ( pSh && !bAlive )
292cdf0e10cSrcweir 	{
293cdf0e10cSrcweir 		if (((ScTabViewShell*)pSh)->GetInputHandler() == pHdl)
294cdf0e10cSrcweir 			bAlive = sal_True;
295cdf0e10cSrcweir 		pSh = SfxViewShell::GetNext( *pSh, &aScType );
296cdf0e10cSrcweir 	}
297cdf0e10cSrcweir 
298cdf0e10cSrcweir 	return bAlive;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
GetNextInputHandler(ScDocShell * pDocShell,PtrTabViewShell * ppViewSh)302cdf0e10cSrcweir ScInputHandler* ScFormulaDlg::GetNextInputHandler(ScDocShell* pDocShell,PtrTabViewShell* ppViewSh)
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	ScInputHandler* pHdl=NULL;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir 	SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
307cdf0e10cSrcweir 	while( pFrame && pHdl==NULL)
308cdf0e10cSrcweir 	{
309cdf0e10cSrcweir 		SfxViewShell* p = pFrame->GetViewShell();
310cdf0e10cSrcweir 		ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
311cdf0e10cSrcweir 		if(pViewSh!=NULL)
312cdf0e10cSrcweir 		{
313cdf0e10cSrcweir 			pHdl=pViewSh->GetInputHandler();
314cdf0e10cSrcweir 			if(ppViewSh!=NULL) *ppViewSh=pViewSh;
315cdf0e10cSrcweir 		}
316cdf0e10cSrcweir 		pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
317cdf0e10cSrcweir 	}
318cdf0e10cSrcweir 
319cdf0e10cSrcweir 
320cdf0e10cSrcweir 	return pHdl;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 
Close()324cdf0e10cSrcweir sal_Bool __EXPORT ScFormulaDlg::Close()
325cdf0e10cSrcweir {
326cdf0e10cSrcweir 	DoEnter(sal_False);
327cdf0e10cSrcweir 	return sal_True;
328cdf0e10cSrcweir }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir //	--------------------------------------------------------------------------
331cdf0e10cSrcweir //							Funktionen fuer rechte Seite
332cdf0e10cSrcweir //	--------------------------------------------------------------------------
calculateValue(const String & rStrExp,String & rStrResult)333cdf0e10cSrcweir bool ScFormulaDlg::calculateValue( const String& rStrExp, String& rStrResult )
334cdf0e10cSrcweir {
335cdf0e10cSrcweir 	sal_Bool bResult = sal_True;
336cdf0e10cSrcweir 
337cdf0e10cSrcweir     ::std::auto_ptr<ScFormulaCell> pFCell( new ScFormulaCell( pDoc, aCursorPos, rStrExp ) );
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 	// #35521# HACK! um bei ColRowNames kein #REF! zu bekommen,
340cdf0e10cSrcweir 	// wenn ein Name eigentlich als Bereich in die Gesamt-Formel
341cdf0e10cSrcweir 	// eingefuegt wird, bei der Einzeldarstellung aber als
342cdf0e10cSrcweir 	// single-Zellbezug interpretiert wird
343cdf0e10cSrcweir 	sal_Bool bColRowName = pCell->HasColRowName();
344cdf0e10cSrcweir 	if ( bColRowName )
345cdf0e10cSrcweir 	{
346cdf0e10cSrcweir 		// ColRowName im RPN-Code?
347cdf0e10cSrcweir 		if ( pCell->GetCode()->GetCodeLen() <= 1 )
348cdf0e10cSrcweir 		{	// ==1: einzelner ist als Parameter immer Bereich
349cdf0e10cSrcweir 			// ==0: es waere vielleicht einer, wenn..
350cdf0e10cSrcweir 			String aBraced( '(' );
351cdf0e10cSrcweir 			aBraced += rStrExp;
352cdf0e10cSrcweir 			aBraced += ')';
353cdf0e10cSrcweir 			pFCell.reset( new ScFormulaCell( pDoc, aCursorPos, aBraced ) );
354cdf0e10cSrcweir 		}
355cdf0e10cSrcweir 		else
356cdf0e10cSrcweir 			bColRowName = sal_False;
357cdf0e10cSrcweir 	}
358cdf0e10cSrcweir 
359cdf0e10cSrcweir 	sal_uInt16 nErrCode = pFCell->GetErrCode();
360cdf0e10cSrcweir 	if ( nErrCode == 0 )
361cdf0e10cSrcweir 	{
362cdf0e10cSrcweir 		SvNumberFormatter& aFormatter = *(pDoc->GetFormatTable());
363cdf0e10cSrcweir 		Color* pColor;
364cdf0e10cSrcweir 		if ( pFCell->IsValue() )
365cdf0e10cSrcweir 		{
366cdf0e10cSrcweir 			double n = pFCell->GetValue();
367cdf0e10cSrcweir 			sal_uLong nFormat = aFormatter.GetStandardFormat( n, 0,
368cdf0e10cSrcweir 							pFCell->GetFormatType(), ScGlobal::eLnge );
369cdf0e10cSrcweir 			aFormatter.GetOutputString( n, nFormat,
370cdf0e10cSrcweir 										rStrResult, &pColor );
371cdf0e10cSrcweir 		}
372cdf0e10cSrcweir 		else
373cdf0e10cSrcweir 		{
374cdf0e10cSrcweir 			String aStr;
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 			pFCell->GetString( aStr );
377cdf0e10cSrcweir 			sal_uLong nFormat = aFormatter.GetStandardFormat(
378cdf0e10cSrcweir 							pFCell->GetFormatType(), ScGlobal::eLnge);
379cdf0e10cSrcweir 			aFormatter.GetOutputString( aStr, nFormat,
380cdf0e10cSrcweir 										rStrResult, &pColor );
381cdf0e10cSrcweir 		}
382cdf0e10cSrcweir 
383cdf0e10cSrcweir 		ScRange aTestRange;
384cdf0e10cSrcweir 		if ( bColRowName || (aTestRange.Parse(rStrExp) & SCA_VALID) )
385cdf0e10cSrcweir 			rStrResult.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " ..." ));
386cdf0e10cSrcweir 			// Bereich
387cdf0e10cSrcweir 	}
388cdf0e10cSrcweir 	else
389cdf0e10cSrcweir 		rStrResult += ScGlobal::GetErrorString(nErrCode);
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 	if(!isUserMatrix() && pFCell->GetMatrixFlag())
392cdf0e10cSrcweir 	{
393cdf0e10cSrcweir 		CheckMatrix();
394cdf0e10cSrcweir 	}
395cdf0e10cSrcweir 
396cdf0e10cSrcweir 	return bResult;
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 
400cdf0e10cSrcweir 
401cdf0e10cSrcweir //	virtuelle Methoden von ScAnyRefDlg:
RefInputStart(formula::RefEdit * pEdit,formula::RefButton * pButton)402cdf0e10cSrcweir void ScFormulaDlg::RefInputStart( formula::RefEdit* pEdit, formula::RefButton* pButton )
403cdf0e10cSrcweir {
404cdf0e10cSrcweir     ::std::pair<formula::RefButton*,formula::RefEdit*> aPair = RefInputStartBefore( pEdit, pButton );
405cdf0e10cSrcweir     m_aHelper.RefInputStart( aPair.second, aPair.first);
406cdf0e10cSrcweir     RefInputStartAfter( aPair.second, aPair.first );
407cdf0e10cSrcweir }
RefInputDone(sal_Bool bForced)408cdf0e10cSrcweir void ScFormulaDlg::RefInputDone( sal_Bool bForced )
409cdf0e10cSrcweir {
410cdf0e10cSrcweir     m_aHelper.RefInputDone( bForced );
411cdf0e10cSrcweir     RefInputDoneAfter( bForced );
412cdf0e10cSrcweir }
413cdf0e10cSrcweir 
SetReference(const ScRange & rRef,ScDocument * pRefDoc)414cdf0e10cSrcweir void ScFormulaDlg::SetReference( const ScRange& rRef, ScDocument* pRefDoc )
415cdf0e10cSrcweir {
416cdf0e10cSrcweir     const IFunctionDescription* pFunc = getCurrentFunctionDescription();
417cdf0e10cSrcweir 	if ( pFunc && pFunc->getSuppressedArgumentCount() > 0 )
418cdf0e10cSrcweir 	{
419cdf0e10cSrcweir         Selection theSel;
420cdf0e10cSrcweir 		sal_Bool bRefNull = UpdateParaWin(theSel);
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 		if ( rRef.aStart != rRef.aEnd && bRefNull )
423cdf0e10cSrcweir 		{
424cdf0e10cSrcweir 			RefInputStart(GetActiveEdit());
425cdf0e10cSrcweir 		}
426cdf0e10cSrcweir 
427cdf0e10cSrcweir         String		aRefStr;
428cdf0e10cSrcweir 		sal_Bool bOtherDoc = ( pRefDoc != pDoc && pRefDoc->GetDocumentShell()->HasName() );
429cdf0e10cSrcweir 		if ( bOtherDoc )
430cdf0e10cSrcweir 		{
431cdf0e10cSrcweir 			//	Referenz auf anderes Dokument - wie inputhdl.cxx
432cdf0e10cSrcweir 
433cdf0e10cSrcweir 			DBG_ASSERT(rRef.aStart.Tab()==rRef.aEnd.Tab(), "nStartTab!=nEndTab");
434cdf0e10cSrcweir 
435cdf0e10cSrcweir 			String aTmp;
436cdf0e10cSrcweir 			rRef.Format( aTmp, SCA_VALID|SCA_TAB_3D, pRefDoc );		// immer 3d
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 			SfxObjectShell* pObjSh = pRefDoc->GetDocumentShell();
439cdf0e10cSrcweir 
440cdf0e10cSrcweir             // #i75893# convert escaped URL of the document to something user friendly
441cdf0e10cSrcweir //           String aFileName = pObjSh->GetMedium()->GetName();
442cdf0e10cSrcweir             String aFileName = pObjSh->GetMedium()->GetURLObject().GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
443cdf0e10cSrcweir 
444cdf0e10cSrcweir 			aRefStr = '\'';
445cdf0e10cSrcweir 			aRefStr += aFileName;
446cdf0e10cSrcweir 			aRefStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( "'#" ));
447cdf0e10cSrcweir 			aRefStr += aTmp;
448cdf0e10cSrcweir 		}
449cdf0e10cSrcweir 		else
450cdf0e10cSrcweir 		{
451cdf0e10cSrcweir 			sal_uInt16 nFmt = ( rRef.aStart.Tab() == aCursorPos.Tab() )
452cdf0e10cSrcweir 								? SCA_VALID
453cdf0e10cSrcweir 								: SCA_VALID | SCA_TAB_3D;
454cdf0e10cSrcweir 			rRef.Format( aRefStr, nFmt, pRefDoc, pRefDoc->GetAddressConvention() );
455cdf0e10cSrcweir 		}
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 		UpdateParaWin(theSel,aRefStr);
458cdf0e10cSrcweir 	}
459cdf0e10cSrcweir }
460cdf0e10cSrcweir 
IsRefInputMode() const461cdf0e10cSrcweir sal_Bool ScFormulaDlg::IsRefInputMode() const
462cdf0e10cSrcweir {
463cdf0e10cSrcweir     const IFunctionDescription*	pDesc = getCurrentFunctionDescription();
464cdf0e10cSrcweir 	sal_Bool bRef = (pDesc && (pDesc->getSuppressedArgumentCount() > 0)) && (pDoc!=NULL);
465cdf0e10cSrcweir 	return bRef;
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
IsDocAllowed(SfxObjectShell * pDocSh) const468cdf0e10cSrcweir sal_Bool ScFormulaDlg::IsDocAllowed(SfxObjectShell* pDocSh) const
469cdf0e10cSrcweir {
470cdf0e10cSrcweir 	//	not allowed: different from this doc, and no name
471cdf0e10cSrcweir 	//	pDocSh is always a ScDocShell
472cdf0e10cSrcweir 	if ( pDocSh && ((ScDocShell*)pDocSh)->GetDocument() != pDoc && !pDocSh->HasName() )
473cdf0e10cSrcweir 		return sal_False;
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	return sal_True;		// everything else is allowed
476cdf0e10cSrcweir }
477cdf0e10cSrcweir 
SetActive()478cdf0e10cSrcweir void ScFormulaDlg::SetActive()
479cdf0e10cSrcweir {
480cdf0e10cSrcweir     const IFunctionDescription* pFunc = getCurrentFunctionDescription();
481cdf0e10cSrcweir 	if ( pFunc && pFunc->getSuppressedArgumentCount() > 0 )
482cdf0e10cSrcweir 	{
483cdf0e10cSrcweir 		RefInputDone();
484cdf0e10cSrcweir         SetEdSelection();
485cdf0e10cSrcweir 	}
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
SaveLRUEntry(const ScFuncDesc * pFuncDescP)488cdf0e10cSrcweir void ScFormulaDlg::SaveLRUEntry(const ScFuncDesc* pFuncDescP)
489cdf0e10cSrcweir {
490cdf0e10cSrcweir 	if (pFuncDescP && pFuncDescP->nFIndex!=0)
491cdf0e10cSrcweir 	{
492cdf0e10cSrcweir 		ScModule* pScMod = SC_MOD();
493cdf0e10cSrcweir 		pScMod->InsertEntryToLRUList(pFuncDescP->nFIndex);
494cdf0e10cSrcweir 	}
495cdf0e10cSrcweir }
496cdf0e10cSrcweir 
doClose(sal_Bool)497cdf0e10cSrcweir void ScFormulaDlg::doClose(sal_Bool /*_bOk*/)
498cdf0e10cSrcweir {
499cdf0e10cSrcweir     m_aHelper.DoClose( ScFormulaDlgWrapper::GetChildWindowId() );
500cdf0e10cSrcweir }
insertEntryToLRUList(const formula::IFunctionDescription * _pDesc)501cdf0e10cSrcweir void ScFormulaDlg::insertEntryToLRUList(const formula::IFunctionDescription*	_pDesc)
502cdf0e10cSrcweir {
503cdf0e10cSrcweir     const ScFuncDesc* pDesc = dynamic_cast<const ScFuncDesc*>(_pDesc);
504cdf0e10cSrcweir     SaveLRUEntry(pDesc);
505cdf0e10cSrcweir }
showReference(const String & _sFormula)506cdf0e10cSrcweir void ScFormulaDlg::showReference(const String& _sFormula)
507cdf0e10cSrcweir {
508cdf0e10cSrcweir     ShowReference(_sFormula);
509cdf0e10cSrcweir }
ShowReference(const String & _sFormula)510cdf0e10cSrcweir void ScFormulaDlg::ShowReference(const String& _sFormula)
511cdf0e10cSrcweir {
512cdf0e10cSrcweir     m_aHelper.ShowReference(_sFormula);
513cdf0e10cSrcweir }
HideReference(sal_Bool bDoneRefMode)514cdf0e10cSrcweir void ScFormulaDlg::HideReference( sal_Bool bDoneRefMode )
515cdf0e10cSrcweir {
516cdf0e10cSrcweir     m_aHelper.HideReference(bDoneRefMode);
517cdf0e10cSrcweir }
ViewShellChanged(ScTabViewShell * pScViewShell)518cdf0e10cSrcweir void ScFormulaDlg::ViewShellChanged( ScTabViewShell* pScViewShell )
519cdf0e10cSrcweir {
520cdf0e10cSrcweir     m_aHelper.ViewShellChanged( pScViewShell );
521cdf0e10cSrcweir }
AddRefEntry()522cdf0e10cSrcweir void ScFormulaDlg::AddRefEntry( )
523cdf0e10cSrcweir {
524cdf0e10cSrcweir 
525cdf0e10cSrcweir }
IsTableLocked() const526cdf0e10cSrcweir sal_Bool ScFormulaDlg::IsTableLocked( ) const
527cdf0e10cSrcweir {
528cdf0e10cSrcweir     // per Default kann bei Referenzeingabe auch die Tabelle umgeschaltet werden
529cdf0e10cSrcweir     return sal_False;
530cdf0e10cSrcweir }
ToggleCollapsed(formula::RefEdit * pEdit,formula::RefButton * pButton)531cdf0e10cSrcweir void ScFormulaDlg::ToggleCollapsed( formula::RefEdit* pEdit, formula::RefButton* pButton)
532cdf0e10cSrcweir {
533cdf0e10cSrcweir     m_aHelper.ToggleCollapsed(pEdit,pButton);
534cdf0e10cSrcweir }
ReleaseFocus(formula::RefEdit * pEdit,formula::RefButton * pButton)535cdf0e10cSrcweir void ScFormulaDlg::ReleaseFocus( formula::RefEdit* pEdit, formula::RefButton* pButton)
536cdf0e10cSrcweir {
537cdf0e10cSrcweir     m_aHelper.ReleaseFocus(pEdit,pButton);
538cdf0e10cSrcweir }
dispatch(sal_Bool _bOK,sal_Bool _bMartixChecked)539cdf0e10cSrcweir void ScFormulaDlg::dispatch(sal_Bool _bOK,sal_Bool _bMartixChecked)
540cdf0e10cSrcweir {
541cdf0e10cSrcweir     SfxBoolItem	  aRetItem( SID_DLG_RETOK, _bOK );
542cdf0e10cSrcweir 	SfxBoolItem	  aMatItem( SID_DLG_MATRIX, _bMartixChecked );
543cdf0e10cSrcweir 	SfxStringItem aStrItem( SCITEM_STRING, getCurrentFormula() );
544cdf0e10cSrcweir 
545cdf0e10cSrcweir 	// Wenn durch Dokument-Umschalterei die Eingabezeile weg war/ist,
546cdf0e10cSrcweir 	// ist der String leer. Dann nicht die alte Formel loeschen.
547cdf0e10cSrcweir 	if ( !aStrItem.GetValue().Len() )
548cdf0e10cSrcweir 		aRetItem.SetValue( sal_False );		// sal_False = Cancel
549cdf0e10cSrcweir 
550cdf0e10cSrcweir 	m_aHelper.SetDispatcherLock( sal_False ); // Modal-Modus ausschalten
551cdf0e10cSrcweir 
552cdf0e10cSrcweir     clear();
553cdf0e10cSrcweir 
554cdf0e10cSrcweir 	GetBindings().GetDispatcher()->Execute( SID_INS_FUNCTION,
555cdf0e10cSrcweir 							  SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD,
556cdf0e10cSrcweir 							  &aRetItem, &aStrItem, &aMatItem, 0L );
557cdf0e10cSrcweir }
setDispatcherLock(sal_Bool bLock)558cdf0e10cSrcweir void ScFormulaDlg::setDispatcherLock( sal_Bool bLock )
559cdf0e10cSrcweir {
560cdf0e10cSrcweir     m_aHelper.SetDispatcherLock( bLock );
561cdf0e10cSrcweir }
setReferenceInput(const formula::FormEditData * _pData)562cdf0e10cSrcweir void ScFormulaDlg::setReferenceInput(const formula::FormEditData* _pData)
563cdf0e10cSrcweir {
564cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
565cdf0e10cSrcweir     ScFormEditData* pData = const_cast<ScFormEditData*>(dynamic_cast<const ScFormEditData*>(_pData));
566cdf0e10cSrcweir     pScMod->SetRefInputHdl(pData->GetInputHandler());
567cdf0e10cSrcweir }
deleteFormData()568cdf0e10cSrcweir void ScFormulaDlg::deleteFormData()
569cdf0e10cSrcweir {
570cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
571cdf0e10cSrcweir     pScMod->ClearFormEditData();		// pData wird ungueltig!
572cdf0e10cSrcweir }
clear()573cdf0e10cSrcweir void ScFormulaDlg::clear()
574cdf0e10cSrcweir {
575cdf0e10cSrcweir     pDoc = NULL;
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 	//Referenz Inputhandler zuruecksetzen
578cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
579cdf0e10cSrcweir 	pScMod->SetRefInputHdl(NULL);
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 	// Enable() der Eingabezeile erzwingen:
582cdf0e10cSrcweir     ScTabViewShell* pScViewShell = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
583cdf0e10cSrcweir 	if ( pScViewShell )
584cdf0e10cSrcweir 		pScViewShell->UpdateInputHandler();
585cdf0e10cSrcweir }
switchBack()586cdf0e10cSrcweir void ScFormulaDlg::switchBack()
587cdf0e10cSrcweir {
588cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
589cdf0e10cSrcweir     // auf das Dokument zurueckschalten
590cdf0e10cSrcweir 	// (noetig, weil ein fremdes oben sein kann - #34222#)
591cdf0e10cSrcweir 	ScInputHandler* pHdl = pScMod->GetInputHdl();
592cdf0e10cSrcweir 	if ( pHdl )
593cdf0e10cSrcweir 	{
594cdf0e10cSrcweir 		pHdl->ViewShellGone(NULL);	// -> aktive View neu holen
595cdf0e10cSrcweir 		pHdl->ShowRefFrame();
596cdf0e10cSrcweir 	}
597cdf0e10cSrcweir 
598cdf0e10cSrcweir 	// aktuelle Tabelle ggF. restaurieren (wg. Maus-RefInput)
599cdf0e10cSrcweir 	ScTabViewShell* pScViewShell = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
600cdf0e10cSrcweir 	if ( pScViewShell )
601cdf0e10cSrcweir 	{
602cdf0e10cSrcweir 		ScViewData* pVD=pScViewShell->GetViewData();
603cdf0e10cSrcweir 		SCTAB nExecTab = aCursorPos.Tab();
604cdf0e10cSrcweir 		if ( nExecTab != pVD->GetTabNo() )
605cdf0e10cSrcweir 			pScViewShell->SetTabNo( nExecTab );
606cdf0e10cSrcweir 
607cdf0e10cSrcweir 		SCROW nRow=aCursorPos.Row();
608cdf0e10cSrcweir 		SCCOL nCol=aCursorPos.Col();
609cdf0e10cSrcweir 
610cdf0e10cSrcweir 		if(pVD->GetCurX()!=nCol || pVD->GetCurY()!=nRow)
611cdf0e10cSrcweir 			pScViewShell->SetCursor(nCol,nRow);
612cdf0e10cSrcweir     }
613cdf0e10cSrcweir }
getFormEditData() const614cdf0e10cSrcweir formula::FormEditData* ScFormulaDlg::getFormEditData() const
615cdf0e10cSrcweir {
616cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
617cdf0e10cSrcweir 	return pScMod->GetFormEditData();
618cdf0e10cSrcweir }
setCurrentFormula(const String & _sReplacement)619cdf0e10cSrcweir void ScFormulaDlg::setCurrentFormula(const String& _sReplacement)
620cdf0e10cSrcweir {
621cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
622cdf0e10cSrcweir     pScMod->InputReplaceSelection(_sReplacement);
623cdf0e10cSrcweir }
setSelection(xub_StrLen _nStart,xub_StrLen _nEnd)624cdf0e10cSrcweir void ScFormulaDlg::setSelection(xub_StrLen _nStart,xub_StrLen _nEnd)
625cdf0e10cSrcweir {
626cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
627cdf0e10cSrcweir     pScMod->InputSetSelection( _nStart, _nEnd );
628cdf0e10cSrcweir }
getSelection(xub_StrLen & _nStart,xub_StrLen & _nEnd) const629cdf0e10cSrcweir void ScFormulaDlg::getSelection(xub_StrLen& _nStart,xub_StrLen& _nEnd) const
630cdf0e10cSrcweir {
631cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
632cdf0e10cSrcweir     pScMod->InputGetSelection( _nStart, _nEnd );
633cdf0e10cSrcweir }
getCurrentFormula() const634cdf0e10cSrcweir String ScFormulaDlg::getCurrentFormula() const
635cdf0e10cSrcweir {
636cdf0e10cSrcweir     ScModule* pScMod = SC_MOD();
637cdf0e10cSrcweir     return pScMod->InputGetFormulaStr();
638cdf0e10cSrcweir }
getFunctionManager()639cdf0e10cSrcweir formula::IFunctionManager* ScFormulaDlg::getFunctionManager()
640cdf0e10cSrcweir {
641cdf0e10cSrcweir     return ScGlobal::GetStarCalcFunctionMgr();
642cdf0e10cSrcweir }
getFormulaParser() const643cdf0e10cSrcweir uno::Reference< sheet::XFormulaParser> ScFormulaDlg::getFormulaParser() const
644cdf0e10cSrcweir {
645cdf0e10cSrcweir     return m_xParser;
646cdf0e10cSrcweir }
getFormulaOpCodeMapper() const647cdf0e10cSrcweir uno::Reference< sheet::XFormulaOpCodeMapper> ScFormulaDlg::getFormulaOpCodeMapper() const
648cdf0e10cSrcweir {
649cdf0e10cSrcweir     return m_xOpCodeMapper;
650cdf0e10cSrcweir }
651cdf0e10cSrcweir 
getReferencePosition() const652cdf0e10cSrcweir table::CellAddress ScFormulaDlg::getReferencePosition() const
653cdf0e10cSrcweir {
654cdf0e10cSrcweir     return table::CellAddress(aCursorPos.Tab(),aCursorPos.Col(),aCursorPos.Row());
655cdf0e10cSrcweir }
656cdf0e10cSrcweir 
convertToTokenArray(const uno::Sequence<sheet::FormulaToken> & _aTokenList)657cdf0e10cSrcweir ::std::auto_ptr<formula::FormulaTokenArray> ScFormulaDlg::convertToTokenArray(const uno::Sequence< sheet::FormulaToken >& _aTokenList)
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     ::std::auto_ptr<formula::FormulaTokenArray> pArray(new ScTokenArray());
660cdf0e10cSrcweir     pArray->Fill( _aTokenList, pDoc->GetExternalRefManager());
661cdf0e10cSrcweir     return pArray;
662cdf0e10cSrcweir }
663cdf0e10cSrcweir 
664