merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / docshell / docsh.cxx
blobdbe6013e234b1b1a48c26a8f61be0ee62b99f22c
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docsh.cxx,v $
10 * $Revision: 1.103.36.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 // System - Includes -----------------------------------------------------
37 #include "scitems.hxx"
38 #include <svx/eeitem.hxx>
39 #include <svx/svxenum.hxx>
40 #include <svx/algitem.hxx>
44 #include <sot/clsids.hxx>
45 #include <svtools/securityoptions.hxx>
46 #include <tools/stream.hxx>
47 #include <tools/string.hxx>
48 #include <tools/urlobj.hxx>
49 #include <vcl/msgbox.hxx>
50 #include <vcl/virdev.hxx>
51 #include <vcl/waitobj.hxx>
52 #include <svtools/ctrltool.hxx>
53 #include <svtools/sfxecode.hxx>
54 #include <svtools/zforlist.hxx>
55 #include <sfx2/app.hxx>
56 #include <sfx2/bindings.hxx>
57 #include <sfx2/dinfdlg.hxx>
58 #include <sfx2/docfile.hxx>
59 #include <sfx2/docfilt.hxx>
60 #include <sfx2/fcontnr.hxx>
61 #include <sfx2/evntconf.hxx>
62 #include <sfx2/sfx.hrc>
63 #include <sfx2/topfrm.hxx>
64 #include <sfx2/objface.hxx>
65 #include <svx/srchitem.hxx>
66 #include <svx/svxmsbas.hxx>
67 #include <svtools/fltrcfg.hxx>
68 #include <svtools/documentlockfile.hxx>
69 #include <svtools/sharecontrolfile.hxx>
70 #include <unotools/charclass.hxx>
71 #include <vcl/virdev.hxx>
72 #include "chgtrack.hxx"
73 #include "chgviset.hxx"
74 #include <sfx2/request.hxx>
75 #include <com/sun/star/document/UpdateDocMode.hpp>
78 #include "scabstdlg.hxx" //CHINA001
79 #include <sot/formats.hxx>
80 #define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC
82 // INCLUDE ---------------------------------------------------------------
84 #include "cell.hxx"
85 #include "global.hxx"
86 #include "filter.hxx"
87 #include "scmod.hxx"
88 #include "tabvwsh.hxx"
89 #include "docfunc.hxx"
90 #include "imoptdlg.hxx"
91 #include "impex.hxx"
92 #include "scresid.hxx"
93 #include "sc.hrc"
94 #include "globstr.hrc"
95 #include "scerrors.hxx"
96 #include "brdcst.hxx"
97 #include "stlpool.hxx"
98 #include "autostyl.hxx"
99 #include "attrib.hxx"
100 #include "asciiopt.hxx"
101 #include "waitoff.hxx"
102 #include "docpool.hxx" // LoadCompleted
103 #include "progress.hxx"
104 #include "pntlock.hxx"
105 #include "collect.hxx"
106 #include "docuno.hxx"
107 #include "appoptio.hxx"
108 #include "detdata.hxx"
109 #include "printfun.hxx"
110 #include "dociter.hxx"
111 #include "cellform.hxx"
112 #include "chartlis.hxx"
113 #include "hints.hxx"
114 #include "xmlwrap.hxx"
115 #include "drwlayer.hxx"
116 #include "refreshtimer.hxx"
117 #include "dbcolect.hxx"
118 #include "scextopt.hxx"
119 #include "compiler.hxx"
120 #include "cfgids.hxx"
121 #include "warnpassword.hxx"
122 #include "optsolver.hxx"
123 #include "sheetdata.hxx"
124 #include "tabprotection.hxx"
126 #include "docsh.hxx"
127 #include "docshimp.hxx"
128 #include <rtl/logfile.hxx>
130 #include <comphelper/processfactory.hxx>
131 #include "uiitems.hxx"
132 #include "cellsuno.hxx"
133 #include <com/sun/star/document/XVbaEventsHelper.hpp>
134 #include <com/sun/star/document/VbaEventId.hpp>
135 #include <basic/sbstar.hxx>
136 #include <basic/basmgr.hxx>
137 using namespace com::sun::star;
138 using namespace com::sun::star::document::VbaEventId;
140 using namespace com::sun::star;
141 using ::rtl::OUString;
142 using ::rtl::OUStringBuffer;
144 // STATIC DATA -----------------------------------------------------------
146 // Stream-Namen im Storage
148 const sal_Char __FAR_DATA ScDocShell::pStarCalcDoc[] = STRING_SCSTREAM; // "StarCalcDocument"
149 const sal_Char __FAR_DATA ScDocShell::pStyleName[] = "SfxStyleSheets";
151 // Filter-Namen (wie in sclib.cxx)
153 static const sal_Char __FAR_DATA pFilterSc50[] = "StarCalc 5.0";
154 //static const sal_Char __FAR_DATA pFilterSc50Temp[] = "StarCalc 5.0 Vorlage/Template";
155 static const sal_Char __FAR_DATA pFilterSc40[] = "StarCalc 4.0";
156 //static const sal_Char __FAR_DATA pFilterSc40Temp[] = "StarCalc 4.0 Vorlage/Template";
157 static const sal_Char __FAR_DATA pFilterSc30[] = "StarCalc 3.0";
158 //static const sal_Char __FAR_DATA pFilterSc30Temp[] = "StarCalc 3.0 Vorlage/Template";
159 static const sal_Char __FAR_DATA pFilterSc10[] = "StarCalc 1.0";
160 static const sal_Char __FAR_DATA pFilterXML[] = "StarOffice XML (Calc)";
161 static const sal_Char __FAR_DATA pFilterAscii[] = "Text - txt - csv (StarCalc)";
162 static const sal_Char __FAR_DATA pFilterLotus[] = "Lotus";
163 static const sal_Char __FAR_DATA pFilterQPro6[] = "Quattro Pro 6.0";
164 static const sal_Char __FAR_DATA pFilterExcel4[] = "MS Excel 4.0";
165 static const sal_Char __FAR_DATA pFilterEx4Temp[] = "MS Excel 4.0 Vorlage/Template";
166 static const sal_Char __FAR_DATA pFilterExcel5[] = "MS Excel 5.0/95";
167 static const sal_Char __FAR_DATA pFilterEx5Temp[] = "MS Excel 5.0/95 Vorlage/Template";
168 static const sal_Char __FAR_DATA pFilterExcel95[] = "MS Excel 95";
169 static const sal_Char __FAR_DATA pFilterEx95Temp[] = "MS Excel 95 Vorlage/Template";
170 static const sal_Char __FAR_DATA pFilterExcel97[] = "MS Excel 97";
171 static const sal_Char __FAR_DATA pFilterEx97Temp[] = "MS Excel 97 Vorlage/Template";
172 static const sal_Char __FAR_DATA pFilterEx07Xml[] = "MS Excel 2007 XML";
173 static const sal_Char __FAR_DATA pFilterDBase[] = "dBase";
174 static const sal_Char __FAR_DATA pFilterDif[] = "DIF";
175 static const sal_Char __FAR_DATA pFilterSylk[] = "SYLK";
176 static const sal_Char __FAR_DATA pFilterHtml[] = "HTML (StarCalc)";
177 static const sal_Char __FAR_DATA pFilterHtmlWebQ[] = "calc_HTML_WebQuery";
178 static const sal_Char __FAR_DATA pFilterRtf[] = "Rich Text Format (StarCalc)";
180 //----------------------------------------------------------------------
182 #define ScDocShell
183 #include "scslots.hxx"
186 SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL))
188 SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
191 // GlobalName der aktuellen Version:
192 SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "scalc" )
194 TYPEINIT1( ScDocShell, SfxObjectShell ); // SfxInPlaceObject: kein Type-Info ?
196 //------------------------------------------------------------------
198 void __EXPORT ScDocShell::FillClass( SvGlobalName* pClassName,
199 sal_uInt32* pFormat,
200 String* /* pAppName */,
201 String* pFullTypeName,
202 String* pShortTypeName,
203 sal_Int32 nFileFormat,
204 sal_Bool bTemplate /* = sal_False */) const
206 if ( nFileFormat == SOFFICE_FILEFORMAT_60 )
208 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
209 *pFormat = SOT_FORMATSTR_ID_STARCALC_60;
210 *pFullTypeName = String( ScResId( SCSTR_LONG_SCDOC_NAME ) );
211 *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
213 else if ( nFileFormat == SOFFICE_FILEFORMAT_8 )
215 *pClassName = SvGlobalName( SO3_SC_CLASSID_60 );
216 *pFormat = bTemplate ? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE : SOT_FORMATSTR_ID_STARCALC_8;
217 *pFullTypeName = String( RTL_CONSTASCII_USTRINGPARAM("calc8") );
218 *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
220 else
222 DBG_ERROR("wat fuer ne Version?");
226 //------------------------------------------------------------------
228 void ScDocShell::DoEnterHandler()
230 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
231 if (pViewSh)
232 if (pViewSh->GetViewData()->GetDocShell() == this)
233 SC_MOD()->InputEnterHandler();
236 //------------------------------------------------------------------
238 SCTAB ScDocShell::GetSaveTab()
240 SCTAB nTab = 0;
241 ScTabViewShell* pSh = GetBestViewShell();
242 if (pSh)
244 const ScMarkData& rMark = pSh->GetViewData()->GetMarkData();
245 for ( nTab = 0; nTab <= MAXTAB; nTab++ ) // erste markierte Tabelle
246 if ( rMark.GetTableSelect( nTab ) )
247 break;
249 return nTab;
252 sal_uInt16 ScDocShell::GetHiddenInformationState( sal_uInt16 nStates )
254 // get global state like HIDDENINFORMATION_DOCUMENTVERSIONS
255 sal_uInt16 nState = SfxObjectShell::GetHiddenInformationState( nStates );
257 if ( nStates & HIDDENINFORMATION_RECORDEDCHANGES )
259 if ( aDocument.GetChangeTrack() && aDocument.GetChangeTrack()->GetFirst() )
260 nState |= HIDDENINFORMATION_RECORDEDCHANGES;
262 if ( nStates & HIDDENINFORMATION_NOTES )
264 SCTAB nTableCount = aDocument.GetTableCount();
265 SCTAB nTable = 0;
266 sal_Bool bFound(sal_False);
267 while ( nTable < nTableCount && !bFound )
269 ScCellIterator aCellIter( &aDocument, 0,0, nTable, MAXCOL,MAXROW, nTable );
270 for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bFound; pCell = aCellIter.GetNext() )
271 if (pCell->HasNote())
272 bFound = sal_True;
273 nTable++;
276 if (bFound)
277 nState |= HIDDENINFORMATION_NOTES;
280 return nState;
283 void ScDocShell::BeforeXMLLoading()
285 aDocument.DisableIdle( TRUE );
286 // suppress VBA events when loading the xml
287 uno::Reference< document::XVbaEventsHelper > xEvt( aDocument.GetVbaEventsHelper() );
288 if ( xEvt.is() )
289 xEvt->setIgnoreEvents( sal_True );
291 // if VBA enabled then we need to
292 // prevent unnecessary broadcasts and updates
293 DBG_ASSERT(pModificator == NULL, "The Modificator should not exist");
294 pModificator = new ScDocShellModificator( *this );
296 aDocument.SetImportingXML( TRUE );
297 aDocument.EnableExecuteLink( false ); // #i101304# to be safe, prevent nested loading from external references
298 aDocument.EnableUndo( FALSE );
299 // prevent unnecessary broadcasts and "half way listeners"
300 aDocument.SetInsertingFromOtherDoc( TRUE );
302 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
303 ScColumn::bDoubleAlloc = sal_True;
306 void ScDocShell::AfterXMLLoading(sal_Bool bRet)
308 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
310 UpdateLinks();
311 // don't prevent establishing of listeners anymore
312 aDocument.SetInsertingFromOtherDoc( FALSE );
313 if ( bRet )
315 ScChartListenerCollection* pChartListener = aDocument.GetChartListenerCollection();
316 if (pChartListener)
317 pChartListener->UpdateDirtyCharts();
319 // #95582#; set the table names of linked tables to the new path
320 SCTAB nTabCount = aDocument.GetTableCount();
321 for (SCTAB i = 0; i < nTabCount; ++i)
323 if (aDocument.IsLinked( i ))
325 String aName;
326 aDocument.GetName(i, aName);
327 String aLinkTabName = aDocument.GetLinkTab(i);
328 xub_StrLen nLinkTabNameLength = aLinkTabName.Len();
329 xub_StrLen nNameLength = aName.Len();
330 if (nLinkTabNameLength < nNameLength)
333 // remove the quottes on begin and end of the docname and restore the escaped quotes
334 const sal_Unicode* pNameBuffer = aName.GetBuffer();
335 if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos
336 ScGlobal::UnicodeStrChr( pNameBuffer, SC_COMPILER_FILE_TAB_SEP ) )
338 rtl::OUStringBuffer aDocURLBuffer;
339 BOOL bQuote = TRUE; // Dokumentenname ist immer quoted
340 ++pNameBuffer;
341 while ( bQuote && *pNameBuffer )
343 if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' )
344 bQuote = FALSE;
345 else if( !(*pNameBuffer == '\\' && *(pNameBuffer+1) == '\'') )
346 aDocURLBuffer.append(*pNameBuffer); // falls escaped Quote: nur Quote in den Namen
347 ++pNameBuffer;
351 if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP ) // after the last quote of the docname should be the # char
353 xub_StrLen nIndex = nNameLength - nLinkTabNameLength;
354 INetURLObject aINetURLObject(aDocURLBuffer.makeStringAndClear());
355 if( aName.Equals(aLinkTabName, nIndex, nLinkTabNameLength) &&
356 (aName.GetChar(nIndex - 1) == '#') && // before the table name should be the # char
357 !aINetURLObject.HasError()) // the docname should be a valid URL
359 aName = ScGlobal::GetDocTabName( aDocument.GetLinkDoc( i ), aDocument.GetLinkTab( i ) );
360 aDocument.RenameTab(i, aName, TRUE, TRUE);
362 // else; nothing has to happen, because it is a user given name
364 // else; nothing has to happen, because it is a user given name
366 // else; nothing has to happen, because it is a user given name
368 // else; nothing has to happen, because it is a user given name
372 ScColumn::bDoubleAlloc = sal_False;
374 else
375 aDocument.SetInsertingFromOtherDoc( FALSE );
376 // add vba globals ( if they are availabl )
377 SfxObjectShell* pShell = aDocument.GetDocumentShell();
378 if ( pShell )
380 uno::Any aGlobs;
381 uno::Sequence< uno::Any > aArgs(1);
382 aArgs[ 0 ] <<= pShell->GetModel();
383 aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs );
384 pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs );
386 // suppress VBA events when loading the xml
387 uno::Reference< document::XVbaEventsHelper > xEvt( aDocument.GetVbaEventsHelper() );
388 if ( xEvt.is() )
389 xEvt->setIgnoreEvents( sal_False );
390 aDocument.SetImportingXML( FALSE );
391 aDocument.EnableExecuteLink( true );
392 aDocument.EnableUndo( TRUE );
393 bIsEmpty = FALSE;
395 if (pModificator)
397 delete pModificator;
398 pModificator = NULL;
400 else
402 DBG_ERROR("The Modificator should exist");
405 aDocument.DisableIdle( FALSE );
408 BOOL ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
410 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::LoadXML" );
412 // MacroCallMode is no longer needed, state is kept in SfxObjectShell now
414 // no Seek(0) here - always loading from storage, GetInStream must not be called
416 BeforeXMLLoading();
418 // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked
419 // from an external component. The XMLFromWrapper flag is only set here, when called
420 // through ScDocShell.
421 aDocument.SetXMLFromWrapper( TRUE );
423 ScXMLImportWrapper aImport( aDocument, pLoadMedium, xStor );
425 sal_Bool bRet(sal_False);
426 ErrCode nError = ERRCODE_NONE;
427 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
428 bRet = aImport.Import(sal_False, nError);
429 else
430 bRet = aImport.Import(sal_True, nError);
432 if ( nError )
433 pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
435 aDocument.SetXMLFromWrapper( FALSE );
436 AfterXMLLoading(bRet);
438 //! row heights...
440 return bRet;
443 BOOL ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
445 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::SaveXML" );
447 aDocument.DisableIdle( TRUE );
449 ScXMLImportWrapper aImport( aDocument, pSaveMedium, xStor );
450 sal_Bool bRet(sal_False);
451 if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
452 bRet = aImport.Export(sal_False);
453 else
454 bRet = aImport.Export(sal_True);
456 aDocument.DisableIdle( FALSE );
458 return bRet;
461 namespace {
463 class DocLoadChecker
465 public:
466 explicit DocLoadChecker(ScDocument* pDoc) :
467 mpDoc(pDoc)
469 mpDoc->SetLoadingMedium(true);
472 ~DocLoadChecker()
474 mpDoc->SetLoadingMedium(false);
476 private:
477 ScDocument* mpDoc;
482 BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium )
484 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" );
485 DocLoadChecker aChecker(&aDocument);
486 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
488 // only the latin script language is loaded
489 // -> initialize the others from options (before loading)
490 InitOptions();
492 GetUndoManager()->Clear();
494 BOOL bRet = SfxObjectShell::Load( rMedium );
495 if( bRet )
497 if (GetMedium())
499 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
500 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
504 // prepare a valid document for XML filter
505 // (for ConvertFrom, InitNew is called before)
506 aDocument.MakeTable(0);
507 aDocument.GetStyleSheetPool()->CreateStandardStyles();
508 aDocument.UpdStlShtPtrsFrmNms();
510 bRet = LoadXML( &rMedium, NULL );
514 if (!bRet && !rMedium.GetError())
515 rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
517 if (rMedium.GetError())
518 SetError( rMedium.GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
520 InitItems();
521 CalcOutputFactor();
523 // #73762# invalidate eventually temporary table areas
524 if ( bRet )
525 aDocument.InvalidateTableArea();
527 bIsEmpty = FALSE;
528 FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
529 return bRet;
532 void lcl_processCompatibleSfxHint( uno::Reference< document::XVbaEventsHelper > xVbaEventsHelper, const SfxHint& rHint )
534 if (rHint.ISA(ScTablesHint) )
536 USHORT nId = ((ScTablesHint&)rHint).GetId();
537 SCTAB nTab = ((ScTablesHint&)rHint).GetTab1();
538 if( nId == SC_TAB_INSERTED )
540 uno::Sequence< uno::Any > aArgs(1);
541 aArgs[0] <<= nTab;
542 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_NEWSHEET, aArgs );
545 else if ( rHint.ISA( SfxEventHint ) )
547 ULONG nEventId = ((SfxEventHint&)rHint).GetEventId();
548 switch ( nEventId )
550 case SFX_EVENT_ACTIVATEDOC:
552 uno::Sequence< uno::Any > aArgs;
553 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_ACTIVATE, aArgs );
555 break;
556 case SFX_EVENT_DEACTIVATEDOC:
558 uno::Sequence< uno::Any > aArgs;
559 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_DEACTIVATE, aArgs );
561 break;
562 /*case SFX_EVENT_CLOSEDOC :
564 uno::Sequence< uno::Any > aArgs;
565 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_CLOSE, aArgs );
567 break;
568 case SFX_EVENT_CLOSEVIEW :
570 uno::Sequence< uno::Any > aArgs;
571 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_WINDOWCOLSE, aArgs );
573 break;
575 case SFX_EVENT_OPENDOC:
577 // some later than workbook activate.
578 uno::Sequence< uno::Any > aArgs;
579 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_OPEN, aArgs );
581 break;
582 default:
585 break;
590 void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
592 uno::Reference< document::XVbaEventsHelper > xVbaEventsHelper ( aDocument.GetVbaEventsHelper(), uno::UNO_QUERY );
593 if ( xVbaEventsHelper.is() )
595 lcl_processCompatibleSfxHint( xVbaEventsHelper, rHint );
597 if (rHint.ISA(SfxSimpleHint)) // ohne Parameter
599 ULONG nSlot = ((const SfxSimpleHint&)rHint).GetId();
600 switch ( nSlot )
602 case SFX_HINT_TITLECHANGED:
603 aDocument.SetName( SfxShell::GetName() );
604 // RegisterNewTargetNames gibts nicht mehr
605 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED )); // Navigator
606 break;
609 else if (rHint.ISA(SfxStyleSheetHint)) // Vorlagen geaendert
610 NotifyStyle((const SfxStyleSheetHint&) rHint);
611 else if (rHint.ISA(ScAutoStyleHint))
613 //! direct call for AutoStyles
615 // this is called synchronously from ScInterpreter::ScStyle,
616 // modifying the document must be asynchronous
617 // (handled by AddInitial)
619 ScAutoStyleHint& rStlHint = (ScAutoStyleHint&)rHint;
620 ScRange aRange = rStlHint.GetRange();
621 String aName1 = rStlHint.GetStyle1();
622 String aName2 = rStlHint.GetStyle2();
623 UINT32 nTimeout = rStlHint.GetTimeout();
625 if (!pAutoStyleList)
626 pAutoStyleList = new ScAutoStyleList(this);
627 pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 );
629 else if ( rHint.ISA( SfxEventHint ) )
631 ULONG nEventId = ((SfxEventHint&)rHint).GetEventId();
632 switch ( nEventId )
634 case SFX_EVENT_LOADFINISHED:
636 // the readonly documents should not be opened in shared mode
637 if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
639 if ( SwitchToShared( sal_True, sal_False ) )
641 ScViewData* pViewData = GetViewData();
642 ScTabView* pTabView = ( pViewData ? dynamic_cast< ScTabView* >( pViewData->GetView() ) : NULL );
643 if ( pTabView )
645 pTabView->UpdateLayerLocks();
648 else
650 // switching to shared mode has failed, the document should be opened readonly
651 // TODO/LATER: And error message should be shown here probably
652 SetReadOnlyUI( sal_True );
656 break;
657 case SFX_EVENT_VIEWCREATED:
659 if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
661 ScAppOptions aAppOptions = SC_MOD()->GetAppOptions();
662 if ( aAppOptions.GetShowSharedDocumentWarning() )
664 WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
665 ScGlobal::GetRscString( STR_SHARED_DOC_WARNING ) );
666 aBox.SetDefaultCheckBoxText();
667 aBox.Execute();
668 BOOL bChecked = aBox.GetCheckBoxState();
669 if ( bChecked )
671 aAppOptions.SetShowSharedDocumentWarning( !bChecked );
672 SC_MOD()->SetAppOptions( aAppOptions );
677 break;
678 case SFX_EVENT_SAVEDOC:
680 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
682 bool bSuccess = false;
683 bool bRetry = true;
684 while ( bRetry )
686 bRetry = false;
687 uno::Reference< frame::XModel > xModel;
690 // load shared file
691 xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
692 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
694 // check if shared flag is set in shared file
695 bool bShared = false;
696 ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
697 ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : NULL );
698 if ( pSharedDocShell )
700 bShared = pSharedDocShell->HasSharedXMLFlagSet();
703 // #i87870# check if shared status was disabled and enabled again
704 bool bOwnEntry = false;
705 bool bEntriesNotAccessible = false;
708 ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
709 bOwnEntry = aControlFile.HasOwnEntry();
711 catch ( uno::Exception& )
713 bEntriesNotAccessible = true;
716 if ( bShared && bOwnEntry )
718 uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
720 if ( xStorable->isReadonly() )
722 xCloseable->close( sal_True );
724 String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
725 bool bNoLockAccess = false;
728 ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
729 uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData();
730 if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID )
732 if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 )
734 aUserName = aData[LOCKFILE_OOOUSERNAME_ID];
736 else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 )
738 aUserName = aData[LOCKFILE_SYSUSERNAME_ID];
742 catch ( uno::Exception& )
744 bNoLockAccess = true;
747 if ( bNoLockAccess )
749 // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
750 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
752 else
754 String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER ) );
755 aMessage.SearchAndReplaceAscii( "%1", aUserName );
757 WarningBox aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL | WB_DEF_RETRY ), aMessage );
758 if ( aBox.Execute() == RET_RETRY )
760 bRetry = true;
764 else
766 // merge changes from shared file into temp file
767 bool bSaveToShared = false;
768 if ( pSharedDocShell )
770 bSaveToShared = MergeSharedDocument( pSharedDocShell );
773 // close shared file
774 xCloseable->close( sal_True );
776 // TODO: keep file lock on shared file
778 // store to shared file
779 if ( bSaveToShared )
781 bool bChangedViewSettings = false;
782 ScChangeViewSettings* pChangeViewSet = aDocument.GetChangeViewSettings();
783 if ( pChangeViewSet && pChangeViewSet->ShowChanges() )
785 pChangeViewSet->SetShowChanges( FALSE );
786 pChangeViewSet->SetShowAccepted( FALSE );
787 aDocument.SetChangeViewSettings( *pChangeViewSet );
788 bChangedViewSettings = true;
791 uno::Reference< frame::XStorable > xStor( GetModel(), uno::UNO_QUERY_THROW );
792 // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
793 uno::Sequence< beans::PropertyValue > aValues(1);
794 aValues[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
795 aValues[0].Value <<= ::rtl::OUString( GetMedium()->GetFilter()->GetFilterName() );
797 SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
798 if ( pPasswordItem && pPasswordItem->GetValue().Len() )
800 aValues.realloc( 2 );
801 aValues[1].Name = ::rtl::OUString::createFromAscii( "Password" );
802 aValues[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() );
805 SC_MOD()->SetInSharedDocSaving( true );
806 xStor->storeToURL( GetSharedFileURL(), aValues );
807 SC_MOD()->SetInSharedDocSaving( false );
809 if ( bChangedViewSettings )
811 pChangeViewSet->SetShowChanges( TRUE );
812 pChangeViewSet->SetShowAccepted( TRUE );
813 aDocument.SetChangeViewSettings( *pChangeViewSet );
817 bSuccess = true;
818 GetUndoManager()->Clear();
821 else
823 xCloseable->close( sal_True );
825 if ( bEntriesNotAccessible )
827 // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
828 ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
830 else
832 WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
833 ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
834 aBox.Execute();
836 SfxBindings* pBindings = GetViewBindings();
837 if ( pBindings )
839 pBindings->ExecuteSynchron( SID_SAVEASDOC );
844 catch ( uno::Exception& )
846 DBG_ERROR( "SFX_EVENT_SAVEDOC: caught exception\n" );
847 SC_MOD()->SetInSharedDocSaving( false );
851 uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
852 xClose->close( sal_True );
854 catch ( uno::Exception& )
860 if ( !bSuccess )
861 SetError( ERRCODE_IO_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) ); // this error code will produce no error message, but will break the further saving process
864 break;
865 case SFX_EVENT_SAVEDOCDONE:
867 if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
870 UseSheetSaveEntries(); // use positions from saved file for next saving
872 break;
873 case SFX_EVENT_SAVEASDOCDONE:
874 // new positions are used after "save" and "save as", but not "save to"
875 UseSheetSaveEntries(); // use positions from saved file for next saving
876 break;
877 default:
880 break;
885 // Inhalte fuer Organizer laden
888 BOOL __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium )
890 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::LoadFrom" );
891 DocLoadChecker aChecker(&aDocument);
892 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
894 WaitObject aWait( GetActiveDialogParent() );
896 BOOL bRet = FALSE;
898 if (GetMedium())
900 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
901 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
904 // until loading/saving only the styles in XML is implemented,
905 // load the whole file
906 bRet = LoadXML( &rMedium, NULL );
907 InitItems();
909 SfxObjectShell::LoadFrom( rMedium );
911 return bRet;
914 static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert)
916 OUStringBuffer aBuf;
917 OUString aTokens[2];
918 sal_Int32 n = rOption.getLength();
919 const sal_Unicode* p = rOption.getStr();
920 sal_Int32 nTokenId = 0;
921 for (sal_Int32 i = 0; i < n; ++i)
923 const sal_Unicode c = p[i];
924 if (c == sal_Unicode(' '))
926 if (aBuf.getLength())
927 aTokens[nTokenId++] = aBuf.makeStringAndClear();
929 else
930 aBuf.append(c);
932 if (nTokenId >= 2)
933 break;
936 if (aBuf.getLength())
937 aTokens[nTokenId] = aBuf.makeStringAndClear();
939 rLang = static_cast<LanguageType>(aTokens[0].toInt32());
940 rDateConvert = static_cast<bool>(aTokens[1].toInt32());
943 BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
945 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" );
946 DocLoadChecker aChecker(&aDocument);
948 BOOL bRet = FALSE; // FALSE heisst Benutzerabbruch !!
949 // bei Fehler: Fehler am Stream setzen!!
951 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
953 GetUndoManager()->Clear();
955 // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
956 BOOL bSetColWidths = FALSE;
957 BOOL bSetSimpleTextColWidths = FALSE;
958 BOOL bSimpleColWidth[MAXCOLCOUNT];
959 memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(BOOL) );
960 ScRange aColWidthRange;
961 // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
962 BOOL bSetRowHeights = FALSE;
964 aConvFilterName.Erase(); //@ #BugId 54198
966 // Alle Filter brauchen die komplette Datei am Stueck (nicht asynchron),
967 // darum vorher per CreateFileStream dafuer sorgen, dass die komplette
968 // Datei uebertragen wird.
969 rMedium.GetPhysicalName(); //! CreateFileStream direkt rufen, wenn verfuegbar
971 SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
972 nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
974 const SfxFilter* pFilter = rMedium.GetFilter();
975 if (pFilter)
977 String aFltName = pFilter->GetFilterName();
979 aConvFilterName=aFltName; //@ #BugId 54198
981 BOOL bCalc3 = ( aFltName.EqualsAscii(pFilterSc30) );
982 BOOL bCalc4 = ( aFltName.EqualsAscii(pFilterSc40) );
983 if (!bCalc3 && !bCalc4)
984 aDocument.SetInsertingFromOtherDoc( TRUE );
986 if (aFltName.EqualsAscii(pFilterXML))
987 bRet = LoadXML( &rMedium, NULL );
988 else if (aFltName.EqualsAscii(pFilterSc10))
990 SvStream* pStream = rMedium.GetInStream();
991 if (pStream)
993 FltError eError = ScFormatFilter::Get().ScImportStarCalc10( *pStream, &aDocument );
994 if (eError != eERR_OK)
996 if (!GetError())
997 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
999 else
1000 bRet = TRUE;
1003 else if (aFltName.EqualsAscii(pFilterLotus))
1005 String sItStr;
1006 SfxItemSet* pSet = rMedium.GetItemSet();
1007 const SfxPoolItem* pItem;
1008 if ( pSet && SFX_ITEM_SET ==
1009 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
1011 sItStr = ((const SfxStringItem*)pItem)->GetValue();
1014 if (sItStr.Len() == 0)
1016 // default for lotus import (from API without options):
1017 // IBM_437 encoding
1018 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 );
1021 ScColumn::bDoubleAlloc = TRUE;
1022 FltError eError = ScFormatFilter::Get().ScImportLotus123( rMedium, &aDocument,
1023 ScGlobal::GetCharsetValue(sItStr));
1024 ScColumn::bDoubleAlloc = FALSE;
1025 if (eError != eERR_OK)
1027 if (!GetError())
1028 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1030 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1031 bRet = TRUE;
1033 else
1034 bRet = TRUE;
1035 bSetColWidths = TRUE;
1036 bSetRowHeights = TRUE;
1038 else if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterExcel5) ||
1039 aFltName.EqualsAscii(pFilterExcel95) || aFltName.EqualsAscii(pFilterExcel97) ||
1040 aFltName.EqualsAscii(pFilterEx4Temp) || aFltName.EqualsAscii(pFilterEx5Temp) ||
1041 aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) )
1043 EXCIMPFORMAT eFormat = EIF_AUTO;
1044 if ( aFltName.EqualsAscii(pFilterExcel4) || aFltName.EqualsAscii(pFilterEx4Temp) )
1045 eFormat = EIF_BIFF_LE4;
1046 else if ( aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
1047 aFltName.EqualsAscii(pFilterEx5Temp) || aFltName.EqualsAscii(pFilterEx95Temp) )
1048 eFormat = EIF_BIFF5;
1049 else if ( aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx97Temp) )
1050 eFormat = EIF_BIFF8;
1052 MakeDrawLayer(); //! im Filter
1053 CalcOutputFactor(); // #93255# prepare update of row height
1054 ScColumn::bDoubleAlloc = TRUE;
1055 FltError eError = ScFormatFilter::Get().ScImportExcel( rMedium, &aDocument, eFormat );
1056 ScColumn::bDoubleAlloc = FALSE;
1057 aDocument.UpdateFontCharSet();
1058 if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
1059 aDocument.UpdateChartListenerCollection(); //! fuer alle Importe?
1061 // #75299# all graphics objects must have names
1062 aDocument.EnsureGraphicNames();
1064 if (eError == SCWARN_IMPORT_RANGE_OVERFLOW)
1066 if (!GetError())
1067 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1068 bRet = TRUE;
1070 else if (eError != eERR_OK)
1072 if (!GetError())
1073 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1075 else
1076 bRet = TRUE;
1078 // #93255# update of row height done inside of Excel filter to speed up chart import
1079 // bSetRowHeights = TRUE; // #75357# optimal row heights must be updated
1081 else if (aFltName.EqualsAscii(pFilterAscii))
1083 SfxItemSet* pSet = rMedium.GetItemSet();
1084 const SfxPoolItem* pItem;
1085 ScAsciiOptions aOptions;
1086 BOOL bOptInit = FALSE;
1088 if ( pSet && SFX_ITEM_SET ==
1089 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
1091 aOptions.ReadFromString( ((const SfxStringItem*)pItem)->GetValue() );
1092 bOptInit = TRUE;
1095 if ( !bOptInit )
1097 // default for ascii import (from API without options):
1098 // ISO8859-1/MS_1252 encoding, comma, double quotes
1100 aOptions.SetCharSet( RTL_TEXTENCODING_MS_1252 );
1101 aOptions.SetFieldSeps( (sal_Unicode) ',' );
1102 aOptions.SetTextSep( (sal_Unicode) '"' );
1105 FltError eError = eERR_OK;
1106 BOOL bOverflow = FALSE;
1108 if( ! rMedium.IsStorage() )
1110 ScImportExport aImpEx( &aDocument );
1111 aImpEx.SetExtOptions( aOptions );
1113 SvStream* pInStream = rMedium.GetInStream();
1114 if (pInStream)
1116 pInStream->SetStreamCharSet( aOptions.GetCharSet() );
1117 pInStream->Seek( 0 );
1118 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL() );
1119 eError = bRet ? eERR_OK : SCERR_IMPORT_CONNECT;
1120 aDocument.StartAllListeners();
1121 aDocument.SetDirty();
1122 bOverflow = aImpEx.IsOverflow();
1124 else
1126 DBG_ERROR( "No Stream" );
1130 if (eError != eERR_OK)
1132 if (!GetError())
1133 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1135 else if ( bOverflow )
1137 if (!GetError())
1138 SetError(SCWARN_IMPORT_RANGE_OVERFLOW, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1140 bSetColWidths = TRUE;
1141 bSetSimpleTextColWidths = TRUE;
1143 else if (aFltName.EqualsAscii(pFilterDBase))
1145 String sItStr;
1146 SfxItemSet* pSet = rMedium.GetItemSet();
1147 const SfxPoolItem* pItem;
1148 if ( pSet && SFX_ITEM_SET ==
1149 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
1151 sItStr = ((const SfxStringItem*)pItem)->GetValue();
1154 if (sItStr.Len() == 0)
1156 // default for dBase import (from API without options):
1157 // IBM_850 encoding
1159 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
1162 ULONG eError = DBaseImport( rMedium.GetPhysicalName(),
1163 ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );
1165 if (eError != eERR_OK)
1167 if (!GetError())
1168 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1169 bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW );
1171 else
1172 bRet = TRUE;
1174 aColWidthRange.aStart.SetRow( 1 ); // Spaltenheader nicht
1175 bSetColWidths = TRUE;
1176 bSetSimpleTextColWidths = TRUE;
1177 // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
1178 for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
1180 if ( !bSimpleColWidth[nCol] )
1181 bSetRowHeights = TRUE;
1184 else if (aFltName.EqualsAscii(pFilterDif))
1186 SvStream* pStream = rMedium.GetInStream();
1187 if (pStream)
1189 FltError eError;
1190 String sItStr;
1191 SfxItemSet* pSet = rMedium.GetItemSet();
1192 const SfxPoolItem* pItem;
1193 if ( pSet && SFX_ITEM_SET ==
1194 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
1196 sItStr = ((const SfxStringItem*)pItem)->GetValue();
1199 if (sItStr.Len() == 0)
1201 // default for DIF import (from API without options):
1202 // ISO8859-1/MS_1252 encoding
1204 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
1207 eError = ScFormatFilter::Get().ScImportDif( *pStream, &aDocument, ScAddress(0,0,0),
1208 ScGlobal::GetCharsetValue(sItStr));
1209 if (eError != eERR_OK)
1211 if (!GetError())
1212 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1214 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1215 bRet = TRUE;
1217 else
1218 bRet = TRUE;
1220 bSetColWidths = TRUE;
1221 bSetSimpleTextColWidths = TRUE;
1222 bSetRowHeights = TRUE;
1224 else if (aFltName.EqualsAscii(pFilterSylk))
1226 FltError eError = SCERR_IMPORT_UNKNOWN;
1227 if( !rMedium.IsStorage() )
1229 ScImportExport aImpEx( &aDocument );
1231 SvStream* pInStream = rMedium.GetInStream();
1232 if (pInStream)
1234 pInStream->Seek( 0 );
1235 bRet = aImpEx.ImportStream( *pInStream, rMedium.GetBaseURL(), SOT_FORMATSTR_ID_SYLK );
1236 eError = bRet ? eERR_OK : SCERR_IMPORT_UNKNOWN;
1237 aDocument.StartAllListeners();
1238 aDocument.SetDirty();
1240 else
1242 DBG_ERROR( "No Stream" );
1246 if ( eError != eERR_OK && !GetError() )
1247 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1248 bSetColWidths = TRUE;
1249 bSetSimpleTextColWidths = TRUE;
1250 bSetRowHeights = TRUE;
1252 else if (aFltName.EqualsAscii(pFilterQPro6))
1254 ScColumn::bDoubleAlloc = TRUE;
1255 FltError eError = ScFormatFilter::Get().ScImportQuattroPro( rMedium, &aDocument);
1256 ScColumn::bDoubleAlloc = FALSE;
1257 if (eError != eERR_OK)
1259 if (!GetError())
1260 SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
1261 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1262 bRet = TRUE;
1264 else
1265 bRet = TRUE;
1266 // TODO: Filter should set column widths. Not doing it here, it may
1267 // result in very narrow or wide columns, depending on content.
1268 // Setting row heights makes cells with font size attribution or
1269 // wrapping enabled look nicer..
1270 bSetRowHeights = TRUE;
1272 else if (aFltName.EqualsAscii(pFilterRtf))
1274 FltError eError = SCERR_IMPORT_UNKNOWN;
1275 if( !rMedium.IsStorage() )
1277 SvStream* pInStream = rMedium.GetInStream();
1278 if (pInStream)
1280 pInStream->Seek( 0 );
1281 ScRange aRange;
1282 eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange );
1283 if (eError != eERR_OK)
1285 if (!GetError())
1286 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1288 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1289 bRet = TRUE;
1291 else
1292 bRet = TRUE;
1293 aDocument.StartAllListeners();
1294 aDocument.SetDirty();
1295 bSetColWidths = TRUE;
1296 bSetRowHeights = TRUE;
1298 else
1300 DBG_ERROR( "No Stream" );
1304 if ( eError != eERR_OK && !GetError() )
1305 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1307 else if (aFltName.EqualsAscii(pFilterHtml) || aFltName.EqualsAscii(pFilterHtmlWebQ))
1309 FltError eError = SCERR_IMPORT_UNKNOWN;
1310 BOOL bWebQuery = aFltName.EqualsAscii(pFilterHtmlWebQ);
1311 if( !rMedium.IsStorage() )
1313 SvStream* pInStream = rMedium.GetInStream();
1314 if (pInStream)
1316 LanguageType eLang = LANGUAGE_SYSTEM;
1317 bool bDateConvert = false;
1318 SfxItemSet* pSet = rMedium.GetItemSet();
1319 const SfxPoolItem* pItem;
1320 if ( pSet && SFX_ITEM_SET ==
1321 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
1323 String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue();
1324 lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert);
1327 pInStream->Seek( 0 );
1328 ScRange aRange;
1329 // HTML macht eigenes ColWidth/RowHeight
1330 CalcOutputFactor();
1331 SvNumberFormatter aNumFormatter(aDocument.GetServiceManager(), eLang);
1332 eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange,
1333 GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert );
1334 if (eError != eERR_OK)
1336 if (!GetError())
1337 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1339 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1340 bRet = TRUE;
1342 else
1343 bRet = TRUE;
1344 aDocument.StartAllListeners();
1345 aDocument.SetDirty();
1347 else
1349 DBG_ERROR( "No Stream" );
1353 if ( eError != eERR_OK && !GetError() )
1354 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1356 else
1358 if (!GetError())
1359 SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1362 if (!bCalc3)
1363 aDocument.SetInsertingFromOtherDoc( FALSE );
1365 else
1367 DBG_ERROR("Kein Filter bei ConvertFrom");
1370 InitItems();
1371 CalcOutputFactor();
1372 if ( bRet && (bSetColWidths || bSetRowHeights) )
1373 { // Spaltenbreiten/Zeilenhoehen anpassen, Basis 100% Zoom
1374 Fraction aZoom( 1, 1 );
1375 double nPPTX = ScGlobal::nScreenPPTX * (double) aZoom
1376 / GetOutputFactor(); // Faktor ist Drucker zu Bildschirm
1377 double nPPTY = ScGlobal::nScreenPPTY * (double) aZoom;
1378 VirtualDevice aVirtDev;
1379 // all sheets (for Excel import)
1380 SCTAB nTabCount = aDocument.GetTableCount();
1381 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
1383 SCCOL nEndCol;
1384 SCROW nEndRow;
1385 aDocument.GetCellArea( nTab, nEndCol, nEndRow );
1386 aColWidthRange.aEnd.SetCol( nEndCol );
1387 aColWidthRange.aEnd.SetRow( nEndRow );
1388 ScMarkData aMark;
1389 aMark.SetMarkArea( aColWidthRange );
1390 aMark.MarkToMulti();
1391 // Reihenfolge erst Breite dann Hoehe ist wichtig (vergl. hund.rtf)
1392 if ( bSetColWidths )
1394 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
1396 USHORT nWidth = aDocument.GetOptimalColWidth(
1397 nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, FALSE, &aMark,
1398 (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
1399 aDocument.SetColWidth( nCol, nTab,
1400 nWidth + (USHORT)ScGlobal::nLastColWidthExtra );
1403 // if ( bSetRowHeights )
1404 // {
1405 // // nExtra must be 0
1406 // aDocument.SetOptimalHeight( 0, nEndRow, nTab, 0, &aVirtDev,
1407 // nPPTX, nPPTY, aZoom, aZoom, FALSE );
1408 // }
1410 if ( bSetRowHeights )
1411 UpdateAllRowHeights(); // with vdev or printer, depending on configuration
1413 FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
1415 // #73762# invalidate eventually temporary table areas
1416 if ( bRet )
1417 aDocument.InvalidateTableArea();
1419 bIsEmpty = FALSE;
1421 return bRet;
1425 ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell )
1426 : mrDocShell( rDocShell)
1428 // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1430 ScChartListenerCollection* pCharts = mrDocShell.aDocument.GetChartListenerCollection();
1431 if (pCharts)
1432 pCharts->UpdateDirtyCharts(); // Charts to be updated.
1433 mrDocShell.aDocument.StopTemporaryChartLock();
1434 if (mrDocShell.pAutoStyleList)
1435 mrDocShell.pAutoStyleList->ExecuteAllNow(); // Execute template timeouts now.
1436 if (mrDocShell.aDocument.HasExternalRefManager())
1438 ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
1439 if (pRefMgr && pRefMgr->hasExternalData())
1441 pRefMgr->setAllCacheTableReferencedStati( false);
1442 mrDocShell.aDocument.MarkUsedExternalReferences(); // Mark tables of external references to be written.
1445 if (mrDocShell.GetCreateMode()== SFX_CREATE_MODE_STANDARD)
1446 mrDocShell.SfxObjectShell::SetVisArea( Rectangle() ); // "Normally" worked on => no VisArea.
1449 ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
1451 if (mrDocShell.aDocument.HasExternalRefManager())
1453 ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
1454 if (pRefMgr && pRefMgr->hasExternalData())
1456 // Prevent accidental data loss due to lack of knowledge.
1457 pRefMgr->setAllCacheTableReferencedStati( true);
1463 BOOL __EXPORT ScDocShell::Save()
1465 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Save" );
1467 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
1469 PrepareSaveGuard aPrepareGuard( *this);
1471 // wait cursor is handled with progress bar
1472 BOOL bRet = SfxObjectShell::Save();
1473 if( bRet )
1474 bRet = SaveXML( GetMedium(), NULL );
1475 return bRet;
1479 BOOL __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium )
1481 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::SaveAs" );
1483 #if ENABLE_SHEET_PROTECTION
1484 ScTabViewShell* pViewShell = GetBestViewShell();
1485 bool bNeedsRehash = ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_SHA1);
1486 if (bNeedsRehash)
1487 // legacy xls hash double-hashed by SHA1 is also supported.
1488 bNeedsRehash = ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_XL, PASSHASH_SHA1);
1490 if (pViewShell && bNeedsRehash)
1492 if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_SHA1))
1493 // password re-type cancelled. Don't save the document.
1494 return false;
1496 #endif
1498 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
1500 PrepareSaveGuard aPrepareGuard( *this);
1502 // wait cursor is handled with progress bar
1503 BOOL bRet = SfxObjectShell::SaveAs( rMedium );
1504 if( bRet )
1505 bRet = SaveXML( &rMedium, NULL );
1507 return bRet;
1511 BOOL __EXPORT ScDocShell::IsInformationLost()
1514 const SfxFilter *pFilt = GetMedium()->GetFilter();
1515 BOOL bRet = pFilt && pFilt->IsAlienFormat() && bNoInformLost;
1516 if (bNoInformLost) // nur einmal!!
1517 bNoInformLost = FALSE;
1518 return bRet;
1520 //!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen
1522 return SfxObjectShell::IsInformationLost();
1526 // Xcl-like column width measured in characters of standard font.
1527 xub_StrLen lcl_ScDocShell_GetColWidthInChars( USHORT nWidth )
1529 // double fColScale = 1.0;
1530 double f = nWidth;
1531 f *= 1328.0 / 25.0;
1532 f += 90.0;
1533 f *= 1.0 / 23.0;
1534 // f /= fColScale * 256.0;
1535 f /= 256.0;
1537 return xub_StrLen( f );
1541 void lcl_ScDocShell_GetFixedWidthString( String& rStr, const ScDocument& rDoc,
1542 SCTAB nTab, SCCOL nCol, BOOL bValue, SvxCellHorJustify eHorJust )
1544 xub_StrLen nLen = lcl_ScDocShell_GetColWidthInChars(
1545 rDoc.GetColWidth( nCol, nTab ) );
1546 if ( nLen < rStr.Len() )
1548 if ( bValue )
1549 rStr.AssignAscii( "###" );
1550 rStr.Erase( nLen );
1552 if ( nLen > rStr.Len() )
1554 if ( bValue && eHorJust == SVX_HOR_JUSTIFY_STANDARD )
1555 eHorJust = SVX_HOR_JUSTIFY_RIGHT;
1556 switch ( eHorJust )
1558 case SVX_HOR_JUSTIFY_RIGHT:
1560 String aTmp;
1561 aTmp.Fill( nLen - rStr.Len() );
1562 rStr.Insert( aTmp, 0 );
1564 break;
1565 case SVX_HOR_JUSTIFY_CENTER:
1567 xub_StrLen nLen2 = (nLen - rStr.Len()) / 2;
1568 String aTmp;
1569 aTmp.Fill( nLen2 );
1570 rStr.Insert( aTmp, 0 );
1571 rStr.Expand( nLen );
1573 break;
1574 default:
1575 rStr.Expand( nLen );
1581 void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream,
1582 const ScDocument& rDoc, SCTAB nTab, SCCOL nCol )
1584 String aString;
1585 lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, FALSE,
1586 SVX_HOR_JUSTIFY_STANDARD );
1587 rStream.WriteUnicodeOrByteText( aString );
1591 void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt )
1593 sal_Unicode cDelim = rAsciiOpt.nFieldSepCode;
1594 sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
1595 CharSet eCharSet = rAsciiOpt.eCharSet;
1596 BOOL bFixedWidth = rAsciiOpt.bFixedWidth;
1597 BOOL bSaveAsShown = rAsciiOpt.bSaveAsShown;
1599 CharSet eOldCharSet = rStream.GetStreamCharSet();
1600 rStream.SetStreamCharSet( eCharSet );
1601 USHORT nOldNumberFormatInt = rStream.GetNumberFormatInt();
1602 ByteString aStrDelimEncoded; // only used if not Unicode
1603 UniString aStrDelimDecoded; // only used if context encoding
1604 BOOL bContextOrNotAsciiEncoding;
1605 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
1607 rStream.StartWritingUnicodeText();
1608 bContextOrNotAsciiEncoding = FALSE;
1610 else
1612 aStrDelimEncoded = ByteString( cStrDelim, eCharSet );
1613 rtl_TextEncodingInfo aInfo;
1614 aInfo.StructSize = sizeof(aInfo);
1615 if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
1617 bContextOrNotAsciiEncoding =
1618 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
1619 ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
1620 if ( bContextOrNotAsciiEncoding )
1621 aStrDelimDecoded = String( aStrDelimEncoded, eCharSet );
1623 else
1624 bContextOrNotAsciiEncoding = FALSE;
1627 SCCOL nStartCol = 0;
1628 SCROW nStartRow = 0;
1629 SCTAB nTab = GetSaveTab();
1630 SCCOL nEndCol;
1631 SCROW nEndRow;
1632 aDocument.GetCellArea( nTab, nEndCol, nEndRow );
1634 ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), nEndRow );
1636 String aString;
1638 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
1639 const ScViewOptions& rOpt = (pViewSh)
1640 ? pViewSh->GetViewData()->GetOptions()
1641 : aDocument.GetViewOptions();
1642 BOOL bShowFormulas = rOpt.GetOption( VOPT_FORMULAS );
1643 BOOL bTabProtect = aDocument.IsTabProtected( nTab );
1645 SCCOL nCol;
1646 SCROW nRow;
1647 SCCOL nNextCol = nStartCol;
1648 SCROW nNextRow = nStartRow;
1649 SCCOL nEmptyCol;
1650 SCROW nEmptyRow;
1651 SvNumberFormatter& rFormatter = *aDocument.GetFormatTable();
1653 ScHorizontalCellIterator aIter( &aDocument, nTab, nStartCol, nStartRow,
1654 nEndCol, nEndRow );
1655 ScBaseCell* pCell;
1656 while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != NULL )
1658 BOOL bProgress = FALSE; // only upon line change
1659 if ( nNextRow < nRow )
1660 { // empty rows or/and empty columns up to end of row
1661 bProgress = TRUE;
1662 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
1663 { // remaining columns of last row
1664 if ( bFixedWidth )
1665 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1666 aDocument, nTab, nEmptyCol );
1667 else if ( cDelim != 0 )
1668 rStream.WriteUniOrByteChar( cDelim );
1670 endlub( rStream );
1671 nNextRow++;
1672 for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ )
1673 { // completely empty rows
1674 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
1676 if ( bFixedWidth )
1677 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1678 aDocument, nTab, nEmptyCol );
1679 else if ( cDelim != 0 )
1680 rStream.WriteUniOrByteChar( cDelim );
1682 endlub( rStream );
1684 for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ )
1685 { // empty columns at beginning of row
1686 if ( bFixedWidth )
1687 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1688 aDocument, nTab, nEmptyCol );
1689 else if ( cDelim != 0 )
1690 rStream.WriteUniOrByteChar( cDelim );
1692 nNextRow = nRow;
1694 else if ( nNextCol < nCol )
1695 { // empty columns in same row
1696 for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ )
1697 { // columns in between
1698 if ( bFixedWidth )
1699 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1700 aDocument, nTab, nEmptyCol );
1701 else if ( cDelim != 0 )
1702 rStream.WriteUniOrByteChar( cDelim );
1705 if ( nCol == nEndCol )
1707 bProgress = TRUE;
1708 nNextCol = nStartCol;
1709 nNextRow = nRow + 1;
1711 else
1712 nNextCol = nCol + 1;
1714 CellType eType = pCell->GetCellType();
1715 if ( bTabProtect )
1717 const ScProtectionAttr* pProtAttr =
1718 (const ScProtectionAttr*) aDocument.GetAttr(
1719 nCol, nRow, nTab, ATTR_PROTECTION );
1720 if ( pProtAttr->GetHideCell() ||
1721 ( eType == CELLTYPE_FORMULA && bShowFormulas &&
1722 pProtAttr->GetHideFormula() ) )
1723 eType = CELLTYPE_NONE; // hide
1725 BOOL bString;
1726 switch ( eType )
1728 case CELLTYPE_NOTE:
1729 case CELLTYPE_NONE:
1730 aString.Erase();
1731 bString = FALSE;
1732 break;
1733 case CELLTYPE_FORMULA :
1735 USHORT nErrCode;
1736 if ( bShowFormulas )
1738 ((ScFormulaCell*)pCell)->GetFormula( aString );
1739 bString = TRUE;
1741 else if ( ( nErrCode = ((ScFormulaCell*)pCell)->GetErrCode() ) != 0 )
1743 aString = ScGlobal::GetErrorString( nErrCode );
1744 bString = TRUE;
1746 else if ( ((ScFormulaCell*)pCell)->IsValue() )
1748 sal_uInt32 nFormat;
1749 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1750 if ( bFixedWidth || bSaveAsShown )
1752 Color* pDummy;
1753 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1754 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
1756 else
1758 ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
1759 bString = FALSE;
1762 else
1764 if ( bSaveAsShown )
1766 sal_uInt32 nFormat;
1767 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1768 Color* pDummy;
1769 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1771 else
1772 ((ScFormulaCell*)pCell)->GetString( aString );
1773 bString = TRUE;
1776 break;
1777 case CELLTYPE_STRING :
1778 if ( bSaveAsShown )
1780 sal_uInt32 nFormat;
1781 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1782 Color* pDummy;
1783 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1785 else
1786 ((ScStringCell*)pCell)->GetString( aString );
1787 bString = TRUE;
1788 break;
1789 case CELLTYPE_EDIT :
1791 const EditTextObject* pObj;
1792 static_cast<const ScEditCell*>(pCell)->GetData( pObj);
1793 EditEngine& rEngine = aDocument.GetEditEngine();
1794 rEngine.SetText( *pObj);
1795 aString = rEngine.GetText(); // including LF
1796 bString = TRUE;
1798 break;
1799 case CELLTYPE_VALUE :
1801 sal_uInt32 nFormat;
1802 aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1803 if ( bFixedWidth || bSaveAsShown )
1805 Color* pDummy;
1806 ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1807 bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
1809 else
1811 ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
1812 bString = FALSE;
1815 break;
1816 default:
1817 DBG_ERROR( "ScDocShell::AsciiSave: unknown CellType" );
1818 aString.Erase();
1819 bString = FALSE;
1822 if ( bFixedWidth )
1824 SvxCellHorJustify eHorJust = (SvxCellHorJustify)
1825 ((const SvxHorJustifyItem*) aDocument.GetAttr( nCol, nRow,
1826 nTab, ATTR_HOR_JUSTIFY ))->GetValue();
1827 lcl_ScDocShell_GetFixedWidthString( aString, aDocument, nTab, nCol,
1828 !bString, eHorJust );
1829 rStream.WriteUnicodeOrByteText( aString );
1831 else
1833 if (!bString && cStrDelim != 0 && aString.Len() > 0)
1835 sal_Unicode c = aString.GetChar(0);
1836 bString = (c == cStrDelim || c == ' ' ||
1837 aString.GetChar( aString.Len()-1) == ' ' ||
1838 aString.Search( cStrDelim) != STRING_NOTFOUND);
1839 if (!bString && cDelim != 0)
1840 bString = (aString.Search( cDelim) != STRING_NOTFOUND);
1842 if ( bString )
1844 if ( cStrDelim != 0 ) //@ BugId 55355
1846 if ( eCharSet == RTL_TEXTENCODING_UNICODE )
1848 xub_StrLen nPos = aString.Search( cStrDelim );
1849 while ( nPos != STRING_NOTFOUND )
1851 aString.Insert( cStrDelim, nPos );
1852 nPos = aString.Search( cStrDelim, nPos+2 );
1854 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1855 rStream.WriteUnicodeText( aString );
1856 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1858 else
1860 // #105549# This is nasty. The Unicode to byte encoding
1861 // may convert typographical quotation marks to ASCII
1862 // quotation marks, which may interfer with the delimiter,
1863 // so we have to escape delimiters after the string has
1864 // been encoded. Since this may happen also with UTF-8
1865 // encoded typographical quotation marks if such was
1866 // specified as a delimiter we have to check for the full
1867 // encoded delimiter string, not just one character.
1868 // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
1869 // dead encodings where one code point (and especially a
1870 // low ASCII value) may represent different characters, we
1871 // have to convert forth and back and forth again. Same for
1872 // UTF-7 since it is a context sensitive encoding too.
1874 if ( bContextOrNotAsciiEncoding )
1876 // to byte encoding
1877 ByteString aStrEnc( aString, eCharSet );
1878 // back to Unicode
1879 UniString aStrDec( aStrEnc, eCharSet );
1880 // search on re-decoded string
1881 xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded );
1882 while ( nPos != STRING_NOTFOUND )
1884 aStrDec.Insert( aStrDelimDecoded, nPos );
1885 nPos = aStrDec.Search( aStrDelimDecoded,
1886 nPos+1+aStrDelimDecoded.Len() );
1888 // write byte re-encoded
1889 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1890 rStream.WriteUnicodeOrByteText( aStrDec, eCharSet );
1891 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1893 else
1895 ByteString aStrEnc( aString, eCharSet );
1896 // search on encoded string
1897 xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded );
1898 while ( nPos != STRING_NOTFOUND )
1900 aStrEnc.Insert( aStrDelimEncoded, nPos );
1901 nPos = aStrEnc.Search( aStrDelimEncoded,
1902 nPos+1+aStrDelimEncoded.Len() );
1904 // write byte encoded
1905 rStream.Write( aStrDelimEncoded.GetBuffer(),
1906 aStrDelimEncoded.Len() );
1907 rStream.Write( aStrEnc.GetBuffer(), aStrEnc.Len() );
1908 rStream.Write( aStrDelimEncoded.GetBuffer(),
1909 aStrDelimEncoded.Len() );
1913 else
1914 rStream.WriteUnicodeOrByteText( aString );
1916 else
1917 rStream.WriteUnicodeOrByteText( aString );
1920 if( nCol < nEndCol )
1922 if(cDelim!=0) //@ BugId 55355
1923 rStream.WriteUniOrByteChar( cDelim );
1925 else
1926 endlub( rStream );
1928 if ( bProgress )
1929 aProgress.SetStateOnPercent( nRow );
1932 // write out empty if requested
1933 if ( nNextRow <= nEndRow )
1935 for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
1936 { // remaining empty columns of last row
1937 if ( bFixedWidth )
1938 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1939 aDocument, nTab, nEmptyCol );
1940 else if ( cDelim != 0 )
1941 rStream.WriteUniOrByteChar( cDelim );
1943 endlub( rStream );
1944 nNextRow++;
1946 for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ )
1947 { // entire empty rows
1948 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
1950 if ( bFixedWidth )
1951 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1952 aDocument, nTab, nEmptyCol );
1953 else if ( cDelim != 0 )
1954 rStream.WriteUniOrByteChar( cDelim );
1956 endlub( rStream );
1959 rStream.SetStreamCharSet( eOldCharSet );
1960 rStream.SetNumberFormatInt( nOldNumberFormatInt );
1963 BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
1965 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );
1967 ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
1969 // #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
1970 // it's already in ExecuteSave (as for Save and SaveAs)
1972 if (pAutoStyleList)
1973 pAutoStyleList->ExecuteAllNow(); // Vorlagen-Timeouts jetzt ausfuehren
1974 if (GetCreateMode()== SFX_CREATE_MODE_STANDARD)
1975 SfxObjectShell::SetVisArea( Rectangle() ); // normal bearbeitet -> keine VisArea
1977 DBG_ASSERT( rMed.GetFilter(), "Filter == 0" );
1979 BOOL bRet = FALSE;
1980 String aFltName = rMed.GetFilter()->GetFilterName();
1983 if (aFltName.EqualsAscii(pFilterLotus))
1985 SvStream* pStream = rMed.GetOutStream();
1986 if (pStream)
1988 FltError eError = ScFormatFilter::Get().ScExportLotus123( *pStream, &aDocument, ExpWK1,
1989 CHARSET_IBMPC_437 );
1990 bRet = eError == eERR_OK;
1993 else
1995 if (aFltName.EqualsAscii(pFilterXML))
1997 //TODO/LATER: this shouldn't happen!
1998 DBG_ERROR("XML filter in ConvertFrom?!");
1999 bRet = SaveXML( &rMed, NULL );
2001 else if (aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
2002 aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx5Temp) ||
2003 aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) ||
2004 aFltName.EqualsAscii(pFilterEx07Xml))
2006 WaitObject aWait( GetActiveDialogParent() );
2008 bool bDoSave = true;
2009 if( ScTabViewShell* pViewShell = GetBestViewShell() )
2011 ScExtDocOptions* pExtDocOpt = aDocument.GetExtDocOptions();
2012 if( !pExtDocOpt )
2013 aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
2014 pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );
2016 /* #115980# #i104990# If the imported document contains a medium
2017 password, determine if we can save it, otherwise ask the users
2018 whether they want to save without it. */
2019 if( !::sfx2::CheckMSPasswordCapabilityForExport( aFltName ) )
2021 SfxItemSet* pItemSet = rMed.GetItemSet();
2022 const SfxPoolItem* pItem = 0;
2023 if( pItemSet && pItemSet->GetItemState( SID_PASSWORD, sal_True, &pItem ) == SFX_ITEM_SET )
2025 bDoSave = ScWarnPassword::WarningOnPassword( rMed );
2026 // #i42858# remove password from medium (warn only one time)
2027 if( bDoSave )
2028 pItemSet->ClearItem( SID_PASSWORD );
2032 #if ENABLE_SHEET_PROTECTION
2033 if( bDoSave )
2035 bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen( aDocument, PASSHASH_XL );
2036 bDoSave = !bNeedRetypePassDlg || pViewShell->ExecuteRetypePassDlg( PASSHASH_XL );
2038 #endif
2041 if( bDoSave )
2043 ExportFormatExcel eFormat = ExpBiff5;
2044 if( aFltName.EqualsAscii( pFilterExcel97 ) || aFltName.EqualsAscii( pFilterEx97Temp ) )
2045 eFormat = ExpBiff8;
2046 if( aFltName.EqualsAscii( pFilterEx07Xml ) )
2047 eFormat = Exp2007Xml;
2048 FltError eError = ScFormatFilter::Get().ScExportExcel5( rMed, &aDocument, eFormat, RTL_TEXTENCODING_MS_1252 );
2050 if( eError && !GetError() )
2051 SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2053 // don't return false for warnings
2054 bRet = ((eError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK) || (eError == eERR_OK);
2056 else
2058 // export aborted, i.e. "Save without password" warning
2059 SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2062 else if (aFltName.EqualsAscii(pFilterAscii))
2064 SvStream* pStream = rMed.GetOutStream();
2065 if (pStream)
2067 String sItStr;
2068 SfxItemSet* pSet = rMed.GetItemSet();
2069 const SfxPoolItem* pItem;
2070 if ( pSet && SFX_ITEM_SET ==
2071 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
2073 sItStr = ((const SfxStringItem*)pItem)->GetValue();
2076 if ( sItStr.Len() == 0 )
2078 // default for ascii export (from API without options):
2079 // ISO8859-1/MS_1252 encoding, comma, double quotes
2081 ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
2082 sItStr = aDefOptions.BuildString();
2085 WaitObject aWait( GetActiveDialogParent() );
2086 ScImportOptions aOptions( sItStr );
2087 AsciiSave( *pStream, aOptions );
2088 bRet = TRUE;
2090 if (aDocument.GetTableCount() > 1)
2091 if (!rMed.GetError())
2092 rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
2095 else if (aFltName.EqualsAscii(pFilterDBase))
2097 String sCharSet;
2098 SfxItemSet* pSet = rMed.GetItemSet();
2099 const SfxPoolItem* pItem;
2100 if ( pSet && SFX_ITEM_SET ==
2101 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
2103 sCharSet = ((const SfxStringItem*)pItem)->GetValue();
2106 if (sCharSet.Len() == 0)
2108 // default for dBase export (from API without options):
2109 // IBM_850 encoding
2111 sCharSet = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
2114 WaitObject aWait( GetActiveDialogParent() );
2115 // HACK damit Sba geoffnetes TempFile ueberschreiben kann
2116 rMed.CloseOutStream();
2117 BOOL bHasMemo = FALSE;
2119 ULONG eError = DBaseExport( rMed.GetPhysicalName(),
2120 ScGlobal::GetCharsetValue(sCharSet), bHasMemo );
2122 if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) )
2124 //! if ( !rMed.GetError() )
2125 //! rMed.SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2126 eError = eERR_OK;
2128 //! else if ( aDocument.GetTableCount() > 1 && !rMed.GetError() )
2129 //! rMed.SetError( SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2131 INetURLObject aTmpFile( rMed.GetPhysicalName(), INET_PROT_FILE );
2132 if ( bHasMemo )
2133 aTmpFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
2134 if ( eError != eERR_OK )
2136 if (!GetError())
2137 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
2138 if ( bHasMemo && IsDocument( aTmpFile ) )
2139 KillFile( aTmpFile );
2141 else
2143 bRet = TRUE;
2144 if ( bHasMemo )
2146 SfxStringItem* pNameItem =
2147 (SfxStringItem*) rMed.GetItemSet()->GetItem( SID_FILE_NAME );
2148 INetURLObject aDbtFile( pNameItem->GetValue(), INET_PROT_FILE );
2149 aDbtFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
2150 if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) )
2151 bRet = FALSE;
2152 if ( bRet && !MoveFile( aTmpFile, aDbtFile ) )
2153 bRet = FALSE;
2154 if ( !bRet )
2156 KillFile( aTmpFile );
2157 if ( !GetError() )
2158 SetError( SCERR_EXPORT_DATA, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2163 else if (aFltName.EqualsAscii(pFilterDif))
2165 SvStream* pStream = rMed.GetOutStream();
2166 if (pStream)
2168 String sItStr;
2169 SfxItemSet* pSet = rMed.GetItemSet();
2170 const SfxPoolItem* pItem;
2171 if ( pSet && SFX_ITEM_SET ==
2172 pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) )
2174 sItStr = ((const SfxStringItem*)pItem)->GetValue();
2177 if (sItStr.Len() == 0)
2179 // default for DIF export (from API without options):
2180 // ISO8859-1/MS_1252 encoding
2182 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
2185 WaitObject aWait( GetActiveDialogParent() );
2186 ScFormatFilter::Get().ScExportDif( *pStream, &aDocument, ScAddress(0,0,0),
2187 ScGlobal::GetCharsetValue(sItStr) );
2188 bRet = TRUE;
2190 if (aDocument.GetTableCount() > 1)
2191 if (!rMed.GetError())
2192 rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
2195 else if (aFltName.EqualsAscii(pFilterSylk))
2197 SvStream* pStream = rMed.GetOutStream();
2198 if ( pStream )
2200 WaitObject aWait( GetActiveDialogParent() );
2202 SCCOL nEndCol;
2203 SCROW nEndRow;
2204 aDocument.GetCellArea( 0, nEndCol, nEndRow );
2205 ScRange aRange( 0,0,0, nEndCol,nEndRow,0 );
2207 ScImportExport aImExport( &aDocument, aRange );
2208 aImExport.SetFormulas( TRUE );
2209 bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK );
2212 else if (aFltName.EqualsAscii(pFilterHtml))
2214 SvStream* pStream = rMed.GetOutStream();
2215 if ( pStream )
2217 WaitObject aWait( GetActiveDialogParent() );
2218 ScImportExport aImExport( &aDocument );
2219 aImExport.SetStreamPath( rMed.GetName() );
2220 bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_HTML );
2221 if ( bRet && aImExport.GetNonConvertibleChars().Len() )
2222 SetError( *new StringErrorInfo(
2223 SCWARN_EXPORT_NONCONVERTIBLE_CHARS,
2224 aImExport.GetNonConvertibleChars(),
2225 ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2228 else
2230 if (GetError())
2231 SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2233 return bRet;
2237 BOOL __EXPORT ScDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor )
2239 return SfxObjectShell::SaveCompleted( xStor );
2243 BOOL __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor )
2245 BOOL bRet = SfxObjectShell::DoSaveCompleted( pNewStor );
2247 // SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write
2248 Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) );
2249 return bRet;
2253 USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing )
2255 if(SC_MOD()->GetCurRefDlgId()>0)
2257 SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame) );
2258 if( pFrame )
2260 SfxViewShell* p = pFrame->GetViewShell();
2261 ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
2262 if(pViewSh!=NULL)
2264 Window *pWin=pViewSh->GetWindow();
2265 if(pWin!=NULL) pWin->GrabFocus();
2269 return FALSE;
2271 if ( aDocument.IsInLinkUpdate() || aDocument.IsInInterpreter() )
2273 ErrorMessage(STR_CLOSE_ERROR_LINK);
2274 return FALSE;
2277 DoEnterHandler();
2279 // start handler for possible veto from DocBefore_Close
2280 uno::Sequence< uno::Any > aArgs;
2281 uno::Reference< document::XVbaEventsHelper > xVbaEventsHelper ( aDocument.GetVbaEventsHelper(), uno::UNO_QUERY );
2282 if ( !IsInPrepareClose() && xVbaEventsHelper.is() )
2284 if ( xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKBOOK_BEFORECLOSE, aArgs ) )
2285 return sal_False;
2287 // end handler code
2289 USHORT nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing );
2290 if (nRet == TRUE) // TRUE = schliessen
2291 aDocument.DisableIdle(TRUE); // nicht mehr drin rumpfuschen !!!
2293 return nRet;
2296 void ScDocShell::PrepareReload()
2298 SfxObjectShell::PrepareReload(); // tut nichts?
2300 // Das Disconnect von DDE-Links kann Reschedule ausloesen.
2301 // Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload
2302 // aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest
2303 // werden. Dabei verklemmt sicht dann irgendwas.
2304 // -> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten
2306 aDocument.DisconnectDdeLinks();
2310 String ScDocShell::GetOwnFilterName() // static
2312 return String::CreateFromAscii(pFilterSc50);
2315 String ScDocShell::GetHtmlFilterName()
2317 return String::CreateFromAscii(pFilterHtml);
2320 String ScDocShell::GetWebQueryFilterName() // static
2322 return String::CreateFromAscii(pFilterHtmlWebQ);
2325 String ScDocShell::GetAsciiFilterName() // static
2327 return String::CreateFromAscii(pFilterAscii);
2330 String ScDocShell::GetLotusFilterName() // static
2332 return String::CreateFromAscii(pFilterLotus);
2335 String ScDocShell::GetDBaseFilterName() // static
2337 return String::CreateFromAscii(pFilterDBase);
2340 String ScDocShell::GetDifFilterName() // static
2342 return String::CreateFromAscii(pFilterDif);
2345 BOOL ScDocShell::HasAutomaticTableName( const String& rFilter ) // static
2347 // TRUE for those filters that keep the default table name
2348 // (which is language specific)
2350 return rFilter.EqualsAscii( pFilterAscii )
2351 || rFilter.EqualsAscii( pFilterLotus )
2352 || rFilter.EqualsAscii( pFilterExcel4 )
2353 || rFilter.EqualsAscii( pFilterEx4Temp )
2354 || rFilter.EqualsAscii( pFilterDBase )
2355 || rFilter.EqualsAscii( pFilterDif )
2356 || rFilter.EqualsAscii( pFilterSylk )
2357 || rFilter.EqualsAscii( pFilterHtml )
2358 || rFilter.EqualsAscii( pFilterRtf );
2361 //==================================================================
2363 #define __SCDOCSHELL_INIT \
2364 aDocument ( SCDOCMODE_DOCUMENT, this ), \
2365 aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), \
2366 nPrtToScreenFactor( 1.0 ), \
2367 pImpl ( new DocShell_Impl ), \
2368 bHeaderOn ( TRUE ), \
2369 bFooterOn ( TRUE ), \
2370 bNoInformLost ( TRUE ), \
2371 bIsEmpty ( TRUE ), \
2372 bIsInUndo ( FALSE ), \
2373 bDocumentModifiedPending( FALSE ), \
2374 nDocumentLock ( 0 ), \
2375 nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG), \
2376 bUpdateEnabled ( TRUE ), \
2377 pOldAutoDBRange ( NULL ), \
2378 pDocHelper ( NULL ), \
2379 pAutoStyleList ( NULL ), \
2380 pPaintLockData ( NULL ), \
2381 pOldJobSetup ( NULL ), \
2382 pSolverSaveData ( NULL ), \
2383 pSheetSaveData ( NULL ), \
2384 pModificator ( NULL )
2386 //------------------------------------------------------------------
2388 ScDocShell::ScDocShell( const ScDocShell& rShell )
2389 : SvRefBase(),
2390 SotObject(),
2391 SfxObjectShell( rShell.GetCreateMode() ),
2392 SfxListener(),
2393 __SCDOCSHELL_INIT
2395 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );
2397 SetPool( &SC_MOD()->GetPool() );
2399 bIsInplace = rShell.bIsInplace;
2401 pDocFunc = new ScDocFunc(*this);
2403 // SetBaseModel needs exception handling
2404 ScModelObj::CreateAndSet( this );
2406 StartListening(*this);
2407 SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
2408 if (pStlPool)
2409 StartListening(*pStlPool);
2411 GetPageOnFromPageStyleSet( NULL, 0, bHeaderOn, bFooterOn );
2412 SetHelpId( HID_SCSHELL_DOCSH );
2414 // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
2417 //------------------------------------------------------------------
2419 ScDocShell::ScDocShell( SfxObjectCreateMode eMode, const bool _bScriptSupport )
2420 : SfxObjectShell( eMode ),
2421 __SCDOCSHELL_INIT
2423 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );
2425 SetPool( &SC_MOD()->GetPool() );
2427 bIsInplace = (eMode == SFX_CREATE_MODE_EMBEDDED);
2428 // wird zurueckgesetzt, wenn nicht inplace
2430 pDocFunc = new ScDocFunc(*this);
2432 if ( !_bScriptSupport )
2433 SetHasNoBasic();
2435 // SetBaseModel needs exception handling
2436 ScModelObj::CreateAndSet( this );
2438 StartListening(*this);
2439 SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
2440 if (pStlPool)
2441 StartListening(*pStlPool);
2442 SetHelpId( HID_SCSHELL_DOCSH );
2444 aDocument.GetDBCollection()->SetRefreshHandler(
2445 LINK( this, ScDocShell, RefreshDBDataHdl ) );
2447 // InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
2450 //------------------------------------------------------------------
2452 __EXPORT ScDocShell::~ScDocShell()
2454 ResetDrawObjectShell(); // #55570# falls der Drawing-Layer noch versucht, darauf zuzugreifen
2456 SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
2457 if (pStlPool)
2458 EndListening(*pStlPool);
2459 EndListening(*this);
2461 delete pAutoStyleList;
2463 SfxApplication *pSfxApp = SFX_APP();
2464 if ( pSfxApp->GetDdeService() ) // DDE vor Dokument loeschen
2465 pSfxApp->RemoveDdeTopic( this );
2467 delete pDocFunc;
2468 delete aDocument.mpUndoManager;
2469 aDocument.mpUndoManager = 0;
2470 delete pImpl;
2472 delete pPaintLockData;
2474 delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob()
2476 delete pSolverSaveData;
2477 delete pSheetSaveData;
2478 delete pOldAutoDBRange;
2480 if (pModificator)
2482 DBG_ERROR("The Modificator should not exist");
2483 delete pModificator;
2487 //------------------------------------------------------------------
2489 SfxUndoManager* __EXPORT ScDocShell::GetUndoManager()
2491 return aDocument.GetUndoManager();
2494 void ScDocShell::SetModified( BOOL bModified )
2496 if ( SfxObjectShell::IsEnableSetModified() )
2498 SfxObjectShell::SetModified( bModified );
2499 Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) );
2504 void ScDocShell::SetDocumentModified( BOOL bIsModified /* = TRUE */ )
2506 // BroadcastUno muss auch mit pPaintLockData sofort passieren
2507 //! auch bei SetDrawModified, wenn Drawing angebunden ist
2508 //! dann eigener Hint???
2510 if ( pPaintLockData && bIsModified )
2512 //! BCA_BRDCST_ALWAYS etc. also needed here?
2513 aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
2515 pPaintLockData->SetModified(); // spaeter...
2516 return;
2519 SetDrawModified( bIsModified );
2521 if ( bIsModified )
2523 if ( aDocument.IsAutoCalcShellDisabled() )
2524 SetDocumentModifiedPending( TRUE );
2525 else
2527 SetDocumentModifiedPending( FALSE );
2528 aDocument.InvalidateStyleSheetUsage();
2529 aDocument.InvalidateTableArea();
2530 aDocument.InvalidateLastTableOpParams();
2531 aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
2532 if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() )
2533 aDocument.CalcFormulaTree( TRUE );
2534 PostDataChanged();
2536 // Detective AutoUpdate:
2537 // Update if formulas were modified (DetectiveDirty) or the list contains
2538 // "Trace Error" entries (#75362# - Trace Error can look completely different
2539 // after changes to non-formula cells).
2541 ScDetOpList* pList = aDocument.GetDetOpList();
2542 if ( pList && ( aDocument.IsDetectiveDirty() || pList->HasAddError() ) &&
2543 pList->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
2545 GetDocFunc().DetectiveRefresh(TRUE); // TRUE = caused by automatic update
2547 aDocument.SetDetectiveDirty(FALSE); // always reset, also if not refreshed
2550 // #b6697848# notify UNO objects after BCA_BRDCST_ALWAYS etc.
2551 aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
2555 // SetDrawModified - ohne Formel-Update
2556 // (Drawing muss auch beim normalen SetDocumentModified upgedated werden,
2557 // z.B. bei Tabelle loeschen etc.)
2559 void ScDocShell::SetDrawModified( BOOL bIsModified /* = TRUE */ )
2561 BOOL bUpdate = ( bIsModified != IsModified() );
2563 SetModified( bIsModified );
2565 if (bUpdate)
2567 SfxBindings* pBindings = GetViewBindings();
2568 if (pBindings)
2570 pBindings->Invalidate( SID_SAVEDOC );
2571 pBindings->Invalidate( SID_DOC_MODIFIED );
2575 if (bIsModified)
2577 if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
2579 aDocument.UpdateChartListenerCollection();
2580 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED )); // Navigator
2582 SC_MOD()->AnythingChanged();
2586 void ScDocShell::SetInUndo(BOOL bSet)
2588 bIsInUndo = bSet;
2592 void ScDocShell::GetDocStat( ScDocStat& rDocStat )
2594 SfxPrinter* pPrinter = GetPrinter();
2596 aDocument.GetDocStat( rDocStat );
2597 rDocStat.nPageCount = 0;
2599 if ( pPrinter )
2600 for ( SCTAB i=0; i<rDocStat.nTableCount; i++ )
2601 rDocStat.nPageCount = sal::static_int_cast<USHORT>( rDocStat.nPageCount +
2602 (USHORT) ScPrintFunc( this, pPrinter, i ).GetTotalPages() );
2606 SfxDocumentInfoDialog* __EXPORT ScDocShell::CreateDocumentInfoDialog(
2607 Window *pParent, const SfxItemSet &rSet )
2609 SfxDocumentInfoDialog* pDlg = new SfxDocumentInfoDialog( pParent, rSet );
2610 ScDocShell* pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current());
2612 //nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht
2613 //aus dem Doc-Manager
2615 if( pDocSh == this )
2617 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
2618 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
2619 ::CreateTabPage ScDocStatPageCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_STAT );
2620 DBG_ASSERT(ScDocStatPageCreate, "Tabpage create fail!");//CHINA001
2621 pDlg->AddTabPage( 42,
2622 ScGlobal::GetRscString( STR_DOC_STAT ),
2623 ScDocStatPageCreate,
2624 NULL);
2625 //CHINA001 pDlg->AddTabPage( 42,
2626 //CHINA001 ScGlobal::GetRscString( STR_DOC_STAT ),
2627 //CHINA001 ScDocStatPage::Create,
2628 //CHINA001 NULL );
2630 return pDlg;
2633 Window* ScDocShell::GetActiveDialogParent()
2635 ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2636 if ( pViewSh )
2637 return pViewSh->GetDialogParent();
2638 else
2639 return Application::GetDefDialogParent();
2642 void ScDocShell::SetSolverSaveData( const ScOptSolverSave& rData )
2644 delete pSolverSaveData;
2645 pSolverSaveData = new ScOptSolverSave( rData );
2648 ScSheetSaveData* ScDocShell::GetSheetSaveData()
2650 if (!pSheetSaveData)
2651 pSheetSaveData = new ScSheetSaveData;
2653 return pSheetSaveData;
2656 void ScDocShell::UseSheetSaveEntries()
2658 if (pSheetSaveData)
2660 pSheetSaveData->UseSaveEntries(); // use positions from saved file for next saving
2662 bool bHasEntries = false;
2663 SCTAB nTabCount = aDocument.GetTableCount();
2664 SCTAB nTab;
2665 for (nTab = 0; nTab < nTabCount; ++nTab)
2666 if (pSheetSaveData->HasStreamPos(nTab))
2667 bHasEntries = true;
2669 if (!bHasEntries)
2671 // if no positions were set (for example, export to other format),
2672 // reset all "valid" flags
2674 for (nTab = 0; nTab < nTabCount; ++nTab)
2675 if (aDocument.IsStreamValid(nTab))
2676 aDocument.SetStreamValid(nTab, FALSE);
2681 // --- ScDocShellModificator ------------------------------------------
2683 ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS )
2685 rDocShell( rDS ),
2686 aProtector( rDS.GetDocument()->GetRefreshTimerControlAddress() )
2688 ScDocument* pDoc = rDocShell.GetDocument();
2689 bAutoCalcShellDisabled = pDoc->IsAutoCalcShellDisabled();
2690 bIdleDisabled = pDoc->IsIdleDisabled();
2691 pDoc->SetAutoCalcShellDisabled( TRUE );
2692 pDoc->DisableIdle( TRUE );
2696 ScDocShellModificator::~ScDocShellModificator()
2698 ScDocument* pDoc = rDocShell.GetDocument();
2699 pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
2700 if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() )
2701 rDocShell.SetDocumentModified(); // last one shuts off the lights
2702 pDoc->DisableIdle( bIdleDisabled );
2706 void ScDocShellModificator::SetDocumentModified()
2708 ScDocument* pDoc = rDocShell.GetDocument();
2709 if ( !pDoc->IsImportingXML() )
2711 // AutoCalcShellDisabled temporaer restaurieren
2712 BOOL bDisabled = pDoc->IsAutoCalcShellDisabled();
2713 pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
2714 rDocShell.SetDocumentModified();
2715 pDoc->SetAutoCalcShellDisabled( bDisabled );
2717 else
2719 // uno broadcast is necessary for api to work
2720 // -> must also be done during xml import
2721 pDoc->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );