xref: /trunk/main/sw/source/ui/wrtsh/wrtsh2.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <hintids.hxx>      // define ITEMIDs
32 #include <svl/macitem.hxx>
33 #include <sfx2/frame.hxx>
34 #include <vcl/msgbox.hxx>
35 #include <svl/urihelper.hxx>
36 #include <svl/eitem.hxx>
37 #include <svl/stritem.hxx>
38 #include <sfx2/docfile.hxx>
39 #include <sfx2/fcontnr.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/linkmgr.hxx>
42 #include <fmtinfmt.hxx>
43 #include <frmatr.hxx>
44 #include <swtypes.hxx>      // SET_CURR_SHELL
45 #include <wrtsh.hxx>
46 #include <docsh.hxx>
47 #include <fldbas.hxx>       // Felder
48 #include <expfld.hxx>
49 #include <ddefld.hxx>
50 #include <docufld.hxx>
51 #include <reffld.hxx>
52 #include <swundo.hxx>
53 #include <doc.hxx>
54 #include <IDocumentUndoRedo.hxx>
55 #include <viewopt.hxx>      // SwViewOptions
56 #include <frmfmt.hxx>       // fuer UpdateTable
57 #include <swtable.hxx>      // fuer UpdateTable
58 #include <mdiexp.hxx>
59 #include <view.hxx>
60 #include <swevent.hxx>
61 #include <poolfmt.hxx>
62 #include <section.hxx>
63 #include <navicont.hxx>
64 #include <navipi.hxx>
65 #include <crsskip.hxx>
66 #include <txtinet.hxx>
67 #include <cmdid.h>
68 #include <wrtsh.hrc>
69 #include "swabstdlg.hxx"
70 #include "fldui.hrc"
71 #include <SwRewriter.hxx>
72 
73 #include <com/sun/star/document/XDocumentProperties.hpp>
74 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
75 
76 
77 /*------------------------------------------------------------------------
78         Beschreibung:
79 ------------------------------------------------------------------------*/
80 
81 void SwWrtShell::Insert(SwField &rFld)
82 {
83     ResetCursorStack();
84     if(!_CanInsert())
85         return;
86     StartAllAction();
87 
88     SwRewriter aRewriter;
89     aRewriter.AddRule(UNDO_ARG1, rFld.GetDescription());
90 
91     StartUndo(UNDO_INSERT, &aRewriter);
92 
93     bool bDeleted = false;
94     if( HasSelection() )
95     {
96         bDeleted = DelRight() != 0;
97     }
98 
99     SwEditShell::Insert2(rFld, bDeleted);
100     EndUndo();
101     EndAllAction();
102 }
103 
104 /*--------------------------------------------------------------------
105     Beschreibung: Felder Update anschmeissen
106  --------------------------------------------------------------------*/
107 
108 
109 
110 void SwWrtShell::UpdateInputFlds( SwInputFieldList* pLst, sal_Bool bOnlyInSel )
111 {
112     // ueber die Liste der Eingabefelder gehen und Updaten
113     SwInputFieldList* pTmp = pLst;
114     if( !pTmp )
115         pTmp = new SwInputFieldList( this );
116 
117     if (bOnlyInSel)
118         pTmp->RemoveUnselectedFlds();
119 
120     const sal_uInt16 nCnt = pTmp->Count();
121     if(nCnt)
122     {
123         pTmp->PushCrsr();
124 
125         sal_Bool bCancel = sal_False;
126         ByteString aDlgPos;
127         for( sal_uInt16 i = 0; i < nCnt && !bCancel; ++i )
128         {
129             pTmp->GotoFieldPos( i );
130             SwField* pField = pTmp->GetField( i );
131             if(pField->GetTyp()->Which() == RES_DROPDOWN)
132                 bCancel = StartDropDownFldDlg( pField, sal_True, &aDlgPos );
133             else
134                 bCancel = StartInputFldDlg( pField, sal_True, 0, &aDlgPos);
135 
136             // Sonst Updatefehler bei Multiselektion:
137             pTmp->GetField( i )->GetTyp()->UpdateFlds();
138         }
139         pTmp->PopCrsr();
140     }
141 
142     if( !pLst )
143         delete pTmp;
144 }
145 
146 
147 /*--------------------------------------------------------------------
148     Beschreibung: EingabeDialog fuer ein bestimmtes Feld starten
149  --------------------------------------------------------------------*/
150 
151 
152 
153 sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton,
154                                     Window* pParentWin, ByteString* pWindowState )
155 {
156 //JP 14.08.96: Bug 30332 - nach Umbau der modularietaet im SFX, muss jetzt
157 //              das TopWindow der Application benutzt werden.
158 //  SwFldInputDlg* pDlg = new SwFldInputDlg( GetWin(), *this, pFld );
159 
160     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
161     DBG_ASSERT(pFact, "Dialogdiet fail!");
162     AbstractFldInputDlg* pDlg = pFact->CreateFldInputDlg( DLG_FLD_INPUT,
163                                                         pParentWin, *this, pFld, bNextButton);
164     DBG_ASSERT(pDlg, "Dialogdiet fail!");
165     if(pWindowState && pWindowState->Len())
166         pDlg->SetWindowState(*pWindowState);
167     sal_Bool bRet = RET_CANCEL == pDlg->Execute();
168     if(pWindowState)
169         *pWindowState = pDlg->GetWindowState();
170 
171     delete pDlg;
172     GetWin()->Update();
173     return bRet;
174 }
175 /* -----------------17.06.2003 10:18-----------------
176 
177  --------------------------------------------------*/
178 sal_Bool SwWrtShell::StartDropDownFldDlg(SwField* pFld, sal_Bool bNextButton, ByteString* pWindowState)
179 {
180     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
181     DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
182 
183     AbstractDropDownFieldDialog* pDlg = pFact->CreateDropDownFieldDialog( NULL, *this, pFld, DLG_FLD_DROPDOWN ,bNextButton );
184     DBG_ASSERT(pDlg, "Dialogdiet fail!");
185     if(pWindowState && pWindowState->Len())
186         pDlg->SetWindowState(*pWindowState);
187     sal_uInt16 nRet = pDlg->Execute();
188     if(pWindowState)
189         *pWindowState = pDlg->GetWindowState();
190     delete pDlg;
191     sal_Bool bRet = RET_CANCEL == nRet;
192     GetWin()->Update();
193     if(RET_YES == nRet)
194     {
195         GetView().GetViewFrame()->GetDispatcher()->Execute(FN_EDIT_FIELD, SFX_CALLMODE_SYNCHRON);
196     }
197     return bRet;
198 }
199 
200 /*--------------------------------------------------------------------
201     Beschreibung: Verzeichnis einfuegen Selektion loeschen
202  --------------------------------------------------------------------*/
203 
204 
205 
206 void SwWrtShell::InsertTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
207 {
208     if(!_CanInsert())
209         return;
210 
211     if(HasSelection())
212         DelRight();
213 
214     SwEditShell::InsertTableOf(rTOX, pSet);
215 }
216 
217 
218 /*--------------------------------------------------------------------
219     Beschreibung: Verzeichnis Updaten Selektion loeschen
220  --------------------------------------------------------------------*/
221 
222 sal_Bool SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
223 {
224     sal_Bool bResult = sal_False;
225 
226     if(_CanInsert())
227     {
228         bResult = SwEditShell::UpdateTableOf(rTOX, pSet);
229 
230         if (pSet == NULL)
231         {
232             SwDoc *const pDoc_ = GetDoc();
233             if (pDoc_)
234             {
235                 pDoc_->GetIDocumentUndoRedo().DelAllUndoObj();
236             }
237         }
238     }
239 
240     return bResult;
241 }
242 
243 // handler for click on the field given as parameter.
244 // the cursor is positioned on the field.
245 
246 
247 void SwWrtShell::ClickToField( const SwField& rFld )
248 {
249     bIsInClickToEdit = sal_True;
250     switch( rFld.GetTyp()->Which() )
251     {
252     case RES_JUMPEDITFLD:
253         {
254             sal_uInt16 nSlotId = 0;
255             switch( rFld.GetFormat() )
256             {
257             case JE_FMT_TABLE:
258                 nSlotId = FN_INSERT_TABLE;
259                 break;
260 
261             case JE_FMT_FRAME:
262                 nSlotId = FN_INSERT_FRAME;
263                 break;
264 
265             case JE_FMT_GRAPHIC:    nSlotId = SID_INSERT_GRAPHIC;       break;
266             case JE_FMT_OLE:        nSlotId = SID_INSERT_OBJECT;        break;
267 
268 //          case JE_FMT_TEXT:
269             }
270 
271             Right( CRSR_SKIP_CHARS, sal_True, 1, sal_False );       // Feld selektieren
272 
273             if( nSlotId )
274             {
275                 StartUndo( UNDO_START );
276                 //#97295# immediately select the right shell
277                 GetView().StopShellTimer();
278                 GetView().GetViewFrame()->GetDispatcher()->Execute( nSlotId,
279                             SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
280                 EndUndo( UNDO_END );
281             }
282         }
283         break;
284 
285     case RES_MACROFLD:
286         {
287             const SwMacroField *pFld = (const SwMacroField*)&rFld;
288             String sText( rFld.GetPar2() );
289             String sRet( sText );
290             ExecMacro( pFld->GetSvxMacro(), &sRet );
291 
292             // return Wert veraendert?
293             if( sRet != sText )
294             {
295                 StartAllAction();
296                 ((SwField&)rFld).SetPar2( sRet );
297                 ((SwField&)rFld).GetTyp()->UpdateFlds();
298                 EndAllAction();
299             }
300         }
301         break;
302 
303     case RES_GETREFFLD:
304         StartAllAction();
305         SwCrsrShell::GotoRefMark( ((SwGetRefField&)rFld).GetSetRefName(),
306                                     ((SwGetRefField&)rFld).GetSubType(),
307                                     ((SwGetRefField&)rFld).GetSeqNo() );
308         EndAllAction();
309         break;
310 
311     case RES_INPUTFLD:
312         StartInputFldDlg( (SwField*)&rFld, sal_False );
313         break;
314 
315     case RES_SETEXPFLD:
316         if( ((SwSetExpField&)rFld).GetInputFlag() )
317             StartInputFldDlg( (SwField*)&rFld, sal_False );
318         break;
319     case RES_DROPDOWN :
320         StartDropDownFldDlg( (SwField*)&rFld, sal_False );
321     break;
322     }
323 
324     bIsInClickToEdit = sal_False;
325 }
326 
327 
328 
329 void SwWrtShell::ClickToINetAttr( const SwFmtINetFmt& rItem, sal_uInt16 nFilter )
330 {
331     if( !rItem.GetValue().Len() )
332         return ;
333 
334     bIsInClickToEdit = sal_True;
335 
336     // erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
337     const SvxMacro* pMac = rItem.GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
338     if( pMac )
339     {
340         SwCallMouseEvent aCallEvent;
341         aCallEvent.Set( &rItem );
342         GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
343     }
344 
345     // damit die Vorlagenumsetzung sofort angezeigt wird
346     ::LoadURL( rItem.GetValue(), this, nFilter, &rItem.GetTargetFrame() );
347     const SwTxtINetFmt* pTxtAttr = rItem.GetTxtINetFmt();
348     if( pTxtAttr )
349     {
350         const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisited( true );
351         const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisitedValid( true );
352     }
353 
354     bIsInClickToEdit = sal_False;
355 }
356 
357 
358 
359 sal_Bool SwWrtShell::ClickToINetGrf( const Point& rDocPt, sal_uInt16 nFilter )
360 {
361     sal_Bool bRet = sal_False;
362     String sURL;
363     String sTargetFrameName;
364     const SwFrmFmt* pFnd = IsURLGrfAtPos( rDocPt, &sURL, &sTargetFrameName );
365     if( pFnd && sURL.Len() )
366     {
367         bRet = sal_True;
368         // erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
369         const SvxMacro* pMac = &pFnd->GetMacro().GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
370         if( pMac )
371         {
372             SwCallMouseEvent aCallEvent;
373             aCallEvent.Set( EVENT_OBJECT_URLITEM, pFnd );
374             GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
375         }
376 
377         ::LoadURL( sURL, this, nFilter, &sTargetFrameName);
378     }
379     return bRet;
380 }
381 
382 
383 void LoadURL( const String& rURL, ViewShell* pVSh, sal_uInt16 nFilter,
384               const String *pTargetFrameName )
385 {
386     ASSERT( rURL.Len() && pVSh, "was soll hier geladen werden?" );
387     if( !rURL.Len() || !pVSh )
388         return ;
389 
390     // die Shell kann auch 0 sein !!!!!
391     SwWrtShell *pSh = 0;
392     if ( pVSh && pVSh->ISA(SwCrsrShell) )
393     {
394         //Eine CrsrShell ist auch immer eine WrtShell
395         pSh = (SwWrtShell*)pVSh;
396     }
397     else
398         return;
399 
400     SwDocShell* pDShell = pSh->GetView().GetDocShell();
401     DBG_ASSERT( pDShell, "No DocShell?!");
402     String sTargetFrame;
403     if( pTargetFrameName && pTargetFrameName->Len() )
404         sTargetFrame = *pTargetFrameName;
405     else if( pDShell ) {
406         using namespace ::com::sun::star;
407         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
408             pDShell->GetModel(), uno::UNO_QUERY_THROW);
409         uno::Reference<document::XDocumentProperties> xDocProps
410             = xDPS->getDocumentProperties();
411         sTargetFrame = xDocProps->getDefaultTarget();
412     }
413 
414     String sReferer;
415     if( pDShell && pDShell->GetMedium() )
416         sReferer = pDShell->GetMedium()->GetName();
417     SfxViewFrame* pViewFrm = pSh->GetView().GetViewFrame();
418     SfxFrameItem aView( SID_DOCFRAME, pViewFrm );
419     SfxStringItem aName( SID_FILE_NAME, rURL );
420     SfxStringItem aTargetFrameName( SID_TARGETNAME, sTargetFrame );
421     SfxStringItem aReferer( SID_REFERER, sReferer );
422 
423     SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False );
424     //#39076# Silent kann lt. SFX entfernt werden.
425 //  SfxBoolItem aSilent( SID_SILENT, sal_True );
426     SfxBoolItem aBrowse( SID_BROWSE, sal_True );
427 
428     if( nFilter & URLLOAD_NEWVIEW )
429         aTargetFrameName.SetValue( String::CreateFromAscii("_blank") );
430 
431     const SfxPoolItem* aArr[] = {
432                 &aName,
433                 &aNewView, /*&aSilent,*/
434                 &aReferer,
435                 &aView, &aTargetFrameName,
436                 &aBrowse,
437                 0L
438     };
439 
440     pViewFrm->GetDispatcher()->GetBindings()->Execute( SID_OPENDOC, aArr,
441             SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
442 }
443 
444 void SwWrtShell::NavigatorPaste( const NaviContentBookmark& rBkmk,
445                                     const sal_uInt16 nAction )
446 {
447     if( EXCHG_IN_ACTION_COPY == nAction )
448     {
449         // Einfuegen
450         String sURL = rBkmk.GetURL();
451         //handelt es sich um ein Sprung innerhalb des akt. Docs?
452         const SwDocShell* pDocShell = GetView().GetDocShell();
453         if(pDocShell->HasName())
454         {
455             const String rName = pDocShell->GetMedium()->GetURLObject().GetURLNoMark();
456 
457             if(COMPARE_EQUAL == sURL.CompareTo(rName, rName.Len()))
458                 sURL.Erase(0, rName.Len());
459         }
460         SwFmtINetFmt aFmt( sURL, aEmptyStr );
461         InsertURL( aFmt, rBkmk.GetDescription() );
462     }
463     else
464     {
465         SwSectionData aSection( FILE_LINK_SECTION, GetUniqueSectionName( 0 ) );
466         String aLinkFile( rBkmk.GetURL().GetToken(0, '#') );
467         aLinkFile += sfx2::cTokenSeperator;
468         aLinkFile += sfx2::cTokenSeperator;
469         aLinkFile += rBkmk.GetURL().GetToken(1, '#');
470         aSection.SetLinkFileName( aLinkFile );
471         aSection.SetProtectFlag( true );
472         const SwSection* pIns = InsertSection( aSection );
473         if( EXCHG_IN_ACTION_MOVE == nAction && pIns )
474         {
475             aSection = SwSectionData(*pIns);
476             aSection.SetLinkFileName( aEmptyStr );
477             aSection.SetType( CONTENT_SECTION );
478             aSection.SetProtectFlag( false );
479 
480             // the update of content from linked section at time delete
481             // the undostack. Then the change of the section dont create
482             // any undoobject. -  BUG 69145
483             sal_Bool bDoesUndo = DoesUndo();
484             SwUndoId nLastUndoId(UNDO_EMPTY);
485             if (GetLastUndoInfo(0, & nLastUndoId))
486             {
487                 if (UNDO_INSSECTION != nLastUndoId)
488                 {
489                     DoUndo(false);
490                 }
491             }
492             UpdateSection( GetSectionFmtPos( *pIns->GetFmt() ), aSection );
493             DoUndo( bDoesUndo );
494         }
495     }
496 }
497 
498 
499