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