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_sc.hxx" 30 31 32 33 // INCLUDE --------------------------------------------------------------- 34 #include <editeng/eeitem.hxx> 35 36 #include "scitems.hxx" 37 #include <editeng/editview.hxx> 38 #include <editeng/flditem.hxx> 39 #include <svx/hlnkitem.hxx> 40 #include <svl/srchitem.hxx> 41 #include <sfx2/dispatch.hxx> 42 #include <sfx2/viewfrm.hxx> 43 #include <sfx2/request.hxx> 44 #include <sfx2/objface.hxx> 45 #include <svl/stritem.hxx> 46 #include <vcl/sound.hxx> 47 48 #include "tabvwsh.hxx" 49 #include "sc.hrc" 50 #include "scmod.hxx" 51 #include "impex.hxx" 52 #include "editsh.hxx" 53 #include "dociter.hxx" 54 #include "inputhdl.hxx" 55 #include "document.hxx" 56 57 //================================================================== 58 59 String __EXPORT ScTabViewShell::GetSelectionText( sal_Bool bWholeWord ) 60 { 61 String aStrSelection; 62 63 if ( pEditShell && pEditShell == GetMySubShell() ) 64 { 65 aStrSelection = pEditShell->GetSelectionText( bWholeWord ); 66 } 67 else 68 { 69 ScRange aRange; 70 71 if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) 72 { 73 ScDocument* pDoc = GetViewData()->GetDocument(); 74 if ( bInFormatDialog && aRange.aStart.Row() != aRange.aEnd.Row() ) 75 { 76 // Range auf eine Datenzeile begrenzen 77 // (#48613# nur wenn der Aufruf aus einem Format-Dialog kommt) 78 ScHorizontalCellIterator aIter( pDoc, aRange.aStart.Tab(), 79 aRange.aStart.Col(), aRange.aStart.Row(), 80 aRange.aEnd.Col(), aRange.aEnd.Row() ); 81 SCCOL nCol; 82 SCROW nRow; 83 if ( aIter.GetNext( nCol, nRow ) ) 84 { 85 aRange.aStart.SetCol( nCol ); 86 aRange.aStart.SetRow( nRow ); 87 aRange.aEnd.SetRow( nRow ); 88 } 89 else 90 aRange.aEnd = aRange.aStart; 91 } 92 else 93 { 94 // #i111531# with 1M rows it was necessary to limit the range 95 // to the actually used data area. 96 SCCOL nCol1, nCol2; 97 SCROW nRow1, nRow2; 98 SCTAB nTab1, nTab2; 99 aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); 100 bool bShrunk; 101 pDoc->ShrinkToUsedDataArea( bShrunk, nTab1, nCol1, nRow1, nCol2, nRow2, false); 102 if (bShrunk) 103 { 104 aRange.aStart.SetCol( nCol1 ); 105 aRange.aStart.SetRow( nRow1 ); 106 aRange.aEnd.SetCol( nCol2 ); 107 aRange.aEnd.SetRow( nRow2 ); 108 } 109 } 110 111 ScImportExport aObj( pDoc, aRange ); 112 aObj.SetFormulas( GetViewData()->GetOptions().GetOption( VOPT_FORMULAS ) ); 113 rtl::OUString aExportOUString; 114 aObj.ExportString( aExportOUString ); 115 aStrSelection = aExportOUString; 116 117 aStrSelection.ConvertLineEnd( LINEEND_CR ); 118 119 // Tab/CR durch Space ersetzen, wenn fuer Dialog oder per Basic/SelectionTextExt, 120 // oder wenn es eine einzelne Zeile ist. 121 // Sonst mehrzeilig mit Tabs beibehalten (z.B. Mail oder Basic/SelectionText). 122 // Fuer Mail werden die Tabs dann spaeter in (mehrere) Spaces gewandelt. 123 124 if ( bInFormatDialog || bWholeWord || aRange.aEnd.Row() == aRange.aStart.Row() ) 125 { 126 xub_StrLen nAt; 127 while ( (nAt = aStrSelection.Search( CHAR_CR )) != STRING_NOTFOUND ) 128 aStrSelection.SetChar( nAt, ' ' ); 129 while ( (nAt = aStrSelection.Search( '\t' )) != STRING_NOTFOUND ) 130 aStrSelection.SetChar( nAt, ' ' ); 131 132 aStrSelection.EraseTrailingChars( ' ' ); 133 } 134 } 135 } 136 137 return aStrSelection; 138 } 139 140 //------------------------------------------------------------------------ 141 142 void ScTabViewShell::InsertURL( const String& rName, const String& rURL, const String& rTarget, 143 sal_uInt16 nMode ) 144 { 145 SvxLinkInsertMode eMode = (SvxLinkInsertMode) nMode; 146 sal_Bool bAsText = ( eMode != HLINK_BUTTON ); // Default ist jetzt Text 147 148 if ( bAsText ) 149 { 150 if ( GetViewData()->IsActive() ) 151 { 152 // if the view is active, always use InsertURLField, which starts EditMode 153 // and selects the URL, so it can be changed from the URL bar / dialog 154 155 InsertURLField( rName, rURL, rTarget ); 156 } 157 else 158 { 159 // #91216# if the view is not active, InsertURLField doesn't work 160 // -> use InsertBookmark to directly manipulate cell content 161 // bTryReplace=sal_True -> if cell contains only one URL, replace it 162 163 SCCOL nPosX = GetViewData()->GetCurX(); 164 SCROW nPosY = GetViewData()->GetCurY(); 165 InsertBookmark( rName, rURL, nPosX, nPosY, &rTarget, sal_True ); 166 } 167 } 168 else 169 { 170 SC_MOD()->InputEnterHandler(); 171 InsertURLButton( rName, rURL, rTarget ); 172 } 173 } 174 175 //------------------------------------------------------------------------ 176 177 // wenn CLOOKs: -> mit <editview.hxx> <flditem.hxx>in neue tabvwsh 178 179 void lcl_SelectFieldAfterInsert( EditView& rView ) 180 { 181 ESelection aSel = rView.GetSelection(); 182 if ( aSel.nStartPos == aSel.nEndPos && aSel.nStartPos > 0 ) 183 { 184 // Cursor is behind the inserted field -> extend selection to the left 185 186 --aSel.nStartPos; 187 rView.SetSelection( aSel ); 188 } 189 } 190 191 void ScTabViewShell::InsertURLField( const String& rName, const String& rURL, const String& rTarget ) 192 { 193 SvxURLField aURLField( rURL, rName, SVXURLFORMAT_REPR ); 194 aURLField.SetTargetFrame( rTarget ); 195 SvxFieldItem aURLItem( aURLField, EE_FEATURE_FIELD ); 196 197 ScViewData* pViewData = GetViewData(); 198 ScModule* pScMod = SC_MOD(); 199 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); 200 201 sal_Bool bSelectFirst = sal_False; 202 if ( !pScMod->IsEditMode() ) 203 { 204 if ( !SelectionEditable() ) 205 { 206 // no error message (may be called from drag&drop) 207 Sound::Beep(); 208 return; 209 } 210 211 // single url in cell is shown in the dialog and replaced 212 bSelectFirst = HasBookmarkAtCursor( NULL ); 213 pScMod->SetInputMode( SC_INPUT_TABLE ); 214 } 215 216 EditView* pTopView = pHdl->GetTopView(); 217 EditView* pTableView = pHdl->GetTableView(); 218 DBG_ASSERT( pTopView || pTableView, "No EditView" ); 219 220 if ( bSelectFirst ) 221 { 222 if ( pTopView ) 223 pTopView->SetSelection( ESelection(0,0,0,1) ); 224 if ( pTableView ) 225 pTableView->SetSelection( ESelection(0,0,0,1) ); 226 } 227 228 pHdl->DataChanging(); 229 230 if ( pTopView ) 231 { 232 pTopView->InsertField( aURLItem ); 233 lcl_SelectFieldAfterInsert( *pTopView ); 234 } 235 if ( pTableView ) 236 { 237 pTableView->InsertField( aURLItem ); 238 lcl_SelectFieldAfterInsert( *pTableView ); 239 } 240 241 pHdl->DataChanged(); 242 } 243 244 void ScTabViewShell::ExecSearch( SfxRequest& rReq ) 245 { 246 const SfxItemSet* pReqArgs = rReq.GetArgs(); 247 sal_uInt16 nSlot = rReq.GetSlot(); 248 const SfxPoolItem* pItem; 249 250 switch ( nSlot ) 251 { 252 case FID_SEARCH_NOW: 253 { 254 if ( pReqArgs && 255 SFX_ITEM_SET == pReqArgs->GetItemState(SID_SEARCH_ITEM, sal_False, &pItem) ) 256 { 257 DBG_ASSERT( pItem->ISA(SvxSearchItem), "falsches Item" ); 258 const SvxSearchItem* pSearchItem = (const SvxSearchItem*) pItem; 259 260 ScGlobal::SetSearchItem( *pSearchItem ); 261 SearchAndReplace( pSearchItem, sal_True, rReq.IsAPI() ); 262 rReq.Done(); 263 } 264 } 265 break; 266 267 case SID_SEARCH_ITEM: 268 if (pReqArgs && SFX_ITEM_SET == 269 pReqArgs->GetItemState(SID_SEARCH_ITEM, sal_False, &pItem)) 270 { 271 // Search-Item merken 272 DBG_ASSERT( pItem->ISA(SvxSearchItem), "falsches Item" ); 273 ScGlobal::SetSearchItem( *(const SvxSearchItem*) pItem ); 274 } 275 else 276 { 277 DBG_ERROR("SID_SEARCH_ITEM ohne Parameter"); 278 } 279 break; 280 case FID_SEARCH: 281 case FID_REPLACE: 282 case FID_REPLACE_ALL: 283 case FID_SEARCH_ALL: 284 { 285 if (pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState(nSlot, sal_False, &pItem)) 286 { 287 // SearchItem holen 288 289 SvxSearchItem aSearchItem = ScGlobal::GetSearchItem(); 290 291 // SearchItem fuellen 292 293 aSearchItem.SetSearchString(((SfxStringItem*)pItem)->GetValue()); 294 if(SFX_ITEM_SET == pReqArgs->GetItemState(FN_PARAM_1, sal_False, &pItem)) 295 aSearchItem.SetReplaceString(((SfxStringItem*)pItem)->GetValue()); 296 297 if (nSlot == FID_SEARCH) 298 aSearchItem.SetCommand(SVX_SEARCHCMD_FIND); 299 else if(nSlot == FID_REPLACE) 300 aSearchItem.SetCommand(SVX_SEARCHCMD_REPLACE); 301 else if(nSlot == FID_REPLACE_ALL) 302 aSearchItem.SetCommand(SVX_SEARCHCMD_REPLACE_ALL); 303 else 304 aSearchItem.SetCommand(SVX_SEARCHCMD_FIND_ALL); 305 306 // Request ausfuehren (dabei wird das SearchItem gespeichert) 307 308 aSearchItem.SetWhich(SID_SEARCH_ITEM); 309 GetViewData()->GetDispatcher().Execute( FID_SEARCH_NOW, 310 rReq.IsAPI() ? SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON : 311 SFX_CALLMODE_STANDARD, 312 &aSearchItem, 0L ); 313 } 314 else 315 { 316 GetViewData()->GetDispatcher().Execute( 317 SID_SEARCH_DLG, SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD ); 318 } 319 } 320 break; 321 case FID_REPEAT_SEARCH: 322 { 323 // nochmal mit ScGlobal::GetSearchItem() 324 325 SvxSearchItem aSearchItem = ScGlobal::GetSearchItem(); 326 aSearchItem.SetWhich(SID_SEARCH_ITEM); 327 GetViewData()->GetDispatcher().Execute( FID_SEARCH_NOW, 328 rReq.IsAPI() ? SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON : 329 SFX_CALLMODE_STANDARD, 330 &aSearchItem, 0L ); 331 } 332 break; 333 // case FID_SEARCH_COUNT: 334 } 335 } 336 337 //-------------------------------------------------------------------- 338 339 340 341 342 343 344