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