xref: /aoo42x/main/sw/source/ui/wrtsh/wrtsh2.cxx (revision efeef26f)
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, sal_Bool bOnlyInSel )
107 {
108 	// ueber die Liste der Eingabefelder gehen und Updaten
109 	SwInputFieldList* pTmp = pLst;
110 	if( !pTmp )
111 		pTmp = new SwInputFieldList( this );
112 
113 	if (bOnlyInSel)
114 		pTmp->RemoveUnselectedFlds();
115 
116 	const sal_uInt16 nCnt = pTmp->Count();
117 	if(nCnt)
118 	{
119 		pTmp->PushCrsr();
120 
121 		sal_Bool bCancel = sal_False;
122         ByteString aDlgPos;
123 		for( sal_uInt16 i = 0; i < nCnt && !bCancel; ++i )
124 		{
125 			pTmp->GotoFieldPos( i );
126             SwField* pField = pTmp->GetField( i );
127             if(pField->GetTyp()->Which() == RES_DROPDOWN)
128                 bCancel = StartDropDownFldDlg( pField, sal_True, &aDlgPos );
129             else
130                 bCancel = StartInputFldDlg( pField, sal_True, 0, &aDlgPos);
131 
132 			// Sonst Updatefehler bei Multiselektion:
133 			pTmp->GetField( i )->GetTyp()->UpdateFlds();
134 		}
135 		pTmp->PopCrsr();
136 	}
137 
138 	if( !pLst )
139 		delete pTmp;
140 }
141 
142 
143 /*--------------------------------------------------------------------
144 	Beschreibung: EingabeDialog fuer ein bestimmtes Feld starten
145  --------------------------------------------------------------------*/
146 
147 
148 
149 sal_Bool SwWrtShell::StartInputFldDlg( SwField* pFld, sal_Bool bNextButton,
150                                     Window* pParentWin, ByteString* pWindowState )
151 {
152 //JP 14.08.96: Bug 30332 - nach Umbau der modularietaet im SFX, muss jetzt
153 //				das TopWindow der Application benutzt werden.
154 //	SwFldInputDlg* pDlg = new SwFldInputDlg( GetWin(), *this, pFld );
155 
156     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
157     DBG_ASSERT(pFact, "Dialogdiet fail!");
158     AbstractFldInputDlg* pDlg = pFact->CreateFldInputDlg( DLG_FLD_INPUT,
159                                                         pParentWin, *this, pFld, bNextButton);
160     DBG_ASSERT(pDlg, "Dialogdiet fail!");
161 	if(pWindowState && pWindowState->Len())
162         pDlg->SetWindowState(*pWindowState);
163 	sal_Bool bRet = RET_CANCEL == pDlg->Execute();
164     if(pWindowState)
165         *pWindowState = pDlg->GetWindowState();
166 
167 	delete pDlg;
168 	GetWin()->Update();
169 	return bRet;
170 }
171 /* -----------------17.06.2003 10:18-----------------
172 
173  --------------------------------------------------*/
174 sal_Bool SwWrtShell::StartDropDownFldDlg(SwField* pFld, sal_Bool bNextButton, ByteString* pWindowState)
175 {
176     SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
177     DBG_ASSERT(pFact, "SwAbstractDialogFactory fail!");
178 
179     AbstractDropDownFieldDialog* pDlg = pFact->CreateDropDownFieldDialog( NULL, *this, pFld, DLG_FLD_DROPDOWN ,bNextButton );
180     DBG_ASSERT(pDlg, "Dialogdiet fail!");
181     if(pWindowState && pWindowState->Len())
182         pDlg->SetWindowState(*pWindowState);
183     sal_uInt16 nRet = pDlg->Execute();
184     if(pWindowState)
185         *pWindowState = pDlg->GetWindowState();
186     delete pDlg;
187     sal_Bool bRet = RET_CANCEL == nRet;
188     GetWin()->Update();
189     if(RET_YES == nRet)
190     {
191         GetView().GetViewFrame()->GetDispatcher()->Execute(FN_EDIT_FIELD, SFX_CALLMODE_SYNCHRON);
192     }
193     return bRet;
194 }
195 
196 /*--------------------------------------------------------------------
197 	Beschreibung: Verzeichnis einfuegen Selektion loeschen
198  --------------------------------------------------------------------*/
199 
200 
201 
202 void SwWrtShell::InsertTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
203 {
204 	if(!_CanInsert())
205 		return;
206 
207 	if(HasSelection())
208 		DelRight();
209 
210 	SwEditShell::InsertTableOf(rTOX, pSet);
211 }
212 
213 
214 /*--------------------------------------------------------------------
215 	Beschreibung: Verzeichnis Updaten Selektion loeschen
216  --------------------------------------------------------------------*/
217 
218 sal_Bool SwWrtShell::UpdateTableOf(const SwTOXBase& rTOX, const SfxItemSet* pSet)
219 {
220     sal_Bool bResult = sal_False;
221 
222 	if(_CanInsert())
223     {
224         bResult = SwEditShell::UpdateTableOf(rTOX, pSet);
225 
226         if (pSet == NULL)
227         {
228             SwDoc *const pDoc_ = GetDoc();
229             if (pDoc_)
230             {
231                 pDoc_->GetIDocumentUndoRedo().DelAllUndoObj();
232             }
233         }
234     }
235 
236     return bResult;
237 }
238 
239 // handler for click on the field given as parameter.
240 // the cursor is positioned on the field.
241 
242 
243 void SwWrtShell::ClickToField( const SwField& rFld )
244 {
245 	bIsInClickToEdit = sal_True;
246 	switch( rFld.GetTyp()->Which() )
247 	{
248 	case RES_JUMPEDITFLD:
249 		{
250 			sal_uInt16 nSlotId = 0;
251 			switch( rFld.GetFormat() )
252 			{
253 			case JE_FMT_TABLE:
254 				nSlotId = FN_INSERT_TABLE;
255 				break;
256 
257 			case JE_FMT_FRAME:
258 				nSlotId = FN_INSERT_FRAME;
259 				break;
260 
261 			case JE_FMT_GRAPHIC:	nSlotId = SID_INSERT_GRAPHIC;		break;
262 			case JE_FMT_OLE:        nSlotId = SID_INSERT_OBJECT;		break;
263 
264 //			case JE_FMT_TEXT:
265 			}
266 
267 			Right( CRSR_SKIP_CHARS, sal_True, 1, sal_False );		// Feld selektieren
268 
269 			if( nSlotId )
270 			{
271 				StartUndo( UNDO_START );
272 				//#97295# immediately select the right shell
273                 GetView().StopShellTimer();
274                 GetView().GetViewFrame()->GetDispatcher()->Execute( nSlotId,
275 							SFX_CALLMODE_SYNCHRON|SFX_CALLMODE_RECORD );
276 				EndUndo( UNDO_END );
277 			}
278 		}
279 		break;
280 
281 	case RES_MACROFLD:
282 		{
283 			const SwMacroField *pFld = (const SwMacroField*)&rFld;
284 			String sText( rFld.GetPar2() );
285 			String sRet( sText );
286 			ExecMacro( pFld->GetSvxMacro(), &sRet );
287 
288 			// return Wert veraendert?
289 			if( sRet != sText )
290 			{
291 				StartAllAction();
292 				((SwField&)rFld).SetPar2( sRet );
293 				((SwField&)rFld).GetTyp()->UpdateFlds();
294 				EndAllAction();
295 			}
296 		}
297 		break;
298 
299 	case RES_GETREFFLD:
300 		StartAllAction();
301 		SwCrsrShell::GotoRefMark( ((SwGetRefField&)rFld).GetSetRefName(),
302 									((SwGetRefField&)rFld).GetSubType(),
303 									((SwGetRefField&)rFld).GetSeqNo() );
304 		EndAllAction();
305 		break;
306 
307 	case RES_INPUTFLD:
308 		StartInputFldDlg( (SwField*)&rFld, sal_False );
309 		break;
310 
311 	case RES_SETEXPFLD:
312 		if( ((SwSetExpField&)rFld).GetInputFlag() )
313 			StartInputFldDlg( (SwField*)&rFld, sal_False );
314 		break;
315     case RES_DROPDOWN :
316         StartDropDownFldDlg( (SwField*)&rFld, sal_False );
317     break;
318 	}
319 
320 	bIsInClickToEdit = sal_False;
321 }
322 
323 
324 
325 void SwWrtShell::ClickToINetAttr( const SwFmtINetFmt& rItem, sal_uInt16 nFilter )
326 {
327 	if( !rItem.GetValue().Len() )
328 		return ;
329 
330 	bIsInClickToEdit = sal_True;
331 
332 	// erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
333 	const SvxMacro* pMac = rItem.GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
334 	if( pMac )
335 	{
336 		SwCallMouseEvent aCallEvent;
337 		aCallEvent.Set( &rItem );
338 		GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
339 	}
340 
341 	// damit die Vorlagenumsetzung sofort angezeigt wird
342 	::LoadURL( rItem.GetValue(), this, nFilter, &rItem.GetTargetFrame() );
343     const SwTxtINetFmt* pTxtAttr = rItem.GetTxtINetFmt();
344     if( pTxtAttr )
345     {
346         const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisited( true );
347         const_cast<SwTxtINetFmt*>(pTxtAttr)->SetVisitedValid( true );
348     }
349 
350 	bIsInClickToEdit = sal_False;
351 }
352 
353 
354 
355 sal_Bool SwWrtShell::ClickToINetGrf( const Point& rDocPt, sal_uInt16 nFilter )
356 {
357 	sal_Bool bRet = sal_False;
358 	String sURL;
359 	String sTargetFrameName;
360 	const SwFrmFmt* pFnd = IsURLGrfAtPos( rDocPt, &sURL, &sTargetFrameName );
361 	if( pFnd && sURL.Len() )
362 	{
363 		bRet = sal_True;
364 		// erstmal das evt. gesetzte ObjectSelect Macro ausfuehren
365 		const SvxMacro* pMac = &pFnd->GetMacro().GetMacro( SFX_EVENT_MOUSECLICK_OBJECT );
366 		if( pMac )
367 		{
368 			SwCallMouseEvent aCallEvent;
369 			aCallEvent.Set( EVENT_OBJECT_URLITEM, pFnd );
370 			GetDoc()->CallEvent( SFX_EVENT_MOUSECLICK_OBJECT, aCallEvent, sal_False );
371 		}
372 
373 		::LoadURL( sURL, this, nFilter, &sTargetFrameName);
374 	}
375 	return bRet;
376 }
377 
378 
379 void LoadURL( const String& rURL, ViewShell* pVSh, sal_uInt16 nFilter,
380 			  const String *pTargetFrameName )
381 {
382 	ASSERT( rURL.Len() && pVSh, "was soll hier geladen werden?" );
383 	if( !rURL.Len() || !pVSh )
384 		return ;
385 
386 	// die Shell kann auch 0 sein !!!!!
387 	SwWrtShell *pSh = 0;
388 	if ( pVSh && pVSh->ISA(SwCrsrShell) )
389 	{
390 		//Eine CrsrShell ist auch immer eine WrtShell
391 		pSh = (SwWrtShell*)pVSh;
392 	}
393 	else
394 		return;
395 
396 	SwDocShell* pDShell = pSh->GetView().GetDocShell();
397 	DBG_ASSERT( pDShell, "No DocShell?!");
398 	String sTargetFrame;
399 	if( pTargetFrameName && pTargetFrameName->Len() )
400 		sTargetFrame = *pTargetFrameName;
401 	else if( pDShell ) {
402         using namespace ::com::sun::star;
403         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
404             pDShell->GetModel(), uno::UNO_QUERY_THROW);
405         uno::Reference<document::XDocumentProperties> xDocProps
406             = xDPS->getDocumentProperties();
407         sTargetFrame = xDocProps->getDefaultTarget();
408     }
409 
410 	String sReferer;
411 	if( pDShell && pDShell->GetMedium() )
412 		sReferer = pDShell->GetMedium()->GetName();
413 	SfxViewFrame* pViewFrm = pSh->GetView().GetViewFrame();
414 	SfxFrameItem aView( SID_DOCFRAME, pViewFrm );
415 	SfxStringItem aName( SID_FILE_NAME, rURL );
416 	SfxStringItem aTargetFrameName( SID_TARGETNAME, sTargetFrame );
417 	SfxStringItem aReferer( SID_REFERER, sReferer );
418 
419 	SfxBoolItem aNewView( SID_OPEN_NEW_VIEW, sal_False );
420 	//#39076# Silent kann lt. SFX entfernt werden.
421 //	SfxBoolItem aSilent( SID_SILENT, sal_True );
422 	SfxBoolItem aBrowse( SID_BROWSE, sal_True );
423 
424 	if( nFilter & URLLOAD_NEWVIEW )
425 		aTargetFrameName.SetValue( String::CreateFromAscii("_blank") );
426 
427 	const SfxPoolItem* aArr[] = {
428 				&aName,
429                 &aNewView, /*&aSilent,*/
430 				&aReferer,
431 				&aView, &aTargetFrameName,
432 				&aBrowse,
433 				0L
434 	};
435 
436 	pViewFrm->GetDispatcher()->GetBindings()->Execute( SID_OPENDOC, aArr,
437 			SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD );
438 }
439 
440 void SwWrtShell::NavigatorPaste( const NaviContentBookmark& rBkmk,
441 									const sal_uInt16 nAction )
442 {
443 	if( EXCHG_IN_ACTION_COPY == nAction )
444 	{
445 		// Einfuegen
446 		String sURL = rBkmk.GetURL();
447 		//handelt es sich um ein Sprung innerhalb des akt. Docs?
448 		const SwDocShell* pDocShell = GetView().GetDocShell();
449 		if(pDocShell->HasName())
450 		{
451             const String rName = pDocShell->GetMedium()->GetURLObject().GetURLNoMark();
452 
453 			if(COMPARE_EQUAL == sURL.CompareTo(rName, rName.Len()))
454 				sURL.Erase(0, rName.Len());
455 		}
456 		SwFmtINetFmt aFmt( sURL, aEmptyStr );
457 		InsertURL( aFmt, rBkmk.GetDescription() );
458 	}
459 	else
460 	{
461         SwSectionData aSection( FILE_LINK_SECTION, GetUniqueSectionName( 0 ) );
462 		String aLinkFile( rBkmk.GetURL().GetToken(0, '#') );
463         aLinkFile += sfx2::cTokenSeperator;
464         aLinkFile += sfx2::cTokenSeperator;
465 		aLinkFile += rBkmk.GetURL().GetToken(1, '#');
466 		aSection.SetLinkFileName( aLinkFile );
467         aSection.SetProtectFlag( true );
468 		const SwSection* pIns = InsertSection( aSection );
469 		if( EXCHG_IN_ACTION_MOVE == nAction && pIns )
470 		{
471             aSection = SwSectionData(*pIns);
472 			aSection.SetLinkFileName( aEmptyStr );
473 			aSection.SetType( CONTENT_SECTION );
474             aSection.SetProtectFlag( false );
475 
476 			// the update of content from linked section at time delete
477 			// the undostack. Then the change of the section dont create
478 			// any undoobject. -  BUG 69145
479 			sal_Bool bDoesUndo = DoesUndo();
480             SwUndoId nLastUndoId(UNDO_EMPTY);
481             if (GetLastUndoInfo(0, & nLastUndoId))
482             {
483                 if (UNDO_INSSECTION != nLastUndoId)
484                 {
485                     DoUndo(false);
486                 }
487             }
488             UpdateSection( GetSectionFmtPos( *pIns->GetFmt() ), aSection );
489 			DoUndo( bDoesUndo );
490 		}
491 	}
492 }
493 
494 
495