merge the formfield patch from ooo-build
[ooovba.git] / sw / source / ui / ribbar / inputwin.cxx
blobcd98771445d3b341310831fbd8e411d3885f2048
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inputwin.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <tools/gen.hxx>
36 #include <sfx2/imgmgr.hxx>
37 #include <sfx2/viewfrm.hxx>
38 #include <sfx2/dispatch.hxx>
39 #include <svx/ruler.hxx>
40 #include <svtools/zforlist.hxx>
41 #include <svtools/stritem.hxx>
43 #include "swtypes.hxx"
44 #include "cmdid.h"
45 #include "swmodule.hxx"
46 #include "wrtsh.hxx"
47 #include "view.hxx"
48 #include "calc.hxx"
49 #include "inputwin.hxx"
50 #include "fldbas.hxx"
51 #include "fldmgr.hxx"
52 #include "frmfmt.hxx"
53 #include "cellatr.hxx"
54 #include "edtwin.hxx"
55 #include "helpid.h"
57 // nur fuers UpdateRange - Box in dem der gestackte Cursor sthet loeschen
58 #include "pam.hxx"
60 #include "swundo.hxx"
61 #include "ribbar.hrc"
62 #include "inputwin.hrc"
64 #include <IDocumentContentOperations.hxx>
66 SFX_IMPL_POS_CHILDWINDOW( SwInputChild, FN_EDIT_FORMULA, SFX_OBJECTBAR_OBJECT )
68 //==================================================================
70 SwInputWindow::SwInputWindow( Window* pParent, SfxBindings* pBind )
71 : ToolBox( pParent , SW_RES( RID_TBX_FORMULA )),
72 aPos( this, SW_RES(ED_POS)),
73 aEdit( this, WB_3DLOOK|WB_TABSTOP|WB_BORDER|WB_NOHIDESELECTION),
74 aPopMenu( SW_RES(MN_CALC_POPUP)),
75 pMgr(0),
76 pWrtShell(0),
77 pView(0),
78 pBindings(pBind),
79 aAktTableName(aEmptyStr)
81 bFirst = bDoesUndo = TRUE;
82 bActive = bIsTable = bDelSel = bResetUndo = bCallUndo = FALSE;
84 FreeResource();
86 SfxImageManager* pManager = SfxImageManager::GetImageManager( SW_MOD() );
87 pManager->RegisterToolBox(this);
89 pView = ::GetActiveView();
90 pWrtShell = pView ? pView->GetWrtShellPtr() : 0;
92 InsertWindow( ED_POS, &aPos, 0, 0);
93 InsertSeparator ( 1 );
94 InsertSeparator ();
95 InsertWindow( ED_FORMULA, &aEdit);
96 SetHelpId(ED_FORMULA, HID_EDIT_FORMULA);
98 BOOL bDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
99 SetItemImage( FN_FORMULA_CALC, pManager->GetImage(FN_FORMULA_CALC, bDark ));
100 SetItemImage( FN_FORMULA_CANCEL, pManager->GetImage(FN_FORMULA_CANCEL, bDark ));
101 SetItemImage( FN_FORMULA_APPLY, pManager->GetImage(FN_FORMULA_APPLY, bDark ));
103 SetItemBits( FN_FORMULA_CALC, GetItemBits( FN_FORMULA_CALC ) | TIB_DROPDOWNONLY );
104 SetDropdownClickHdl( LINK( this, SwInputWindow, DropdownClickHdl ));
106 Size aSizeTbx = CalcWindowSizePixel();
107 Size aSize = GetSizePixel();
108 aSize.Height() = aSizeTbx.Height();
109 SetSizePixel( aSize );
110 Size aPosSize = aPos.GetSizePixel();
111 Size aEditSize = aEdit.GetSizePixel();
112 aPosSize.Height() = aEditSize.Height() = GetItemRect(FN_FORMULA_CALC).GetHeight() - 2;
114 Point aPosPos = aPos.GetPosPixel();
115 Point aEditPos= aEdit.GetPosPixel();
116 aPosPos.Y() = aEditPos.Y() = GetItemRect( FN_FORMULA_CALC ).TopLeft().Y() + 1;
117 aPos.SetPosSizePixel( aPosPos, aPosSize );
118 aEdit.SetPosSizePixel( aEditPos, aEditSize );
120 aPopMenu.SetSelectHdl(LINK( this, SwInputWindow, MenuHdl ));
123 //==================================================================
125 __EXPORT SwInputWindow::~SwInputWindow()
127 SfxImageManager::GetImageManager( SW_MOD() )->ReleaseToolBox(this);
129 //Lineale aufwecken
130 if(pView)
132 pView->GetHLineal().SetActive( TRUE );
133 pView->GetVLineal().SetActive( TRUE );
135 if ( pMgr )
136 delete pMgr;
137 if(pWrtShell)
138 pWrtShell->EndSelTblCells();
140 if( bResetUndo )
142 DelBoxCntnt();
143 pWrtShell->DoUndo( bDoesUndo );
144 if(bCallUndo)
145 pWrtShell->Undo();
146 SwEditShell::SetUndoActionCount( nActionCnt );
150 //==================================================================
152 void SwInputWindow::DataChanged( const DataChangedEvent& rDCEvt )
154 if ( rDCEvt.GetType() == DATACHANGED_SETTINGS && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
156 // update item images
157 SwModule *pMod = SW_MOD();
158 SfxImageManager *pImgMgr = SfxImageManager::GetImageManager( pMod );
159 //!! Don't use display-background to check for IsDark !!
160 BOOL bDark = GetSettings().GetStyleSettings().GetFaceColor().IsDark();
162 SetItemImage( FN_FORMULA_CALC, pImgMgr->GetImage(FN_FORMULA_CALC, bDark ));
163 SetItemImage( FN_FORMULA_CANCEL, pImgMgr->GetImage(FN_FORMULA_CANCEL, bDark ));
164 SetItemImage( FN_FORMULA_APPLY, pImgMgr->GetImage(FN_FORMULA_APPLY, bDark ));
167 ToolBox::DataChanged( rDCEvt );
170 //==================================================================
172 void __EXPORT SwInputWindow::Resize()
174 ToolBox::Resize();
176 long nWidth = GetSizePixel().Width();
177 long nLeft = aEdit.GetPosPixel().X();
178 Size aEditSize = aEdit.GetSizePixel();
180 aEditSize.Width() = Max( ((long)(nWidth - nLeft - 5)), (long)0 );
181 aEdit.SetSizePixel( aEditSize );
182 aEdit.Invalidate();
185 //==================================================================
187 void SwInputWindow::ShowWin()
189 bIsTable = FALSE;
190 //Lineale anhalten
191 if(pView)
193 pView->GetHLineal().SetActive( FALSE );
194 pView->GetVLineal().SetActive( FALSE );
196 DBG_ASSERT(pWrtShell, "Keine WrtShell!");
197 // Cursor in Tabelle
198 bIsTable = pWrtShell->IsCrsrInTbl() ? TRUE : FALSE;
200 if( bFirst )
201 pWrtShell->SelTblCells( LINK( this, SwInputWindow,
202 SelTblCellsNotify) );
203 if( bIsTable )
205 const String& rPos = pWrtShell->GetBoxNms();
206 USHORT nPos = 0;
207 short nSrch = -1;
208 while( (nPos = rPos.Search( ':',nPos + 1 ) ) != STRING_NOTFOUND )
209 nSrch = (short) nPos;
210 aPos.SetText( rPos.Copy( ++nSrch ) );
211 aAktTableName = pWrtShell->GetTableFmt()->GetName();
213 else
214 aPos.SetText(SW_RESSTR(STR_TBL_FORMULA));
216 // Aktuelles Feld bearbeiten
217 ASSERT(pMgr == 0, FieldManager nicht geloescht.);
218 pMgr = new SwFldMgr;
220 // JP 13.01.97: Formel soll immer mit einem "=" beginnen, hier
221 // also setzen
222 String sEdit( '=' );
223 if( pMgr->GetCurFld() && TYP_FORMELFLD == pMgr->GetCurTypeId() )
225 sEdit += pMgr->GetCurFldPar2();
227 else if( bFirst )
229 if( bIsTable )
231 bResetUndo = TRUE;
232 nActionCnt = SwEditShell::GetUndoActionCount();
233 SwEditShell::SetUndoActionCount( nActionCnt + 1 );
235 bDoesUndo = pWrtShell->DoesUndo();
236 if( !bDoesUndo )
237 pWrtShell->DoUndo( TRUE );
239 if( !pWrtShell->SwCrsrShell::HasSelection() )
241 pWrtShell->MoveSection( fnSectionCurr, fnSectionStart );
242 pWrtShell->SetMark();
243 pWrtShell->MoveSection( fnSectionCurr, fnSectionEnd );
245 if( pWrtShell->SwCrsrShell::HasSelection() )
247 pWrtShell->StartUndo( UNDO_DELETE );
248 pWrtShell->Delete();
249 if( 0 != pWrtShell->EndUndo( UNDO_DELETE ))
250 bCallUndo = TRUE;
252 pWrtShell->DoUndo( FALSE );
254 SfxItemSet aSet( pWrtShell->GetAttrPool(), RES_BOXATR_FORMULA, RES_BOXATR_FORMULA );
255 if( pWrtShell->GetTblBoxFormulaAttrs( aSet ))
256 sEdit += ((SwTblBoxFormula&)aSet.Get( RES_BOXATR_FORMULA )).GetFormula();
260 if( bFirst )
262 // WrtShell Flags richtig setzen
263 pWrtShell->SttSelect();
264 pWrtShell->EndSelect();
267 bFirst = FALSE;
269 aEdit.SetModifyHdl( LINK( this, SwInputWindow, ModifyHdl ));
271 aEdit.SetText( sEdit );
272 aEdit.SetSelection( Selection( sEdit.Len(), sEdit.Len() ) );
273 sOldFml = sEdit;
275 aEdit.Invalidate();
276 aEdit.Update();
277 aEdit.GrabFocus();
278 // UserInterface fuer die Eingabe abklemmen
280 pView->GetEditWin().LockKeyInput(TRUE);
281 pView->GetViewFrame()->GetDispatcher()->Lock(TRUE);
282 pWrtShell->Push();
284 ToolBox::Show();
286 //==================================================================
288 IMPL_LINK( SwInputWindow, MenuHdl, Menu *, pMenu )
290 static const char * __READONLY_DATA aStrArr[] = {
291 sCalc_Phd,
292 sCalc_Sqrt,
293 sCalc_Or,
294 sCalc_Xor,
295 sCalc_And,
296 sCalc_Not,
297 sCalc_Eq,
298 sCalc_Neq,
299 sCalc_Leq,
300 sCalc_Geq,
301 sCalc_L,
302 sCalc_G,
303 sCalc_Sum,
304 sCalc_Mean,
305 sCalc_Min,
306 sCalc_Max,
307 sCalc_Sin,
308 sCalc_Cos,
309 sCalc_Tan,
310 sCalc_Asin,
311 sCalc_Acos,
312 sCalc_Atan,
313 sCalc_Pow,
314 "|",
315 sCalc_Round
318 USHORT nId = pMenu->GetCurItemId();
319 if ( nId <= MN_CALC_ROUND )
321 String aTmp( String::CreateFromAscii(aStrArr[nId - 1]) );
322 aTmp += ' ';
323 aEdit.ReplaceSelected( aTmp );
325 return 0;
328 IMPL_LINK( SwInputWindow, DropdownClickHdl, ToolBox*, EMPTYARG )
330 USHORT nCurID = GetCurItemId();
331 EndSelection(); // setzt CurItemId zurueck !
332 switch ( nCurID )
334 case FN_FORMULA_CALC :
336 aPopMenu.Execute( this, GetItemRect( FN_FORMULA_CALC ), POPUPMENU_NOMOUSEUPCLOSE );
337 break;
338 default:
339 break;
343 return TRUE;
346 //==================================================================
349 void __EXPORT SwInputWindow::Click( )
351 USHORT nCurID = GetCurItemId();
352 EndSelection(); // setzt CurItemId zurueck !
353 switch ( nCurID )
355 case FN_FORMULA_CANCEL:
357 CancelFormula();
359 break;
360 case FN_FORMULA_APPLY:
362 ApplyFormula();
364 break;
368 //==================================================================
370 void SwInputWindow::ApplyFormula()
372 pView->GetViewFrame()->GetDispatcher()->Lock(FALSE);
373 pView->GetEditWin().LockKeyInput(FALSE);
374 if( bResetUndo )
376 DelBoxCntnt();
377 pWrtShell->DoUndo( bDoesUndo );
378 SwEditShell::SetUndoActionCount( nActionCnt );
379 if( bCallUndo )
380 pWrtShell->Undo();
381 bResetUndo = FALSE;
383 pWrtShell->Pop( FALSE );
385 // JP 13.01.97: Formel soll immer mit einem "=" beginnen, hier
386 // also wieder entfernen
387 String sEdit( aEdit.GetText() );
388 sEdit.EraseLeadingChars().EraseTrailingChars();
389 if( sEdit.Len() && '=' == sEdit.GetChar( 0 ) )
390 sEdit.Erase( 0, 1 );
391 SfxStringItem aParam(FN_EDIT_FORMULA, sEdit);
393 pWrtShell->EndSelTblCells();
394 pView->GetEditWin().GrabFocus();
395 const SfxPoolItem* aArgs[2];
396 aArgs[0] = &aParam;
397 aArgs[1] = 0;
398 pView->GetViewFrame()->GetBindings().Execute( FN_EDIT_FORMULA, aArgs, 0, SFX_CALLMODE_ASYNCHRON );
401 //==================================================================
403 void SwInputWindow::CancelFormula()
405 if(pView)
407 pView->GetViewFrame()->GetDispatcher()->Lock( FALSE );
408 pView->GetEditWin().LockKeyInput(FALSE);
409 if( bResetUndo )
411 DelBoxCntnt();
412 pWrtShell->DoUndo( bDoesUndo );
413 SwEditShell::SetUndoActionCount( nActionCnt );
414 if( bCallUndo )
415 pWrtShell->Undo();
416 bResetUndo = FALSE;
418 pWrtShell->Pop( FALSE );
420 if( bDelSel )
421 pWrtShell->EnterStdMode();
423 pWrtShell->EndSelTblCells();
425 pView->GetEditWin().GrabFocus();
427 pView->GetViewFrame()->GetDispatcher()->Execute( FN_EDIT_FORMULA, SFX_CALLMODE_ASYNCHRON);
429 //==================================================================
431 const xub_Unicode CH_LRE = 0x202a;
432 const xub_Unicode CH_PDF = 0x202c;
434 IMPL_LINK( SwInputWindow, SelTblCellsNotify, SwWrtShell *, pCaller )
436 if(bIsTable)
438 SwFrmFmt* pTblFmt = pCaller->GetTableFmt();
439 String sBoxNms( pCaller->GetBoxNms() );
440 String sTblNm;
441 if( pTblFmt && aAktTableName != pTblFmt->GetName() )
442 sTblNm = pTblFmt->GetName();
444 aEdit.UpdateRange( sBoxNms, sTblNm );
446 String sNew;
447 sNew += CH_LRE;
448 sNew += aEdit.GetText();
449 sNew += CH_PDF;
451 if( sNew != sOldFml )
453 // Die WrtShell ist in der Tabellen Selektion
454 // dann die Tabellen Selektion wieder aufheben, sonst steht der
455 // Cursor "im Wald" und das LiveUpdate funktioniert nicht!
456 pWrtShell->StartAllAction();
458 SwPaM aPam( *pWrtShell->GetStkCrsr()->GetPoint() );
459 aPam.Move( fnMoveBackward, fnGoSection );
460 aPam.SetMark();
461 aPam.Move( fnMoveForward, fnGoSection );
463 IDocumentContentOperations* pIDCO = pWrtShell->getIDocumentContentOperations();
464 pIDCO->DeleteRange( aPam );
465 pIDCO->InsertString( aPam, sNew );
466 pWrtShell->EndAllAction();
467 sOldFml = sNew;
470 else
471 aEdit.GrabFocus();
472 return 0;
476 void SwInputWindow::SetFormula( const String& rFormula, BOOL bDelFlag )
478 String sEdit( '=' );
479 if( rFormula.Len() )
481 if( '=' == rFormula.GetChar( 0 ) )
482 sEdit = rFormula;
483 else
484 sEdit += rFormula;
486 aEdit.SetText( sEdit );
487 aEdit.SetSelection( Selection( sEdit.Len(), sEdit.Len() ) );
488 aEdit.Invalidate();
489 bDelSel = bDelFlag;
492 IMPL_LINK( SwInputWindow, ModifyHdl, InputEdit*, EMPTYARG )
494 if( bIsTable && bResetUndo )
496 pWrtShell->StartAllAction();
497 DelBoxCntnt();
498 String sNew;
499 sNew += CH_LRE;
500 sNew += aEdit.GetText();
501 sNew += CH_PDF;
502 pWrtShell->SwEditShell::Insert2( sNew );
503 pWrtShell->EndAllAction();
504 sOldFml = sNew;
506 return 0;
510 void SwInputWindow::DelBoxCntnt()
512 if( bIsTable )
514 pWrtShell->StartAllAction();
515 pWrtShell->ClearMark();
516 pWrtShell->Pop( FALSE );
517 pWrtShell->Push();
518 pWrtShell->MoveSection( fnSectionCurr, fnSectionStart );
519 pWrtShell->SetMark();
520 pWrtShell->MoveSection( fnSectionCurr, fnSectionEnd );
521 pWrtShell->SwEditShell::Delete();
522 pWrtShell->EndAllAction();
526 //==================================================================
528 void __EXPORT InputEdit::KeyInput(const KeyEvent& rEvent)
530 const KeyCode aCode = rEvent.GetKeyCode();
531 if(aCode == KEY_RETURN || aCode == KEY_F2 )
532 ((SwInputWindow*)GetParent())->ApplyFormula();
533 else if(aCode == KEY_ESCAPE )
534 ((SwInputWindow*)GetParent())->CancelFormula();
535 else
536 Edit::KeyInput(rEvent);
539 //==================================================================
541 void __EXPORT InputEdit::UpdateRange(const String& rBoxes,
542 const String& rName )
544 if( !rBoxes.Len() )
546 GrabFocus();
547 return;
549 const sal_Unicode cOpen = '<', cClose = '>',
550 cOpenBracket = '(';
551 String aPrefix = rName;
552 if(rName.Len())
553 aPrefix += '.';
554 String aBoxes = aPrefix;
555 aBoxes += rBoxes;
556 Selection aSelection(GetSelection());
557 USHORT nSel = (USHORT) aSelection.Len();
558 //OS: mit dem folgenden Ausdruck wird sichergestellt, dass im overwrite-Modus
559 //die selektierte schliessende Klammer nicht geloescht wird
560 if( nSel && ( nSel > 1 ||
561 GetText().GetChar( (USHORT)aSelection.Min() ) != cClose ) )
562 Cut();
563 else
564 aSelection.Max() = aSelection.Min();
565 String aActText(GetText());
566 const USHORT nLen = aActText.Len();
567 if( !nLen )
569 String aStr(cOpen);
570 aStr += aBoxes;
571 aStr += cClose;
572 SetText(aStr);
573 USHORT nPos = aStr.Search( cClose );
574 ASSERT(nPos < aStr.Len(), Delimiter nicht gefunden.);
575 ++nPos;
576 SetSelection( Selection( nPos, nPos ));
578 else
580 BOOL bFound = FALSE;
581 sal_Unicode cCh;
582 USHORT nPos, nEndPos = 0, nStartPos = (USHORT) aSelection.Min();
583 if( nStartPos-- )
585 do {
586 if( cOpen == (cCh = aActText.GetChar( nStartPos ) ) ||
587 cOpenBracket == cCh )
589 bFound = cCh == cOpen;
590 break;
592 } while( nStartPos-- > 0 );
594 if( bFound )
596 bFound = FALSE;
597 nEndPos = nStartPos;
598 while( nEndPos < nLen )
600 if( cClose == (cCh = aActText.GetChar( nEndPos )) /*||
601 cCh == cCloseBracket*/ )
603 bFound = TRUE;
604 break;
606 ++nEndPos;
608 // nur wenn akt. Pos im Breich oder direkt dahinter liegt
609 if( bFound && !( nStartPos < (USHORT)aSelection.Max() &&
610 (USHORT)aSelection.Max() <= nEndPos + 1 ))
611 bFound = FALSE;
613 if( bFound )
615 nPos = ++nStartPos + 1; // wir wollen dahinter
616 aActText.Erase( nStartPos, nEndPos - nStartPos );
617 aActText.Insert( aBoxes, nStartPos );
618 nPos = nPos + aBoxes.Len();
620 else
622 String aTmp( (char)cOpen );
623 aTmp += aBoxes;
624 aTmp += (char)cClose;
625 nPos = (USHORT)aSelection.Min();
626 aActText.Insert( aTmp, nPos );
627 nPos = nPos + aTmp.Len();
629 if( GetText() != aActText )
631 SetText( aActText );
632 SetSelection( Selection( nPos, nPos ) );
633 // GetModifyHdl().Call( this );
636 GrabFocus();
639 //==================================================================
642 SwInputChild::SwInputChild(Window* _pParent,
643 USHORT nId,
644 SfxBindings* pBindings,
645 SfxChildWinInfo* ) :
646 SfxChildWindow( _pParent, nId )
648 pDispatch = pBindings->GetDispatcher();
649 pWindow = new SwInputWindow( _pParent, pBindings );
650 ((SwInputWindow*)pWindow)->ShowWin();
651 eChildAlignment = SFX_ALIGN_LOWESTTOP;
655 __EXPORT SwInputChild::~SwInputChild()
657 if(pDispatch)
658 pDispatch->Lock(FALSE);
662 SfxChildWinInfo __EXPORT SwInputChild::GetInfo() const
664 SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); \
665 return aInfo;