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 28 #include <osl/endian.h> 29 #include <hintids.hxx> 30 #include <svl/urihelper.hxx> 31 #include <tools/cachestr.hxx> 32 #include <doc.hxx> 33 #include <pam.hxx> 34 #include <docary.hxx> 35 #include <editsh.hxx> 36 #include <edimp.hxx> 37 #include <frmfmt.hxx> 38 #include <swundo.hxx> // fuer die UndoIds 39 #include <ndtxt.hxx> 40 #include <swtable.hxx> // fuers kopieren von Tabellen 41 #include <shellio.hxx> // SwTextBlocks 42 #include <acorrect.hxx> 43 #include <swerror.h> // SwTextBlocks 44 45 /****************************************************************************** 46 * jetzt mit einem verkappten Reader/Writer/Dokument 47 ******************************************************************************/ 48 49 void SwEditShell::InsertGlossary( SwTextBlocks& rGlossary, const String& rStr ) 50 { 51 StartAllAction(); 52 GetDoc()->InsertGlossary( rGlossary, rStr, *GetCrsr(), this ); 53 EndAllAction(); 54 } 55 56 57 /****************************************************************************** 58 * aktuelle Selektion zum Textbaustein machen und ins 59 * Textbausteindokument einfuegen, einschliesslich Vorlagen 60 ******************************************************************************/ 61 62 63 sal_uInt16 SwEditShell::MakeGlossary( SwTextBlocks& rBlks, const String& rName, const String& rShortName, 64 sal_Bool bSaveRelFile, const String* pOnlyTxt ) 65 { 66 SwDoc* pGDoc = rBlks.GetDoc(); 67 68 String sBase; 69 if(bSaveRelFile) 70 { 71 INetURLObject aURL( rBlks.GetFileName() ); 72 sBase = aURL.GetMainURL( INetURLObject::NO_DECODE ); 73 } 74 rBlks.SetBaseURL( sBase ); 75 76 sal_uInt16 nRet; 77 78 if( pOnlyTxt ) 79 nRet = rBlks.PutText( rShortName, rName, *pOnlyTxt ); 80 else 81 { 82 rBlks.ClearDoc(); 83 if( rBlks.BeginPutDoc( rShortName, rName ) ) 84 { 85 rBlks.GetDoc()->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES ); 86 _CopySelToDoc( pGDoc ); 87 rBlks.GetDoc()->SetRedlineMode_intern( (RedlineMode_t)0 ); 88 nRet = rBlks.PutDoc(); 89 } 90 else 91 nRet = (sal_uInt16) -1; 92 } 93 94 return nRet; 95 } 96 97 sal_uInt16 SwEditShell::SaveGlossaryDoc( SwTextBlocks& rBlock, 98 const String& rName, 99 const String& rShortName, 100 sal_Bool bSaveRelFile, 101 sal_Bool bOnlyTxt ) 102 { 103 StartAllAction(); 104 105 SwDoc* pGDoc = rBlock.GetDoc(); 106 SwDoc* pMyDoc = GetDoc(); 107 108 String sBase; 109 if(bSaveRelFile) 110 { 111 INetURLObject aURL( rBlock.GetFileName() ); 112 sBase = aURL.GetMainURL( INetURLObject::NO_DECODE ); 113 } 114 rBlock.SetBaseURL( sBase ); 115 sal_uInt16 nRet = USHRT_MAX; 116 117 if( bOnlyTxt ) 118 { 119 KillPams(); 120 121 SwPaM* pCrsr = GetCrsr(); 122 123 SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 ); 124 SwCntntNode* pCntntNd = pMyDoc->GetNodes().GoNext( &aStt ); 125 const SwNode* pNd = pCntntNd->FindTableNode(); 126 if( !pNd ) 127 pNd = pCntntNd; 128 129 pCrsr->GetPoint()->nNode = *pNd; 130 if( pNd == pCntntNd ) 131 pCrsr->GetPoint()->nContent.Assign( pCntntNd, 0 ); 132 pCrsr->SetMark(); 133 134 // dann bis zum Ende vom Nodes Array 135 pCrsr->GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1; 136 pCntntNd = pCrsr->GetCntntNode(); 137 if( pCntntNd ) 138 pCrsr->GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() ); 139 140 String sBuf; 141 if( GetSelectedText( sBuf, GETSELTXT_PARABRK_TO_ONLYCR ) && sBuf.Len() ) 142 nRet = rBlock.PutText( rShortName, rName, sBuf ); 143 } 144 else 145 { 146 rBlock.ClearDoc(); 147 if( rBlock.BeginPutDoc( rShortName, rName ) ) 148 { 149 SwNodeIndex aStt( pMyDoc->GetNodes().GetEndOfExtras(), 1 ); 150 SwCntntNode* pCntntNd = pMyDoc->GetNodes().GoNext( &aStt ); 151 const SwNode* pNd = pCntntNd->FindTableNode(); 152 if( !pNd ) pNd = pCntntNd; 153 SwPaM aCpyPam( *pNd ); 154 aCpyPam.SetMark(); 155 156 // dann bis zum Ende vom Nodes Array 157 aCpyPam.GetPoint()->nNode = pMyDoc->GetNodes().GetEndOfContent().GetIndex()-1; 158 pCntntNd = aCpyPam.GetCntntNode(); 159 aCpyPam.GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() ); 160 161 aStt = pGDoc->GetNodes().GetEndOfExtras(); 162 pCntntNd = pGDoc->GetNodes().GoNext( &aStt ); 163 SwPosition aInsPos( aStt, SwIndex( pCntntNd )); 164 pMyDoc->CopyRange( aCpyPam, aInsPos, false ); 165 166 nRet = rBlock.PutDoc(); 167 } 168 } 169 EndAllAction(); 170 return nRet; 171 } 172 173 /****************************************************************************** 174 * kopiere alle Selectionen und das Doc 175 ******************************************************************************/ 176 177 178 sal_Bool SwEditShell::_CopySelToDoc( SwDoc* pInsDoc, SwNodeIndex* pSttNd ) 179 { 180 ASSERT( pInsDoc, "kein Ins.Dokument" ); 181 182 SwNodes& rNds = pInsDoc->GetNodes(); 183 184 SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 ); 185 SwCntntNode * pNd = aIdx.GetNode().GetCntntNode(); 186 SwPosition aPos( aIdx, SwIndex( pNd, pNd->Len() )); 187 188 // soll der Index auf Anfang returnt werden ? 189 if( pSttNd ) 190 { 191 *pSttNd = aPos.nNode; 192 (*pSttNd)--; 193 } 194 195 sal_Bool bRet = sal_False; 196 SET_CURR_SHELL( this ); 197 198 pInsDoc->LockExpFlds(); 199 200 if( IsTableMode() ) 201 { 202 // kopiere Teile aus einer Tabelle: lege eine Tabelle mit der Breite 203 // von der Originalen an und kopiere die selectierten Boxen. 204 // Die Groessen werden prozentual korrigiert. 205 206 // lasse ueber das Layout die Boxen suchen 207 SwTableNode* pTblNd; 208 SwSelBoxes aBoxes; 209 GetTblSel( *this, aBoxes ); 210 if( aBoxes.Count() && 0 != (pTblNd = (SwTableNode*)aBoxes[0] 211 ->GetSttNd()->FindTableNode() )) 212 { 213 // teste ob der TabellenName kopiert werden kann 214 sal_Bool bCpyTblNm = aBoxes.Count() == pTblNd->GetTable().GetTabSortBoxes().Count(); 215 if( bCpyTblNm ) 216 { 217 const String& rTblName = pTblNd->GetTable().GetFrmFmt()->GetName(); 218 const SwFrmFmts& rTblFmts = *pInsDoc->GetTblFrmFmts(); 219 for( sal_uInt16 n = rTblFmts.Count(); n; ) 220 if( rTblFmts[ --n ]->GetName() == rTblName ) 221 { 222 bCpyTblNm = sal_False; 223 break; 224 } 225 } 226 bRet = pInsDoc->InsCopyOfTbl( aPos, aBoxes, 0, bCpyTblNm, sal_False ); 227 } 228 else 229 bRet = sal_False; 230 } 231 else 232 { 233 bool bColSel = _GetCrsr()->IsColumnSelection(); 234 if( bColSel && pInsDoc->IsClipBoard() ) 235 pInsDoc->SetColumnSelection( true ); 236 { 237 FOREACHPAM_START(this) 238 239 if( !PCURCRSR->HasMark() ) 240 { 241 if( 0 != (pNd = PCURCRSR->GetCntntNode()) && 242 ( bColSel || !pNd->GetTxtNode() ) ) 243 { 244 PCURCRSR->SetMark(); 245 PCURCRSR->Move( fnMoveForward, fnGoCntnt ); 246 bRet = GetDoc()->CopyRange( *PCURCRSR, aPos, false ) 247 || bRet; 248 PCURCRSR->Exchange(); 249 PCURCRSR->DeleteMark(); 250 } 251 } 252 else 253 { 254 bRet = GetDoc()->CopyRange( *PCURCRSR, aPos, false ) || bRet; 255 } 256 257 FOREACHPAM_END() 258 } 259 } 260 261 pInsDoc->UnlockExpFlds(); 262 if( !pInsDoc->IsExpFldsLocked() ) 263 pInsDoc->UpdateExpFlds(NULL, true); 264 265 // die gemerkte Node-Position wieder auf den richtigen Node 266 if( bRet && pSttNd ) 267 (*pSttNd)++; 268 269 270 return bRet; 271 } 272 273 /*------------------------------------------------------------------------ 274 Beschreibung: Text innerhalb der Selektion erfragen 275 Returnwert: liefert sal_False, wenn der selektierte Bereich 276 zu gross ist, um in den Stringpuffer kopiert zu werden. 277 ------------------------------------------------------------------------*/ 278 279 sal_Bool SwEditShell::GetSelectedText( String &rBuf, int nHndlParaBrk ) 280 { 281 sal_Bool bRet = sal_False; 282 GetCrsr(); // ggfs. alle Cursor erzeugen lassen 283 if( IsSelOnePara() ) 284 { 285 rBuf = GetSelTxt(); 286 if( GETSELTXT_PARABRK_TO_BLANK == nHndlParaBrk ) 287 { 288 xub_StrLen nPos = 0; 289 while( STRING_NOTFOUND != 290 ( nPos = rBuf.SearchAndReplace( 0x0a, ' ', nPos )) ) 291 ; 292 } 293 else if( IsSelFullPara() && 294 GETSELTXT_PARABRK_TO_ONLYCR != nHndlParaBrk ) 295 { 296 #if defined(UNX) 297 rBuf += '\012'; 298 #else 299 rBuf += String::CreateFromAscii( 300 RTL_CONSTASCII_STRINGPARAM( "\015\012" )); 301 #endif 302 } 303 bRet = sal_True; 304 } 305 else if( IsSelection() ) 306 { 307 SvCacheStream aStream(20480); 308 #ifdef OSL_BIGENDIAN 309 aStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); 310 #else 311 aStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 312 #endif 313 WriterRef xWrt; 314 SwReaderWriter::GetWriter( String::CreateFromAscii( FILTER_TEXT ), String(), xWrt ); 315 if( xWrt.Is() ) 316 { 317 // Selektierte Bereiche in ein ASCII Dokument schreiben 318 SwWriter aWriter( aStream, *this); 319 xWrt->SetShowProgress( sal_False ); 320 321 switch( nHndlParaBrk ) 322 { 323 case GETSELTXT_PARABRK_TO_BLANK: 324 xWrt->bASCII_ParaAsBlanc = sal_True; 325 xWrt->bASCII_NoLastLineEnd = sal_True; 326 break; 327 328 case GETSELTXT_PARABRK_TO_ONLYCR: 329 xWrt->bASCII_ParaAsCR = sal_True; 330 xWrt->bASCII_NoLastLineEnd = sal_True; 331 break; 332 } 333 334 //JP 09.05.00: write as UNICODE ! (and not as ANSI) 335 SwAsciiOptions aAsciiOpt( xWrt->GetAsciiOptions() ); 336 aAsciiOpt.SetCharSet( RTL_TEXTENCODING_UCS2 ); 337 xWrt->SetAsciiOptions( aAsciiOpt ); 338 xWrt->bUCS2_WithStartChar = sal_False; 339 340 long lLen; 341 if( !IsError( aWriter.Write( xWrt ) ) && 342 STRING_MAXLEN > (( lLen = aStream.GetSize() ) 343 / sizeof( sal_Unicode )) + 1 ) 344 { 345 aStream << (sal_Unicode)'\0'; 346 347 const sal_Unicode *p = (sal_Unicode*)aStream.GetBuffer(); 348 if( p ) 349 rBuf = p; 350 else 351 { 352 sal_Unicode* pStrBuf = rBuf.AllocBuffer( xub_StrLen( 353 ( lLen / sizeof( sal_Unicode ))) ); 354 aStream.Seek( 0 ); 355 aStream.ResetError(); 356 aStream.Read( pStrBuf, lLen ); 357 pStrBuf[ lLen / sizeof( sal_Unicode ) ] = '\0'; 358 } 359 } 360 } 361 } 362 363 return sal_True; 364 } 365 366 367 368 369 370