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