xref: /AOO41X/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