1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: inputwin.cxx,v $
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"
45 #include "swmodule.hxx"
49 #include "inputwin.hxx"
53 #include "cellatr.hxx"
57 // nur fuers UpdateRange - Box in dem der gestackte Cursor sthet loeschen
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
)),
79 aAktTableName(aEmptyStr
)
81 bFirst
= bDoesUndo
= TRUE
;
82 bActive
= bIsTable
= bDelSel
= bResetUndo
= bCallUndo
= FALSE
;
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 );
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);
132 pView
->GetHLineal().SetActive( TRUE
);
133 pView
->GetVLineal().SetActive( TRUE
);
138 pWrtShell
->EndSelTblCells();
143 pWrtShell
->DoUndo( bDoesUndo
);
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()
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
);
185 //==================================================================
187 void SwInputWindow::ShowWin()
193 pView
->GetHLineal().SetActive( FALSE
);
194 pView
->GetVLineal().SetActive( FALSE
);
196 DBG_ASSERT(pWrtShell
, "Keine WrtShell!");
198 bIsTable
= pWrtShell
->IsCrsrInTbl() ? TRUE
: FALSE
;
201 pWrtShell
->SelTblCells( LINK( this, SwInputWindow
,
202 SelTblCellsNotify
) );
205 const String
& rPos
= pWrtShell
->GetBoxNms();
208 while( (nPos
= rPos
.Search( ':',nPos
+ 1 ) ) != STRING_NOTFOUND
)
209 nSrch
= (short) nPos
;
210 aPos
.SetText( rPos
.Copy( ++nSrch
) );
211 aAktTableName
= pWrtShell
->GetTableFmt()->GetName();
214 aPos
.SetText(SW_RESSTR(STR_TBL_FORMULA
));
216 // Aktuelles Feld bearbeiten
217 ASSERT(pMgr
== 0, FieldManager nicht geloescht
.);
220 // JP 13.01.97: Formel soll immer mit einem "=" beginnen, hier
223 if( pMgr
->GetCurFld() && TYP_FORMELFLD
== pMgr
->GetCurTypeId() )
225 sEdit
+= pMgr
->GetCurFldPar2();
232 nActionCnt
= SwEditShell::GetUndoActionCount();
233 SwEditShell::SetUndoActionCount( nActionCnt
+ 1 );
235 bDoesUndo
= pWrtShell
->DoesUndo();
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
);
249 if( 0 != pWrtShell
->EndUndo( UNDO_DELETE
))
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();
262 // WrtShell Flags richtig setzen
263 pWrtShell
->SttSelect();
264 pWrtShell
->EndSelect();
269 aEdit
.SetModifyHdl( LINK( this, SwInputWindow
, ModifyHdl
));
271 aEdit
.SetText( sEdit
);
272 aEdit
.SetSelection( Selection( sEdit
.Len(), sEdit
.Len() ) );
278 // UserInterface fuer die Eingabe abklemmen
280 pView
->GetEditWin().LockKeyInput(TRUE
);
281 pView
->GetViewFrame()->GetDispatcher()->Lock(TRUE
);
286 //==================================================================
288 IMPL_LINK( SwInputWindow
, MenuHdl
, Menu
*, pMenu
)
290 static const char * __READONLY_DATA aStrArr
[] = {
318 USHORT nId
= pMenu
->GetCurItemId();
319 if ( nId
<= MN_CALC_ROUND
)
321 String
aTmp( String::CreateFromAscii(aStrArr
[nId
- 1]) );
323 aEdit
.ReplaceSelected( aTmp
);
328 IMPL_LINK( SwInputWindow
, DropdownClickHdl
, ToolBox
*, EMPTYARG
)
330 USHORT nCurID
= GetCurItemId();
331 EndSelection(); // setzt CurItemId zurueck !
334 case FN_FORMULA_CALC
:
336 aPopMenu
.Execute( this, GetItemRect( FN_FORMULA_CALC
), POPUPMENU_NOMOUSEUPCLOSE
);
346 //==================================================================
349 void __EXPORT
SwInputWindow::Click( )
351 USHORT nCurID
= GetCurItemId();
352 EndSelection(); // setzt CurItemId zurueck !
355 case FN_FORMULA_CANCEL
:
360 case FN_FORMULA_APPLY
:
368 //==================================================================
370 void SwInputWindow::ApplyFormula()
372 pView
->GetViewFrame()->GetDispatcher()->Lock(FALSE
);
373 pView
->GetEditWin().LockKeyInput(FALSE
);
377 pWrtShell
->DoUndo( bDoesUndo
);
378 SwEditShell::SetUndoActionCount( nActionCnt
);
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 ) )
391 SfxStringItem
aParam(FN_EDIT_FORMULA
, sEdit
);
393 pWrtShell
->EndSelTblCells();
394 pView
->GetEditWin().GrabFocus();
395 const SfxPoolItem
* aArgs
[2];
398 pView
->GetViewFrame()->GetBindings().Execute( FN_EDIT_FORMULA
, aArgs
, 0, SFX_CALLMODE_ASYNCHRON
);
401 //==================================================================
403 void SwInputWindow::CancelFormula()
407 pView
->GetViewFrame()->GetDispatcher()->Lock( FALSE
);
408 pView
->GetEditWin().LockKeyInput(FALSE
);
412 pWrtShell
->DoUndo( bDoesUndo
);
413 SwEditShell::SetUndoActionCount( nActionCnt
);
418 pWrtShell
->Pop( FALSE
);
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
)
438 SwFrmFmt
* pTblFmt
= pCaller
->GetTableFmt();
439 String
sBoxNms( pCaller
->GetBoxNms() );
441 if( pTblFmt
&& aAktTableName
!= pTblFmt
->GetName() )
442 sTblNm
= pTblFmt
->GetName();
444 aEdit
.UpdateRange( sBoxNms
, sTblNm
);
448 sNew
+= aEdit
.GetText();
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
);
461 aPam
.Move( fnMoveForward
, fnGoSection
);
463 IDocumentContentOperations
* pIDCO
= pWrtShell
->getIDocumentContentOperations();
464 pIDCO
->DeleteRange( aPam
);
465 pIDCO
->InsertString( aPam
, sNew
);
466 pWrtShell
->EndAllAction();
476 void SwInputWindow::SetFormula( const String
& rFormula
, BOOL bDelFlag
)
481 if( '=' == rFormula
.GetChar( 0 ) )
486 aEdit
.SetText( sEdit
);
487 aEdit
.SetSelection( Selection( sEdit
.Len(), sEdit
.Len() ) );
492 IMPL_LINK( SwInputWindow
, ModifyHdl
, InputEdit
*, EMPTYARG
)
494 if( bIsTable
&& bResetUndo
)
496 pWrtShell
->StartAllAction();
500 sNew
+= aEdit
.GetText();
502 pWrtShell
->SwEditShell::Insert2( sNew
);
503 pWrtShell
->EndAllAction();
510 void SwInputWindow::DelBoxCntnt()
514 pWrtShell
->StartAllAction();
515 pWrtShell
->ClearMark();
516 pWrtShell
->Pop( FALSE
);
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();
536 Edit::KeyInput(rEvent
);
539 //==================================================================
541 void __EXPORT
InputEdit::UpdateRange(const String
& rBoxes
,
542 const String
& rName
)
549 const sal_Unicode cOpen
= '<', cClose
= '>',
551 String aPrefix
= rName
;
554 String aBoxes
= aPrefix
;
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
) )
564 aSelection
.Max() = aSelection
.Min();
565 String
aActText(GetText());
566 const USHORT nLen
= aActText
.Len();
573 USHORT nPos
= aStr
.Search( cClose
);
574 ASSERT(nPos
< aStr
.Len(), Delimiter nicht gefunden
.);
576 SetSelection( Selection( nPos
, nPos
));
582 USHORT nPos
, nEndPos
= 0, nStartPos
= (USHORT
) aSelection
.Min();
586 if( cOpen
== (cCh
= aActText
.GetChar( nStartPos
) ) ||
587 cOpenBracket
== cCh
)
589 bFound
= cCh
== cOpen
;
592 } while( nStartPos
-- > 0 );
598 while( nEndPos
< nLen
)
600 if( cClose
== (cCh
= aActText
.GetChar( nEndPos
)) /*||
601 cCh == cCloseBracket*/ )
608 // nur wenn akt. Pos im Breich oder direkt dahinter liegt
609 if( bFound
&& !( nStartPos
< (USHORT
)aSelection
.Max() &&
610 (USHORT
)aSelection
.Max() <= nEndPos
+ 1 ))
615 nPos
= ++nStartPos
+ 1; // wir wollen dahinter
616 aActText
.Erase( nStartPos
, nEndPos
- nStartPos
);
617 aActText
.Insert( aBoxes
, nStartPos
);
618 nPos
= nPos
+ aBoxes
.Len();
622 String
aTmp( (char)cOpen
);
624 aTmp
+= (char)cClose
;
625 nPos
= (USHORT
)aSelection
.Min();
626 aActText
.Insert( aTmp
, nPos
);
627 nPos
= nPos
+ aTmp
.Len();
629 if( GetText() != aActText
)
632 SetSelection( Selection( nPos
, nPos
) );
633 // GetModifyHdl().Call( this );
639 //==================================================================
642 SwInputChild::SwInputChild(Window
* _pParent
,
644 SfxBindings
* pBindings
,
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()
658 pDispatch
->Lock(FALSE
);
662 SfxChildWinInfo __EXPORT
SwInputChild::GetInfo() const
664 SfxChildWinInfo aInfo
= SfxChildWindow::GetInfo(); \