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