xref: /AOO41X/main/sc/source/ui/docshell/docsh.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 // System - Includes -----------------------------------------------------
27 
28 #include "scitems.hxx"
29 #include <editeng/eeitem.hxx>
30 #include <editeng/svxenum.hxx>
31 #include <svx/algitem.hxx>
32 
33 #include <sot/clsids.hxx>
34 #include <unotools/securityoptions.hxx>
35 #include <tools/stream.hxx>
36 #include <tools/string.hxx>
37 #include <tools/urlobj.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <vcl/virdev.hxx>
40 #include <vcl/waitobj.hxx>
41 #include <svtools/ctrltool.hxx>
42 #include <svtools/sfxecode.hxx>
43 #include <svl/zforlist.hxx>
44 #include <svl/PasswordHelper.hxx>
45 #include <sfx2/app.hxx>
46 #include <sfx2/bindings.hxx>
47 #include <sfx2/dinfdlg.hxx>
48 #include <sfx2/docfile.hxx>
49 #include <sfx2/docfilt.hxx>
50 #include <sfx2/fcontnr.hxx>
51 #include <sfx2/evntconf.hxx>
52 #include <sfx2/sfx.hrc>
53 #include <sfx2/objface.hxx>
54 #include <svl/srchitem.hxx>
55 #include <unotools/fltrcfg.hxx>
56 #include <svl/documentlockfile.hxx>
57 #include <svl/sharecontrolfile.hxx>
58 #include <unotools/charclass.hxx>
59 #include <vcl/virdev.hxx>
60 #include "chgtrack.hxx"
61 #include "chgviset.hxx"
62 #include <sfx2/request.hxx>
63 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
64 #include <com/sun/star/document/UpdateDocMode.hpp>
65 #include <com/sun/star/script/vba/VBAEventId.hpp>
66 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
67 #include <com/sun/star/sheet/XSpreadsheetView.hpp>
68 #include <com/sun/star/task/XJob.hpp>
69 #include <basic/sbstar.hxx>
70 #include <basic/basmgr.hxx>
71 
72 #include "scabstdlg.hxx" //CHINA001
73 #include <sot/formats.hxx>
74 #define SOT_FORMATSTR_ID_STARCALC_30 SOT_FORMATSTR_ID_STARCALC
75 
76 // INCLUDE ---------------------------------------------------------------
77 
78 #include "cell.hxx"
79 #include "global.hxx"
80 #include "filter.hxx"
81 #include "scmod.hxx"
82 #include "tabvwsh.hxx"
83 #include "docfunc.hxx"
84 #include "imoptdlg.hxx"
85 #include "impex.hxx"
86 #include "scresid.hxx"
87 #include "sc.hrc"
88 #include "globstr.hrc"
89 #include "scerrors.hxx"
90 #include "brdcst.hxx"
91 #include "stlpool.hxx"
92 #include "autostyl.hxx"
93 #include "attrib.hxx"
94 #include "asciiopt.hxx"
95 #include "waitoff.hxx"
96 #include "docpool.hxx"      // LoadCompleted
97 #include "progress.hxx"
98 #include "pntlock.hxx"
99 #include "collect.hxx"
100 #include "docuno.hxx"
101 #include "appoptio.hxx"
102 #include "detdata.hxx"
103 #include "printfun.hxx"
104 #include "dociter.hxx"
105 #include "cellform.hxx"
106 #include "chartlis.hxx"
107 #include "hints.hxx"
108 #include "xmlwrap.hxx"
109 #include "drwlayer.hxx"
110 #include "refreshtimer.hxx"
111 #include "dbcolect.hxx"
112 #include "scextopt.hxx"
113 #include "compiler.hxx"
114 #include "cfgids.hxx"
115 #include "warnpassword.hxx"
116 #include "optsolver.hxx"
117 #include "sheetdata.hxx"
118 #include "tabprotection.hxx"
119 #include "dpobject.hxx"
120 
121 #include "docsh.hxx"
122 #include "docshimp.hxx"
123 #include <rtl/logfile.hxx>
124 
125 #include <comphelper/processfactory.hxx>
126 #include "uiitems.hxx"
127 #include "cellsuno.hxx"
128 
129 using namespace com::sun::star;
130 using ::rtl::OUString;
131 using ::rtl::OUStringBuffer;
132 
133 // STATIC DATA -----------------------------------------------------------
134 
135 //  Stream-Namen im Storage
136 
137 const sal_Char __FAR_DATA ScDocShell::pStarCalcDoc[] = STRING_SCSTREAM;     // "StarCalcDocument"
138 const sal_Char __FAR_DATA ScDocShell::pStyleName[] = "SfxStyleSheets";
139 
140 //  Filter-Namen (wie in sclib.cxx)
141 
142 static const sal_Char __FAR_DATA pFilterSc50[]      = "StarCalc 5.0";
143 //static const sal_Char __FAR_DATA pFilterSc50Temp[]    = "StarCalc 5.0 Vorlage/Template";
144 static const sal_Char __FAR_DATA pFilterSc40[]      = "StarCalc 4.0";
145 //static const sal_Char __FAR_DATA pFilterSc40Temp[]    = "StarCalc 4.0 Vorlage/Template";
146 static const sal_Char __FAR_DATA pFilterSc30[]      = "StarCalc 3.0";
147 //static const sal_Char __FAR_DATA pFilterSc30Temp[]    = "StarCalc 3.0 Vorlage/Template";
148 static const sal_Char __FAR_DATA pFilterSc10[]      = "StarCalc 1.0";
149 static const sal_Char __FAR_DATA pFilterXML[]       = "StarOffice XML (Calc)";
150 static const sal_Char __FAR_DATA pFilterAscii[]     = "Text - txt - csv (StarCalc)";
151 static const sal_Char __FAR_DATA pFilterLotus[]     = "Lotus";
152 static const sal_Char __FAR_DATA pFilterQPro6[]     = "Quattro Pro 6.0";
153 static const sal_Char __FAR_DATA pFilterExcel4[]    = "MS Excel 4.0";
154 static const sal_Char __FAR_DATA pFilterEx4Temp[]   = "MS Excel 4.0 Vorlage/Template";
155 static const sal_Char __FAR_DATA pFilterExcel5[]    = "MS Excel 5.0/95";
156 static const sal_Char __FAR_DATA pFilterEx5Temp[]   = "MS Excel 5.0/95 Vorlage/Template";
157 static const sal_Char __FAR_DATA pFilterExcel95[]   = "MS Excel 95";
158 static const sal_Char __FAR_DATA pFilterEx95Temp[]  = "MS Excel 95 Vorlage/Template";
159 static const sal_Char __FAR_DATA pFilterExcel97[]   = "MS Excel 97";
160 static const sal_Char __FAR_DATA pFilterEx97Temp[]  = "MS Excel 97 Vorlage/Template";
161 static const sal_Char __FAR_DATA pFilterEx07Xml[]   = "MS Excel 2007 XML";
162 static const sal_Char __FAR_DATA pFilterDBase[]     = "dBase";
163 static const sal_Char __FAR_DATA pFilterDif[]       = "DIF";
164 static const sal_Char __FAR_DATA pFilterSylk[]      = "SYLK";
165 static const sal_Char __FAR_DATA pFilterHtml[]      = "HTML (StarCalc)";
166 static const sal_Char __FAR_DATA pFilterHtmlWebQ[]  = "calc_HTML_WebQuery";
167 static const sal_Char __FAR_DATA pFilterRtf[]       = "Rich Text Format (StarCalc)";
168 
169 //----------------------------------------------------------------------
170 
171 #define ScDocShell
172 #include "scslots.hxx"
173 
174 
175 SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL))
176 {
177     SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
178 }
179 
180 //  GlobalName der aktuellen Version:
181 SFX_IMPL_OBJECTFACTORY( ScDocShell, SvGlobalName(SO3_SC_CLASSID), SFXOBJECTSHELL_STD_NORMAL, "scalc" )
182 
183 TYPEINIT1( ScDocShell, SfxObjectShell );        // SfxInPlaceObject: kein Type-Info ?
184 
185 //------------------------------------------------------------------
186 
187 void __EXPORT ScDocShell::FillClass( SvGlobalName* pClassName,
188                                         sal_uInt32* pFormat,
189                                         String* /* pAppName */,
190                                         String* pFullTypeName,
191                                         String* pShortTypeName,
192                                         sal_Int32 nFileFormat,
193                                         sal_Bool bTemplate /* = sal_False */) const
194 {
195     if ( nFileFormat == SOFFICE_FILEFORMAT_60 )
196     {
197         *pClassName     = SvGlobalName( SO3_SC_CLASSID_60 );
198         *pFormat        = SOT_FORMATSTR_ID_STARCALC_60;
199         *pFullTypeName  = String( ScResId( SCSTR_LONG_SCDOC_NAME ) );
200         *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
201     }
202     else if ( nFileFormat == SOFFICE_FILEFORMAT_8 )
203     {
204         *pClassName     = SvGlobalName( SO3_SC_CLASSID_60 );
205         *pFormat        = bTemplate ? SOT_FORMATSTR_ID_STARCALC_8_TEMPLATE : SOT_FORMATSTR_ID_STARCALC_8;
206         *pFullTypeName  = String( RTL_CONSTASCII_USTRINGPARAM("calc8") );
207         *pShortTypeName = String( ScResId( SCSTR_SHORT_SCDOC_NAME ) );
208     }
209     else
210     {
211         DBG_ERROR("wat fuer ne Version?");
212     }
213 }
214 
215 //------------------------------------------------------------------
216 
217 void ScDocShell::DoEnterHandler()
218 {
219     ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
220     if (pViewSh)
221         if (pViewSh->GetViewData()->GetDocShell() == this)
222             SC_MOD()->InputEnterHandler();
223 }
224 
225 //------------------------------------------------------------------
226 
227 SCTAB ScDocShell::GetSaveTab()
228 {
229     SCTAB nTab = 0;
230     ScTabViewShell* pSh = GetBestViewShell();
231     if (pSh)
232     {
233         const ScMarkData& rMark = pSh->GetViewData()->GetMarkData();
234         for ( nTab = 0; nTab <= MAXTAB; nTab++ )    // erste markierte Tabelle
235             if ( rMark.GetTableSelect( nTab ) )
236                 break;
237     }
238     return nTab;
239 }
240 
241 sal_uInt16 ScDocShell::GetHiddenInformationState( sal_uInt16 nStates )
242 {
243     // get global state like HIDDENINFORMATION_DOCUMENTVERSIONS
244     sal_uInt16 nState = SfxObjectShell::GetHiddenInformationState( nStates );
245 
246     if ( nStates & HIDDENINFORMATION_RECORDEDCHANGES )
247     {
248         if ( aDocument.GetChangeTrack() && aDocument.GetChangeTrack()->GetFirst() )
249           nState |= HIDDENINFORMATION_RECORDEDCHANGES;
250     }
251     if ( nStates & HIDDENINFORMATION_NOTES )
252     {
253         SCTAB nTableCount = aDocument.GetTableCount();
254         SCTAB nTable = 0;
255         sal_Bool bFound(sal_False);
256         while ( nTable < nTableCount && !bFound )
257         {
258             ScCellIterator aCellIter( &aDocument, 0,0, nTable, MAXCOL,MAXROW, nTable );
259             for( ScBaseCell* pCell = aCellIter.GetFirst(); pCell && !bFound; pCell = aCellIter.GetNext() )
260                 if (pCell->HasNote())
261                     bFound = sal_True;
262             nTable++;
263         }
264 
265         if (bFound)
266             nState |= HIDDENINFORMATION_NOTES;
267     }
268 
269     return nState;
270 }
271 
272 void ScDocShell::BeforeXMLLoading()
273 {
274     aDocument.DisableIdle( sal_True );
275 
276     // prevent unnecessary broadcasts and updates
277     DBG_ASSERT(pModificator == NULL, "The Modificator should not exist");
278     pModificator = new ScDocShellModificator( *this );
279 
280     aDocument.SetImportingXML( sal_True );
281     aDocument.EnableExecuteLink( false );   // #i101304# to be safe, prevent nested loading from external references
282     aDocument.EnableUndo( sal_False );
283     // prevent unnecessary broadcasts and "half way listeners"
284     aDocument.SetInsertingFromOtherDoc( sal_True );
285 
286     if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
287         ScColumn::bDoubleAlloc = sal_True;
288 }
289 
290 void ScDocShell::AfterXMLLoading(sal_Bool bRet)
291 {
292     if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
293     {
294         UpdateLinks();
295         // don't prevent establishing of listeners anymore
296         aDocument.SetInsertingFromOtherDoc( sal_False );
297         if ( bRet )
298         {
299             ScChartListenerCollection* pChartListener = aDocument.GetChartListenerCollection();
300             if (pChartListener)
301                 pChartListener->UpdateDirtyCharts();
302 
303             // #95582#; set the table names of linked tables to the new path
304             SCTAB nTabCount = aDocument.GetTableCount();
305             for (SCTAB i = 0; i < nTabCount; ++i)
306             {
307                 if (aDocument.IsLinked( i ))
308                 {
309                     String aName;
310                     aDocument.GetName(i, aName);
311                     String aLinkTabName = aDocument.GetLinkTab(i);
312                     xub_StrLen nLinkTabNameLength = aLinkTabName.Len();
313                     xub_StrLen nNameLength = aName.Len();
314                     if (nLinkTabNameLength < nNameLength)
315                     {
316 
317                         // remove the quottes on begin and end of the docname and restore the escaped quotes
318                         const sal_Unicode* pNameBuffer = aName.GetBuffer();
319                         if ( *pNameBuffer == '\'' && // all docnames have to have a ' character on the first pos
320                             ScGlobal::UnicodeStrChr( pNameBuffer, SC_COMPILER_FILE_TAB_SEP ) )
321                         {
322                             rtl::OUStringBuffer aDocURLBuffer;
323                             sal_Bool bQuote = sal_True;         // Dokumentenname ist immer quoted
324                             ++pNameBuffer;
325                             while ( bQuote && *pNameBuffer )
326                             {
327                                 if ( *pNameBuffer == '\'' && *(pNameBuffer-1) != '\\' )
328                                     bQuote = sal_False;
329                                 else if( !(*pNameBuffer == '\\' && *(pNameBuffer+1) == '\'') )
330                                     aDocURLBuffer.append(*pNameBuffer);     // falls escaped Quote: nur Quote in den Namen
331                                 ++pNameBuffer;
332                             }
333 
334 
335                             if( *pNameBuffer == SC_COMPILER_FILE_TAB_SEP )  // after the last quote of the docname should be the # char
336                             {
337                                 xub_StrLen nIndex = nNameLength - nLinkTabNameLength;
338                                 INetURLObject aINetURLObject(aDocURLBuffer.makeStringAndClear());
339                                 if( aName.Equals(aLinkTabName, nIndex, nLinkTabNameLength) &&
340                                     (aName.GetChar(nIndex - 1) == '#') && // before the table name should be the # char
341                                     !aINetURLObject.HasError()) // the docname should be a valid URL
342                                 {
343                                     aName = ScGlobal::GetDocTabName( aDocument.GetLinkDoc( i ), aDocument.GetLinkTab( i ) );
344                                     aDocument.RenameTab(i, aName, sal_True, sal_True);
345                                 }
346                                 // else;  nothing has to happen, because it is a user given name
347                             }
348                             // else;  nothing has to happen, because it is a user given name
349                         }
350                         // else;  nothing has to happen, because it is a user given name
351                     }
352                     // else;  nothing has to happen, because it is a user given name
353                 }
354             }
355 
356             // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API.
357             // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name.
358             ScDPCollection* pDPCollection = aDocument.GetDPCollection();
359             if ( pDPCollection )
360             {
361                 sal_uInt16 nDPCount = pDPCollection->GetCount();
362                 for (sal_uInt16 nDP=0; nDP<nDPCount; nDP++)
363                 {
364                     ScDPObject* pDPObj = (*pDPCollection)[nDP];
365                     if ( !pDPObj->GetName().Len() )
366                         pDPObj->SetName( pDPCollection->CreateNewName() );
367                 }
368             }
369         }
370         ScColumn::bDoubleAlloc = sal_False;
371     }
372     else
373         aDocument.SetInsertingFromOtherDoc( sal_False );
374 
375     aDocument.SetImportingXML( sal_False );
376     aDocument.EnableExecuteLink( true );
377     aDocument.EnableUndo( sal_True );
378     bIsEmpty = sal_False;
379 
380     if (pModificator)
381     {
382         delete pModificator;
383         pModificator = NULL;
384     }
385     else
386     {
387         DBG_ERROR("The Modificator should exist");
388     }
389 
390     aDocument.DisableIdle( sal_False );
391 }
392 
393 sal_Bool ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
394 {
395     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::LoadXML" );
396 
397     //  MacroCallMode is no longer needed, state is kept in SfxObjectShell now
398 
399     // no Seek(0) here - always loading from storage, GetInStream must not be called
400 
401     BeforeXMLLoading();
402 
403     // #i62677# BeforeXMLLoading is also called from ScXMLImport::startDocument when invoked
404     // from an external component. The XMLFromWrapper flag is only set here, when called
405     // through ScDocShell.
406     aDocument.SetXMLFromWrapper( sal_True );
407 
408     ScXMLImportWrapper aImport( aDocument, pLoadMedium, xStor );
409 
410     sal_Bool bRet(sal_False);
411     ErrCode nError = ERRCODE_NONE;
412     if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
413         bRet = aImport.Import(sal_False, nError);
414     else
415         bRet = aImport.Import(sal_True, nError);
416 
417     if ( nError )
418         pLoadMedium->SetError( nError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
419 
420     aDocument.SetXMLFromWrapper( sal_False );
421     AfterXMLLoading(bRet);
422 
423     //! row heights...
424 
425     return bRet;
426 }
427 
428 sal_Bool ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
429 {
430     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::SaveXML" );
431 
432     aDocument.DisableIdle( sal_True );
433 
434     ScXMLImportWrapper aImport( aDocument, pSaveMedium, xStor );
435     sal_Bool bRet(sal_False);
436     if (GetCreateMode() != SFX_CREATE_MODE_ORGANIZER)
437         bRet = aImport.Export(sal_False);
438     else
439         bRet = aImport.Export(sal_True);
440 
441     aDocument.DisableIdle( sal_False );
442 
443     return bRet;
444 }
445 
446 sal_Bool __EXPORT ScDocShell::Load( SfxMedium& rMedium )
447 {
448     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" );
449 
450     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
451 
452     //  only the latin script language is loaded
453     //  -> initialize the others from options (before loading)
454     InitOptions(true);
455 
456     GetUndoManager()->Clear();
457 
458     sal_Bool bRet = SfxObjectShell::Load( rMedium );
459     if( bRet )
460     {
461         if (GetMedium())
462         {
463             SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
464             nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
465         }
466 
467         {
468             //  prepare a valid document for XML filter
469             //  (for ConvertFrom, InitNew is called before)
470             aDocument.MakeTable(0);
471             aDocument.GetStyleSheetPool()->CreateStandardStyles();
472             aDocument.UpdStlShtPtrsFrmNms();
473 
474             bRet = LoadXML( &rMedium, NULL );
475         }
476     }
477 
478     if (!bRet && !rMedium.GetError())
479         rMedium.SetError( SVSTREAM_FILEFORMAT_ERROR, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
480 
481     if (rMedium.GetError())
482         SetError( rMedium.GetError(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
483 
484     InitItems();
485     CalcOutputFactor();
486 
487     // #73762# invalidate eventually temporary table areas
488     if ( bRet )
489         aDocument.InvalidateTableArea();
490 
491     bIsEmpty = sal_False;
492     FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
493     return bRet;
494 }
495 
496 void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
497 {
498     if (rHint.ISA(ScTablesHint) )
499     {
500         const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint );
501         if (rScHint.GetId() == SC_TAB_INSERTED)
502         {
503             uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor();
504             if ( xVbaEvents.is() ) try
505             {
506                 uno::Sequence< uno::Any > aArgs( 1 );
507                 aArgs[0] <<= rScHint.GetTab1();
508                 xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_NEWSHEET, aArgs );
509             }
510             catch( uno::Exception& )
511             {
512             }
513         }
514     }
515 
516     if (rHint.ISA(SfxSimpleHint))                               // ohne Parameter
517     {
518         sal_uLong nSlot = ((const SfxSimpleHint&)rHint).GetId();
519         switch ( nSlot )
520         {
521             case SFX_HINT_TITLECHANGED:
522                 aDocument.SetName( SfxShell::GetName() );
523                 //  RegisterNewTargetNames gibts nicht mehr
524                 SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DOCNAME_CHANGED )); // Navigator
525                 break;
526         }
527     }
528     else if (rHint.ISA(SfxStyleSheetHint))                      // Vorlagen geaendert
529         NotifyStyle((const SfxStyleSheetHint&) rHint);
530     else if (rHint.ISA(ScAutoStyleHint))
531     {
532         //! direct call for AutoStyles
533 
534         //  this is called synchronously from ScInterpreter::ScStyle,
535         //  modifying the document must be asynchronous
536         //  (handled by AddInitial)
537 
538         ScAutoStyleHint& rStlHint = (ScAutoStyleHint&)rHint;
539         ScRange aRange = rStlHint.GetRange();
540         String aName1 = rStlHint.GetStyle1();
541         String aName2 = rStlHint.GetStyle2();
542         sal_uInt32 nTimeout = rStlHint.GetTimeout();
543 
544         if (!pAutoStyleList)
545             pAutoStyleList = new ScAutoStyleList(this);
546         pAutoStyleList->AddInitial( aRange, aName1, nTimeout, aName2 );
547     }
548     else if ( rHint.ISA( SfxEventHint ) )
549     {
550         sal_uLong nEventId = ((SfxEventHint&)rHint).GetEventId();
551         switch ( nEventId )
552         {
553             case SFX_EVENT_LOADFINISHED:
554                 {
555                     // the readonly documents should not be opened in shared mode
556                     if ( HasSharedXMLFlagSet() && !SC_MOD()->IsInSharedDocLoading() && !IsReadOnly() )
557                     {
558                         if ( SwitchToShared( sal_True, sal_False ) )
559                         {
560                             ScViewData* pViewData = GetViewData();
561                             ScTabView* pTabView = ( pViewData ? dynamic_cast< ScTabView* >( pViewData->GetView() ) : NULL );
562                             if ( pTabView )
563                             {
564                                 pTabView->UpdateLayerLocks();
565                             }
566                         }
567                         else
568                         {
569                             // switching to shared mode has failed, the document should be opened readonly
570                             // TODO/LATER: And error message should be shown here probably
571                             SetReadOnlyUI( sal_True );
572                         }
573                     }
574                 }
575                 break;
576             case SFX_EVENT_VIEWCREATED:
577                 {
578                     if ( IsDocShared() && !SC_MOD()->IsInSharedDocLoading() )
579                     {
580                         ScAppOptions aAppOptions = SC_MOD()->GetAppOptions();
581                         if ( aAppOptions.GetShowSharedDocumentWarning() )
582                         {
583                             WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
584                                 ScGlobal::GetRscString( STR_SHARED_DOC_WARNING ) );
585                             aBox.SetDefaultCheckBoxText();
586                             aBox.Execute();
587                             sal_Bool bChecked = aBox.GetCheckBoxState();
588                             if ( bChecked )
589                             {
590                                 aAppOptions.SetShowSharedDocumentWarning( !bChecked );
591                                 SC_MOD()->SetAppOptions( aAppOptions );
592                             }
593                         }
594                     }
595 
596                     try
597                     {
598                         uno::Reference< uno::XComponentContext > xContext;
599                         uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
600                         uno::Reference< beans::XPropertySet > xProp( xServiceManager, uno::UNO_QUERY_THROW );
601                         xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext;
602                         if ( xContext.is() )
603                         {
604                             uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW );
605                             uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration(
606                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocumentJob" ) ) );
607                             if ( xEnum.is() )
608                             {
609                                 while ( xEnum->hasMoreElements() )
610                                 {
611                                     uno::Any aAny = xEnum->nextElement();
612                                     uno::Reference< lang::XSingleComponentFactory > xFactory;
613                                     aAny >>= xFactory;
614                                     if ( xFactory.is() )
615                                     {
616                                         uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW );
617                                         uno::Sequence< beans::NamedValue > aArgsForJob(1);
618                                         ScViewData* pViewData = GetViewData();
619                                         SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : NULL );
620                                         SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : NULL );
621                                         SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : NULL );
622                                         uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : 0 );
623                                         uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW );
624                                         aArgsForJob[0] = beans::NamedValue( ::rtl::OUString::createFromAscii( "SpreadsheetView" ),
625                                             uno::makeAny( xSpreadsheetView ) );
626                                         xJob->execute( aArgsForJob );
627                                     }
628                                 }
629                             }
630                         }
631                     }
632                     catch ( uno::Exception & )
633                     {
634                     }
635                 }
636                 break;
637             case SFX_EVENT_SAVEDOC:
638                 {
639                     if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
640                     {
641                         bool bSuccess = false;
642                         bool bRetry = true;
643                         while ( bRetry )
644                         {
645                             bRetry = false;
646                             uno::Reference< frame::XModel > xModel;
647                             try
648                             {
649                                 // load shared file
650                                 xModel.set( LoadSharedDocument(), uno::UNO_QUERY_THROW );
651                                 uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );
652 
653                                 // check if shared flag is set in shared file
654                                 bool bShared = false;
655                                 ScModelObj* pDocObj = ScModelObj::getImplementation( xModel );
656                                 ScDocShell* pSharedDocShell = ( pDocObj ? dynamic_cast< ScDocShell* >( pDocObj->GetObjectShell() ) : NULL );
657                                 if ( pSharedDocShell )
658                                 {
659                                     bShared = pSharedDocShell->HasSharedXMLFlagSet();
660                                 }
661 
662                                 // #i87870# check if shared status was disabled and enabled again
663                                 bool bOwnEntry = false;
664                                 bool bEntriesNotAccessible = false;
665                                 try
666                                 {
667                                     ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
668                                     bOwnEntry = aControlFile.HasOwnEntry();
669                                 }
670                                 catch ( uno::Exception& )
671                                 {
672                                     bEntriesNotAccessible = true;
673                                 }
674 
675                                 if ( bShared && bOwnEntry )
676                                 {
677                                     uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
678 
679                                     if ( xStorable->isReadonly() )
680                                     {
681                                         xCloseable->close( sal_True );
682 
683                                         String aUserName( ScGlobal::GetRscString( STR_UNKNOWN_USER ) );
684                                         bool bNoLockAccess = false;
685                                         try
686                                         {
687                                             ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
688                                             uno::Sequence< ::rtl::OUString > aData = aLockFile.GetLockData();
689                                             if ( aData.getLength() > LOCKFILE_SYSUSERNAME_ID )
690                                             {
691                                                 if ( aData[LOCKFILE_OOOUSERNAME_ID].getLength() > 0 )
692                                                 {
693                                                     aUserName = aData[LOCKFILE_OOOUSERNAME_ID];
694                                                 }
695                                                 else if ( aData[LOCKFILE_SYSUSERNAME_ID].getLength() > 0 )
696                                                 {
697                                                     aUserName = aData[LOCKFILE_SYSUSERNAME_ID];
698                                                 }
699                                             }
700                                         }
701                                         catch ( uno::Exception& )
702                                         {
703                                             bNoLockAccess = true;
704                                         }
705 
706                                         if ( bNoLockAccess )
707                                         {
708                                             // TODO/LATER: in future an error regarding impossibility to open file for writing could be shown
709                                             ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
710                                         }
711                                         else
712                                         {
713                                             String aMessage( ScGlobal::GetRscString( STR_FILE_LOCKED_SAVE_LATER ) );
714                                             aMessage.SearchAndReplaceAscii( "%1", aUserName );
715 
716                                             WarningBox aBox( GetActiveDialogParent(), WinBits( WB_RETRY_CANCEL | WB_DEF_RETRY ), aMessage );
717                                             if ( aBox.Execute() == RET_RETRY )
718                                             {
719                                                 bRetry = true;
720                                             }
721                                         }
722                                     }
723                                     else
724                                     {
725                                         // merge changes from shared file into temp file
726                                         bool bSaveToShared = false;
727                                         if ( pSharedDocShell )
728                                         {
729                                             bSaveToShared = MergeSharedDocument( pSharedDocShell );
730                                         }
731 
732                                         // close shared file
733                                         xCloseable->close( sal_True );
734 
735                                         // TODO: keep file lock on shared file
736 
737                                         // store to shared file
738                                         if ( bSaveToShared )
739                                         {
740                                             bool bChangedViewSettings = false;
741                                             ScChangeViewSettings* pChangeViewSet = aDocument.GetChangeViewSettings();
742                                             if ( pChangeViewSet && pChangeViewSet->ShowChanges() )
743                                             {
744                                                 pChangeViewSet->SetShowChanges( sal_False );
745                                                 pChangeViewSet->SetShowAccepted( sal_False );
746                                                 aDocument.SetChangeViewSettings( *pChangeViewSet );
747                                                 bChangedViewSettings = true;
748                                             }
749 
750                                             uno::Reference< frame::XStorable > xStor( GetModel(), uno::UNO_QUERY_THROW );
751                                             // TODO/LATER: More entries from the MediaDescriptor might be interesting for the merge
752                                             uno::Sequence< beans::PropertyValue > aValues(1);
753                                             aValues[0].Name = ::rtl::OUString::createFromAscii( "FilterName" );
754                                             aValues[0].Value <<= ::rtl::OUString( GetMedium()->GetFilter()->GetFilterName() );
755 
756                                             SFX_ITEMSET_ARG( GetMedium()->GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
757                                             if ( pPasswordItem && pPasswordItem->GetValue().Len() )
758                                             {
759                                                 aValues.realloc( 2 );
760                                                 aValues[1].Name = ::rtl::OUString::createFromAscii( "Password" );
761                                                 aValues[1].Value <<= ::rtl::OUString( pPasswordItem->GetValue() );
762                                             }
763 
764                                             SC_MOD()->SetInSharedDocSaving( true );
765                                             xStor->storeToURL( GetSharedFileURL(), aValues );
766                                             SC_MOD()->SetInSharedDocSaving( false );
767 
768                                             if ( bChangedViewSettings )
769                                             {
770                                                 pChangeViewSet->SetShowChanges( sal_True );
771                                                 pChangeViewSet->SetShowAccepted( sal_True );
772                                                 aDocument.SetChangeViewSettings( *pChangeViewSet );
773                                             }
774                                         }
775 
776                                         bSuccess = true;
777                                         GetUndoManager()->Clear();
778                                     }
779                                 }
780                                 else
781                                 {
782                                     xCloseable->close( sal_True );
783 
784                                     if ( bEntriesNotAccessible )
785                                     {
786                                         // TODO/LATER: in future an error regarding impossibility to write to share control file could be shown
787                                         ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
788                                     }
789                                     else
790                                     {
791                                         WarningBox aBox( GetActiveDialogParent(), WinBits( WB_OK ),
792                                             ScGlobal::GetRscString( STR_DOC_NOLONGERSHARED ) );
793                                         aBox.Execute();
794 
795                                         SfxBindings* pBindings = GetViewBindings();
796                                         if ( pBindings )
797                                         {
798                                             pBindings->ExecuteSynchron( SID_SAVEASDOC );
799                                         }
800                                     }
801                                 }
802                             }
803                             catch ( uno::Exception& )
804                             {
805                                 DBG_ERROR( "SFX_EVENT_SAVEDOC: caught exception\n" );
806                                 SC_MOD()->SetInSharedDocSaving( false );
807 
808                                 try
809                                 {
810                                     uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
811                                     xClose->close( sal_True );
812                                 }
813                                 catch ( uno::Exception& )
814                                 {
815                                 }
816                             }
817                         }
818 
819                         if ( !bSuccess )
820                             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
821                     }
822                     if (pSheetSaveData)
823                         pSheetSaveData->SetInSupportedSave(true);
824                 }
825                 break;
826             case SFX_EVENT_SAVEASDOC:
827             case SFX_EVENT_SAVETODOC:
828                 // #i108978# If no event is sent before saving, there will also be no "...DONE" event,
829                 // and SAVE/SAVEAS can't be distinguished from SAVETO. So stream copying is only enabled
830                 // if there is a SAVE/SAVEAS/SAVETO event first.
831                 if (pSheetSaveData)
832                     pSheetSaveData->SetInSupportedSave(true);
833                 break;
834             case SFX_EVENT_SAVEDOCDONE:
835                 {
836                     if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
837                     {
838                     }
839                     UseSheetSaveEntries();      // use positions from saved file for next saving
840                     if (pSheetSaveData)
841                         pSheetSaveData->SetInSupportedSave(false);
842                 }
843                 break;
844             case SFX_EVENT_SAVEASDOCDONE:
845                 // new positions are used after "save" and "save as", but not "save to"
846                 UseSheetSaveEntries();      // use positions from saved file for next saving
847                 if (pSheetSaveData)
848                     pSheetSaveData->SetInSupportedSave(false);
849                 break;
850             case SFX_EVENT_SAVETODOCDONE:
851                 // only reset the flag, don't use the new positions
852                 if (pSheetSaveData)
853                     pSheetSaveData->SetInSupportedSave(false);
854                 break;
855             default:
856                 {
857                 }
858                 break;
859         }
860     }
861 }
862 
863     // Inhalte fuer Organizer laden
864 
865 
866 sal_Bool __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium )
867 {
868     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::LoadFrom" );
869 
870     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
871 
872     WaitObject aWait( GetActiveDialogParent() );
873 
874     sal_Bool bRet = sal_False;
875 
876     if (GetMedium())
877     {
878         SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
879         nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
880     }
881 
882     //  until loading/saving only the styles in XML is implemented,
883     //  load the whole file
884     bRet = LoadXML( &rMedium, NULL );
885     InitItems();
886 
887     SfxObjectShell::LoadFrom( rMedium );
888 
889     return bRet;
890 }
891 
892 static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert)
893 {
894     OUStringBuffer aBuf;
895     OUString aTokens[2];
896     sal_Int32 n = rOption.getLength();
897     const sal_Unicode* p = rOption.getStr();
898     sal_Int32 nTokenId = 0;
899     for (sal_Int32 i = 0; i < n; ++i)
900     {
901         const sal_Unicode c = p[i];
902         if (c == sal_Unicode(' '))
903         {
904             if (aBuf.getLength())
905                 aTokens[nTokenId++] = aBuf.makeStringAndClear();
906         }
907         else
908             aBuf.append(c);
909 
910         if (nTokenId >= 2)
911             break;
912     }
913 
914     if (aBuf.getLength())
915         aTokens[nTokenId] = aBuf.makeStringAndClear();
916 
917     rLang = static_cast<LanguageType>(aTokens[0].toInt32());
918     rDateConvert = static_cast<bool>(aTokens[1].toInt32());
919 }
920 
921 namespace {
922 
923 class LoadMediumGuard
924 {
925 public:
926     explicit LoadMediumGuard(ScDocument* pDoc) :
927         mpDoc(pDoc)
928     {
929         mpDoc->SetLoadingMedium(true);
930     }
931 
932     ~LoadMediumGuard()
933     {
934         mpDoc->SetLoadingMedium(false);
935     }
936 private:
937     ScDocument* mpDoc;
938 };
939 
940 }
941 
942 sal_Bool __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
943 {
944     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" );
945 
946     LoadMediumGuard aLoadGuard(&aDocument);
947 
948     sal_Bool bRet = sal_False;              // sal_False heisst Benutzerabbruch !!
949                                     // bei Fehler: Fehler am Stream setzen!!
950 
951     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
952 
953     GetUndoManager()->Clear();
954 
955     // ob nach dem Import optimale Spaltenbreiten gesetzt werden sollen
956     sal_Bool bSetColWidths = sal_False;
957     sal_Bool bSetSimpleTextColWidths = sal_False;
958     sal_Bool bSimpleColWidth[MAXCOLCOUNT];
959     memset( bSimpleColWidth, 1, (MAXCOLCOUNT) * sizeof(sal_Bool) );
960     ScRange aColWidthRange;
961     // ob nach dem Import optimale Zeilenhoehen gesetzt werden sollen
962     sal_Bool bSetRowHeights = sal_False;
963 
964     aConvFilterName.Erase(); //@ #BugId 54198
965 
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
970 
971     SFX_ITEMSET_ARG( rMedium.GetItemSet(), pUpdateDocItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False);
972     nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : com::sun::star::document::UpdateDocMode::NO_UPDATE;
973 
974     const SfxFilter* pFilter = rMedium.GetFilter();
975     if (pFilter)
976     {
977         String aFltName = pFilter->GetFilterName();
978 
979         aConvFilterName=aFltName; //@ #BugId 54198
980 
981         sal_Bool bCalc3 = ( aFltName.EqualsAscii(pFilterSc30) );
982         sal_Bool bCalc4 = ( aFltName.EqualsAscii(pFilterSc40) );
983         if (!bCalc3 && !bCalc4)
984             aDocument.SetInsertingFromOtherDoc( sal_True );
985 
986         if (aFltName.EqualsAscii(pFilterXML))
987             bRet = LoadXML( &rMedium, NULL );
988         else if (aFltName.EqualsAscii(pFilterSc10))
989         {
990             SvStream* pStream = rMedium.GetInStream();
991             if (pStream)
992             {
993                 FltError eError = ScFormatFilter::Get().ScImportStarCalc10( *pStream, &aDocument );
994                 if (eError != eERR_OK)
995                 {
996                     if (!GetError())
997                         SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
998                 }
999                 else
1000                     bRet = sal_True;
1001             }
1002         }
1003         else if (aFltName.EqualsAscii(pFilterLotus))
1004         {
1005             String sItStr;
1006             SfxItemSet*  pSet = rMedium.GetItemSet();
1007             const SfxPoolItem* pItem;
1008             if ( pSet && SFX_ITEM_SET ==
1009                  pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
1010             {
1011                 sItStr = ((const SfxStringItem*)pItem)->GetValue();
1012             }
1013 
1014             if (sItStr.Len() == 0)
1015             {
1016                 //  default for lotus import (from API without options):
1017                 //  IBM_437 encoding
1018                 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_437 );
1019             }
1020 
1021             ScColumn::bDoubleAlloc = sal_True;
1022             FltError eError = ScFormatFilter::Get().ScImportLotus123( rMedium, &aDocument,
1023                                                 ScGlobal::GetCharsetValue(sItStr));
1024             ScColumn::bDoubleAlloc = sal_False;
1025             if (eError != eERR_OK)
1026             {
1027                 if (!GetError())
1028                     SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1029 
1030                 if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1031                     bRet = sal_True;
1032             }
1033             else
1034                 bRet = sal_True;
1035             bSetColWidths = sal_True;
1036             bSetRowHeights = sal_True;
1037         }
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) )
1042         {
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;
1051 
1052             MakeDrawLayer();                //! im Filter
1053             CalcOutputFactor();             // #93255# prepare update of row height
1054             ScColumn::bDoubleAlloc = sal_True;
1055             FltError eError = ScFormatFilter::Get().ScImportExcel( rMedium, &aDocument, eFormat );
1056             ScColumn::bDoubleAlloc = sal_False;
1057             aDocument.UpdateFontCharSet();
1058             if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
1059                 aDocument.UpdateChartListenerCollection();              //! fuer alle Importe?
1060 
1061             // #75299# all graphics objects must have names
1062             aDocument.EnsureGraphicNames();
1063 
1064             if (eError == SCWARN_IMPORT_RANGE_OVERFLOW)
1065             {
1066                 if (!GetError())
1067                     SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1068                 bRet = sal_True;
1069             }
1070             else if (eError != eERR_OK)
1071             {
1072                 if (!GetError())
1073                     SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1074             }
1075             else
1076                 bRet = sal_True;
1077 
1078             // #93255# update of row height done inside of Excel filter to speed up chart import
1079 //            bSetRowHeights = sal_True;      //  #75357# optimal row heights must be updated
1080         }
1081         else if (aFltName.EqualsAscii(pFilterAscii))
1082         {
1083             SfxItemSet*  pSet = rMedium.GetItemSet();
1084             const SfxPoolItem* pItem;
1085             ScAsciiOptions aOptions;
1086             sal_Bool bOptInit = sal_False;
1087 
1088             if ( pSet && SFX_ITEM_SET ==
1089                  pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
1090             {
1091                 aOptions.ReadFromString( ((const SfxStringItem*)pItem)->GetValue() );
1092                 bOptInit = sal_True;
1093             }
1094 
1095             if ( !bOptInit )
1096             {
1097                 //  default for ascii import (from API without options):
1098                 //  ISO8859-1/MS_1252 encoding, comma, double quotes
1099 
1100                 aOptions.SetCharSet( RTL_TEXTENCODING_MS_1252 );
1101                 aOptions.SetFieldSeps( (sal_Unicode) ',' );
1102                 aOptions.SetTextSep( (sal_Unicode) '"' );
1103             }
1104 
1105             FltError eError = eERR_OK;
1106             sal_Bool bOverflow = sal_False;
1107 
1108             if( ! rMedium.IsStorage() )
1109             {
1110                 ScImportExport  aImpEx( &aDocument );
1111                 aImpEx.SetExtOptions( aOptions );
1112 
1113                 SvStream* pInStream = rMedium.GetInStream();
1114                 if (pInStream)
1115                 {
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();
1123                 }
1124                 else
1125                 {
1126                     DBG_ERROR( "No Stream" );
1127                 }
1128             }
1129 
1130             if (eError != eERR_OK)
1131             {
1132                 if (!GetError())
1133                     SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1134             }
1135             else if ( bOverflow )
1136             {
1137                 if (!GetError())
1138                     SetError(SCWARN_IMPORT_RANGE_OVERFLOW, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1139             }
1140             bSetColWidths = sal_True;
1141             bSetSimpleTextColWidths = sal_True;
1142         }
1143         else if (aFltName.EqualsAscii(pFilterDBase))
1144         {
1145             String sItStr;
1146             SfxItemSet*  pSet = rMedium.GetItemSet();
1147             const SfxPoolItem* pItem;
1148             if ( pSet && SFX_ITEM_SET ==
1149                  pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
1150             {
1151                 sItStr = ((const SfxStringItem*)pItem)->GetValue();
1152             }
1153 
1154             if (sItStr.Len() == 0)
1155             {
1156                 //  default for dBase import (from API without options):
1157                 //  IBM_850 encoding
1158 
1159                 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
1160             }
1161 
1162             sal_uLong eError = DBaseImport( rMedium.GetPhysicalName(),
1163                     ScGlobal::GetCharsetValue(sItStr), bSimpleColWidth );
1164 
1165             if (eError != eERR_OK)
1166             {
1167                 if (!GetError())
1168                     SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1169                 bRet = ( eError == SCWARN_IMPORT_RANGE_OVERFLOW );
1170             }
1171             else
1172                 bRet = sal_True;
1173 
1174             aColWidthRange.aStart.SetRow( 1 );  // Spaltenheader nicht
1175             bSetColWidths = sal_True;
1176             bSetSimpleTextColWidths = sal_True;
1177             // Memo-Felder fuehren zu einem bSimpleColWidth[nCol]==FALSE
1178             for ( SCCOL nCol=0; nCol <= MAXCOL && !bSetRowHeights; nCol++ )
1179             {
1180                 if ( !bSimpleColWidth[nCol] )
1181                     bSetRowHeights = sal_True;
1182             }
1183         }
1184         else if (aFltName.EqualsAscii(pFilterDif))
1185         {
1186             SvStream* pStream = rMedium.GetInStream();
1187             if (pStream)
1188             {
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, sal_True, &pItem ) )
1195                 {
1196                     sItStr = ((const SfxStringItem*)pItem)->GetValue();
1197                 }
1198 
1199                 if (sItStr.Len() == 0)
1200                 {
1201                     //  default for DIF import (from API without options):
1202                     //  ISO8859-1/MS_1252 encoding
1203 
1204                     sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
1205                 }
1206 
1207                 eError = ScFormatFilter::Get().ScImportDif( *pStream, &aDocument, ScAddress(0,0,0),
1208                                     ScGlobal::GetCharsetValue(sItStr));
1209                 if (eError != eERR_OK)
1210                 {
1211                     if (!GetError())
1212                         SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1213 
1214                     if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1215                         bRet = sal_True;
1216                 }
1217                 else
1218                     bRet = sal_True;
1219             }
1220             bSetColWidths = sal_True;
1221             bSetSimpleTextColWidths = sal_True;
1222             bSetRowHeights = sal_True;
1223         }
1224         else if (aFltName.EqualsAscii(pFilterSylk))
1225         {
1226             FltError eError = SCERR_IMPORT_UNKNOWN;
1227             if( !rMedium.IsStorage() )
1228             {
1229                 ScImportExport aImpEx( &aDocument );
1230 
1231                 SvStream* pInStream = rMedium.GetInStream();
1232                 if (pInStream)
1233                 {
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();
1239                 }
1240                 else
1241                 {
1242                     DBG_ERROR( "No Stream" );
1243                 }
1244             }
1245 
1246             if ( eError != eERR_OK && !GetError() )
1247                 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1248             bSetColWidths = sal_True;
1249             bSetSimpleTextColWidths = sal_True;
1250             bSetRowHeights = sal_True;
1251         }
1252         else if (aFltName.EqualsAscii(pFilterQPro6))
1253         {
1254             ScColumn::bDoubleAlloc = sal_True;
1255             FltError eError = ScFormatFilter::Get().ScImportQuattroPro( rMedium, &aDocument);
1256             ScColumn::bDoubleAlloc = sal_False;
1257             if (eError != eERR_OK)
1258             {
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 = sal_True;
1263             }
1264             else
1265                 bRet = sal_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 = sal_True;
1271         }
1272         else if (aFltName.EqualsAscii(pFilterRtf))
1273         {
1274             FltError eError = SCERR_IMPORT_UNKNOWN;
1275             if( !rMedium.IsStorage() )
1276             {
1277                 SvStream* pInStream = rMedium.GetInStream();
1278                 if (pInStream)
1279                 {
1280                     pInStream->Seek( 0 );
1281                     ScRange aRange;
1282                     eError = ScFormatFilter::Get().ScImportRTF( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange );
1283                     if (eError != eERR_OK)
1284                     {
1285                         if (!GetError())
1286                             SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1287 
1288                         if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1289                             bRet = sal_True;
1290                     }
1291                     else
1292                         bRet = sal_True;
1293                     aDocument.StartAllListeners();
1294                     aDocument.SetDirty();
1295                     bSetColWidths = sal_True;
1296                     bSetRowHeights = sal_True;
1297                 }
1298                 else
1299                 {
1300                     DBG_ERROR( "No Stream" );
1301                 }
1302             }
1303 
1304             if ( eError != eERR_OK && !GetError() )
1305                 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1306         }
1307         else if (aFltName.EqualsAscii(pFilterHtml) || aFltName.EqualsAscii(pFilterHtmlWebQ))
1308         {
1309             FltError eError = SCERR_IMPORT_UNKNOWN;
1310             sal_Bool bWebQuery = aFltName.EqualsAscii(pFilterHtmlWebQ);
1311             if( !rMedium.IsStorage() )
1312             {
1313                 SvStream* pInStream = rMedium.GetInStream();
1314                 if (pInStream)
1315                 {
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, sal_True, &pItem ) )
1322                     {
1323                         String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue();
1324                         lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert);
1325                     }
1326 
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)
1335                     {
1336                         if (!GetError())
1337                             SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1338 
1339                         if( ( eError & ERRCODE_WARNING_MASK ) == ERRCODE_WARNING_MASK )
1340                             bRet = sal_True;
1341                     }
1342                     else
1343                         bRet = sal_True;
1344                     aDocument.StartAllListeners();
1345                     aDocument.SetDirty();
1346                 }
1347                 else
1348                 {
1349                     DBG_ERROR( "No Stream" );
1350                 }
1351             }
1352 
1353             if ( eError != eERR_OK && !GetError() )
1354                 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1355         }
1356         else
1357         {
1358             if (!GetError())
1359                 SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
1360         }
1361 
1362         if (!bCalc3)
1363             aDocument.SetInsertingFromOtherDoc( sal_False );
1364     }
1365     else
1366     {
1367         DBG_ERROR("Kein Filter bei ConvertFrom");
1368     }
1369 
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++)
1382         {
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 )
1393             {
1394                 for ( SCCOL nCol=0; nCol <= nEndCol; nCol++ )
1395                 {
1396                     sal_uInt16 nWidth = aDocument.GetOptimalColWidth(
1397                         nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoom, aZoom, sal_False, &aMark,
1398                         (bSetSimpleTextColWidths && bSimpleColWidth[nCol]) );
1399                     aDocument.SetColWidth( nCol, nTab,
1400                         nWidth + (sal_uInt16)ScGlobal::nLastColWidthExtra );
1401                 }
1402             }
1403 //          if ( bSetRowHeights )
1404 //          {
1405 //              //  nExtra must be 0
1406 //              aDocument.SetOptimalHeight( 0, nEndRow, nTab, 0, &aVirtDev,
1407 //                  nPPTX, nPPTY, aZoom, aZoom, sal_False );
1408 //          }
1409         }
1410         if ( bSetRowHeights )
1411             UpdateAllRowHeights();      // with vdev or printer, depending on configuration
1412     }
1413     FinishedLoading( SFX_LOADED_MAINDOCUMENT | SFX_LOADED_IMAGES );
1414 
1415     // #73762# invalidate eventually temporary table areas
1416     if ( bRet )
1417         aDocument.InvalidateTableArea();
1418 
1419     bIsEmpty = sal_False;
1420 
1421     return bRet;
1422 }
1423 
1424 
1425 ScDocShell::PrepareSaveGuard::PrepareSaveGuard( ScDocShell& rDocShell )
1426     : mrDocShell( rDocShell)
1427 {
1428     // DoEnterHandler not here (because of AutoSave), is in ExecuteSave.
1429 
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())
1437     {
1438         ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
1439         if (pRefMgr && pRefMgr->hasExternalData())
1440         {
1441             pRefMgr->setAllCacheTableReferencedStati( false);
1442             mrDocShell.aDocument.MarkUsedExternalReferences();  // Mark tables of external references to be written.
1443         }
1444     }
1445     if (mrDocShell.GetCreateMode()== SFX_CREATE_MODE_STANDARD)
1446         mrDocShell.SfxObjectShell::SetVisArea( Rectangle() );   // "Normally" worked on => no VisArea.
1447 }
1448 
1449 ScDocShell::PrepareSaveGuard::~PrepareSaveGuard()
1450 {
1451     if (mrDocShell.aDocument.HasExternalRefManager())
1452     {
1453         ScExternalRefManager* pRefMgr = mrDocShell.aDocument.GetExternalRefManager();
1454         if (pRefMgr && pRefMgr->hasExternalData())
1455         {
1456             // Prevent accidental data loss due to lack of knowledge.
1457             pRefMgr->setAllCacheTableReferencedStati( true);
1458         }
1459     }
1460 }
1461 
1462 
1463 sal_Bool __EXPORT ScDocShell::Save()
1464 {
1465     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Save" );
1466 
1467     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
1468 
1469     PrepareSaveGuard aPrepareGuard( *this);
1470 
1471     //  wait cursor is handled with progress bar
1472     sal_Bool bRet = SfxObjectShell::Save();
1473     if( bRet )
1474         bRet = SaveXML( GetMedium(), NULL );
1475     return bRet;
1476 }
1477 
1478 
1479 sal_Bool __EXPORT ScDocShell::SaveAs( SfxMedium& rMedium )
1480 {
1481     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::SaveAs" );
1482 
1483 #if ENABLE_SHEET_PROTECTION
1484     ScTabViewShell* pViewShell = GetBestViewShell();
1485     if (pViewShell && ScPassHashHelper::needsPassHashRegen(aDocument, PASSHASH_OOO))
1486     {
1487         if (!pViewShell->ExecuteRetypePassDlg(PASSHASH_OOO))
1488             // password re-type cancelled.  Don't save the document.
1489             return false;
1490     }
1491 #endif
1492 
1493     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
1494 
1495     PrepareSaveGuard aPrepareGuard( *this);
1496 
1497     //  wait cursor is handled with progress bar
1498     sal_Bool bRet = SfxObjectShell::SaveAs( rMedium );
1499     if( bRet )
1500         bRet = SaveXML( &rMedium, NULL );
1501 
1502     return bRet;
1503 }
1504 
1505 
1506 sal_Bool __EXPORT ScDocShell::IsInformationLost()
1507 {
1508 /*
1509     const SfxFilter *pFilt = GetMedium()->GetFilter();
1510     sal_Bool bRet = pFilt && pFilt->IsAlienFormat() && bNoInformLost;
1511     if (bNoInformLost)                  // nur einmal!!
1512         bNoInformLost = sal_False;
1513     return bRet;
1514 */
1515     //!!! bei Gelegenheit ein korrekte eigene Behandlung einbauen
1516 
1517     return SfxObjectShell::IsInformationLost();
1518 }
1519 
1520 
1521 // Xcl-like column width measured in characters of standard font.
1522 xub_StrLen lcl_ScDocShell_GetColWidthInChars( sal_uInt16 nWidth )
1523 {
1524     // double fColScale = 1.0;
1525     double  f = nWidth;
1526     f *= 1328.0 / 25.0;
1527     f += 90.0;
1528     f *= 1.0 / 23.0;
1529     // f /= fColScale * 256.0;
1530     f /= 256.0;
1531 
1532     return xub_StrLen( f );
1533 }
1534 
1535 
1536 void lcl_ScDocShell_GetFixedWidthString( String& rStr, const ScDocument& rDoc,
1537         SCTAB nTab, SCCOL nCol, sal_Bool bValue, SvxCellHorJustify eHorJust )
1538 {
1539     xub_StrLen nLen = lcl_ScDocShell_GetColWidthInChars(
1540             rDoc.GetColWidth( nCol, nTab ) );
1541     if ( nLen < rStr.Len() )
1542     {
1543         if ( bValue )
1544             rStr.AssignAscii( "###" );
1545         rStr.Erase( nLen );
1546     }
1547     if ( nLen > rStr.Len() )
1548     {
1549         if ( bValue && eHorJust == SVX_HOR_JUSTIFY_STANDARD )
1550             eHorJust = SVX_HOR_JUSTIFY_RIGHT;
1551         switch ( eHorJust )
1552         {
1553             case SVX_HOR_JUSTIFY_RIGHT:
1554             {
1555                 String aTmp;
1556                 aTmp.Fill( nLen - rStr.Len() );
1557                 rStr.Insert( aTmp, 0 );
1558             }
1559             break;
1560             case SVX_HOR_JUSTIFY_CENTER:
1561             {
1562                 xub_StrLen nLen2 = (nLen - rStr.Len()) / 2;
1563                 String aTmp;
1564                 aTmp.Fill( nLen2 );
1565                 rStr.Insert( aTmp, 0 );
1566                 rStr.Expand( nLen );
1567             }
1568             break;
1569             default:
1570                 rStr.Expand( nLen );
1571         }
1572     }
1573 }
1574 
1575 
1576 void lcl_ScDocShell_WriteEmptyFixedWidthString( SvStream& rStream,
1577         const ScDocument& rDoc, SCTAB nTab, SCCOL nCol )
1578 {
1579     String aString;
1580     lcl_ScDocShell_GetFixedWidthString( aString, rDoc, nTab, nCol, sal_False,
1581             SVX_HOR_JUSTIFY_STANDARD );
1582     rStream.WriteUnicodeOrByteText( aString );
1583 }
1584 
1585 
1586 void ScDocShell::AsciiSave( SvStream& rStream, const ScImportOptions& rAsciiOpt )
1587 {
1588     sal_Unicode cDelim    = rAsciiOpt.nFieldSepCode;
1589     sal_Unicode cStrDelim = rAsciiOpt.nTextSepCode;
1590     CharSet eCharSet      = rAsciiOpt.eCharSet;
1591     sal_Bool bFixedWidth      = rAsciiOpt.bFixedWidth;
1592     sal_Bool bSaveAsShown     = rAsciiOpt.bSaveAsShown;
1593 
1594     CharSet eOldCharSet = rStream.GetStreamCharSet();
1595     rStream.SetStreamCharSet( eCharSet );
1596     sal_uInt16 nOldNumberFormatInt = rStream.GetNumberFormatInt();
1597     ByteString aStrDelimEncoded;    // only used if not Unicode
1598     UniString aStrDelimDecoded;     // only used if context encoding
1599     ByteString aDelimEncoded;
1600     UniString aDelimDecoded;
1601     sal_Bool bContextOrNotAsciiEncoding;
1602     if ( eCharSet == RTL_TEXTENCODING_UNICODE )
1603     {
1604         rStream.StartWritingUnicodeText();
1605         bContextOrNotAsciiEncoding = sal_False;
1606     }
1607     else
1608     {
1609         aStrDelimEncoded = ByteString( cStrDelim, eCharSet );
1610         aDelimEncoded = ByteString( cDelim, eCharSet );
1611         rtl_TextEncodingInfo aInfo;
1612         aInfo.StructSize = sizeof(aInfo);
1613         if ( rtl_getTextEncodingInfo( eCharSet, &aInfo ) )
1614         {
1615             bContextOrNotAsciiEncoding =
1616                 (((aInfo.Flags & RTL_TEXTENCODING_INFO_CONTEXT) != 0) ||
1617                  ((aInfo.Flags & RTL_TEXTENCODING_INFO_ASCII) == 0));
1618             if ( bContextOrNotAsciiEncoding )
1619             {
1620                 aStrDelimDecoded = String( aStrDelimEncoded, eCharSet );
1621                 aDelimDecoded = String( aDelimEncoded, eCharSet );
1622             }
1623         }
1624         else
1625             bContextOrNotAsciiEncoding = sal_False;
1626     }
1627 
1628     SCCOL nStartCol = 0;
1629     SCROW nStartRow = 0;
1630     SCTAB nTab = GetSaveTab();
1631     SCCOL nEndCol;
1632     SCROW nEndRow;
1633     aDocument.GetCellArea( nTab, nEndCol, nEndRow );
1634 
1635     ScProgress aProgress( this, ScGlobal::GetRscString( STR_SAVE_DOC ), nEndRow );
1636 
1637     String aString;
1638 
1639     ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell, SfxViewShell::Current());
1640     const ScViewOptions& rOpt = (pViewSh)
1641                                 ? pViewSh->GetViewData()->GetOptions()
1642                                 : aDocument.GetViewOptions();
1643     sal_Bool bShowFormulas = rOpt.GetOption( VOPT_FORMULAS );
1644     sal_Bool bTabProtect = aDocument.IsTabProtected( nTab );
1645 
1646     SCCOL nCol;
1647     SCROW nRow;
1648     SCCOL nNextCol = nStartCol;
1649     SCROW nNextRow = nStartRow;
1650     SCCOL nEmptyCol;
1651     SCROW nEmptyRow;
1652     SvNumberFormatter& rFormatter = *aDocument.GetFormatTable();
1653 
1654     ScHorizontalCellIterator aIter( &aDocument, nTab, nStartCol, nStartRow,
1655         nEndCol, nEndRow );
1656     ScBaseCell* pCell;
1657     while ( ( pCell = aIter.GetNext( nCol, nRow ) ) != NULL )
1658     {
1659         sal_Bool bProgress = sal_False;     // only upon line change
1660         if ( nNextRow < nRow )
1661         {   // empty rows or/and empty columns up to end of row
1662             bProgress = sal_True;
1663             for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
1664             {   // remaining columns of last row
1665                 if ( bFixedWidth )
1666                     lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1667                             aDocument, nTab, nEmptyCol );
1668                 else if ( cDelim != 0 )
1669                     rStream.WriteUniOrByteChar( cDelim );
1670             }
1671             endlub( rStream );
1672             nNextRow++;
1673             for ( nEmptyRow = nNextRow; nEmptyRow < nRow; nEmptyRow++ )
1674             {   // completely empty rows
1675                 for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
1676                 {
1677                     if ( bFixedWidth )
1678                         lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1679                                 aDocument, nTab, nEmptyCol );
1680                     else if ( cDelim != 0 )
1681                         rStream.WriteUniOrByteChar( cDelim );
1682                 }
1683                 endlub( rStream );
1684             }
1685             for ( nEmptyCol = nStartCol; nEmptyCol < nCol; nEmptyCol++ )
1686             {   // empty columns at beginning of row
1687                 if ( bFixedWidth )
1688                     lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1689                             aDocument, nTab, nEmptyCol );
1690                 else if ( cDelim != 0 )
1691                     rStream.WriteUniOrByteChar( cDelim );
1692             }
1693             nNextRow = nRow;
1694         }
1695         else if ( nNextCol < nCol )
1696         {   // empty columns in same row
1697             for ( nEmptyCol = nNextCol; nEmptyCol < nCol; nEmptyCol++ )
1698             {   // columns in between
1699                 if ( bFixedWidth )
1700                     lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1701                             aDocument, nTab, nEmptyCol );
1702                 else if ( cDelim != 0 )
1703                     rStream.WriteUniOrByteChar( cDelim );
1704             }
1705         }
1706         if ( nCol == nEndCol )
1707         {
1708             bProgress = sal_True;
1709             nNextCol = nStartCol;
1710             nNextRow = nRow + 1;
1711         }
1712         else
1713             nNextCol = nCol + 1;
1714 
1715         CellType eType = pCell->GetCellType();
1716         if ( bTabProtect )
1717         {
1718             const ScProtectionAttr* pProtAttr =
1719                 (const ScProtectionAttr*) aDocument.GetAttr(
1720                                                             nCol, nRow, nTab, ATTR_PROTECTION );
1721             if ( pProtAttr->GetHideCell() ||
1722                     ( eType == CELLTYPE_FORMULA && bShowFormulas &&
1723                       pProtAttr->GetHideFormula() ) )
1724                 eType = CELLTYPE_NONE;  // hide
1725         }
1726         sal_Bool bString;
1727         switch ( eType )
1728         {
1729             case CELLTYPE_NOTE:
1730             case CELLTYPE_NONE:
1731                 aString.Erase();
1732                 bString = sal_False;
1733                 break;
1734             case CELLTYPE_FORMULA :
1735                 {
1736                     sal_uInt16 nErrCode;
1737                     if ( bShowFormulas )
1738                     {
1739                         ((ScFormulaCell*)pCell)->GetFormula( aString );
1740                         bString = sal_True;
1741                     }
1742                     else if ( ( nErrCode = ((ScFormulaCell*)pCell)->GetErrCode() ) != 0 )
1743                     {
1744                         aString = ScGlobal::GetErrorString( nErrCode );
1745                         bString = sal_True;
1746                     }
1747                     else if ( ((ScFormulaCell*)pCell)->IsValue() )
1748                     {
1749                         sal_uInt32 nFormat;
1750                         aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1751                         if ( bFixedWidth || bSaveAsShown )
1752                         {
1753                             Color* pDummy;
1754                             ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1755                             bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
1756                         }
1757                         else
1758                         {
1759                             ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
1760                             bString = sal_False;
1761                         }
1762                     }
1763                     else
1764                     {
1765                         if ( bSaveAsShown )
1766                         {
1767                             sal_uInt32 nFormat;
1768                             aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1769                             Color* pDummy;
1770                             ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1771                         }
1772                         else
1773                             ((ScFormulaCell*)pCell)->GetString( aString );
1774                         bString = sal_True;
1775                     }
1776                 }
1777                 break;
1778             case CELLTYPE_STRING :
1779                 if ( bSaveAsShown )
1780                 {
1781                     sal_uInt32 nFormat;
1782                     aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1783                     Color* pDummy;
1784                     ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1785                 }
1786                 else
1787                     ((ScStringCell*)pCell)->GetString( aString );
1788                 bString = sal_True;
1789                 break;
1790             case CELLTYPE_EDIT :
1791                 {
1792                     const EditTextObject* pObj;
1793                     static_cast<const ScEditCell*>(pCell)->GetData( pObj);
1794                     EditEngine& rEngine = aDocument.GetEditEngine();
1795                     rEngine.SetText( *pObj);
1796                     aString = rEngine.GetText();  // including LF
1797                     bString = sal_True;
1798                 }
1799                 break;
1800             case CELLTYPE_VALUE :
1801                 {
1802                     sal_uInt32 nFormat;
1803                     aDocument.GetNumberFormat( nCol, nRow, nTab, nFormat );
1804                     if ( bFixedWidth || bSaveAsShown )
1805                     {
1806                         Color* pDummy;
1807                         ScCellFormat::GetString( pCell, nFormat, aString, &pDummy, rFormatter );
1808                         bString = bSaveAsShown && rFormatter.IsTextFormat( nFormat);
1809                     }
1810                     else
1811                     {
1812                         ScCellFormat::GetInputString( pCell, nFormat, aString, rFormatter );
1813                         bString = sal_False;
1814                     }
1815                 }
1816                 break;
1817             default:
1818                 DBG_ERROR( "ScDocShell::AsciiSave: unknown CellType" );
1819                 aString.Erase();
1820                 bString = sal_False;
1821         }
1822 
1823         if ( bFixedWidth )
1824         {
1825             SvxCellHorJustify eHorJust = (SvxCellHorJustify)
1826                 ((const SvxHorJustifyItem*) aDocument.GetAttr( nCol, nRow,
1827                 nTab, ATTR_HOR_JUSTIFY ))->GetValue();
1828             lcl_ScDocShell_GetFixedWidthString( aString, aDocument, nTab, nCol,
1829                     !bString, eHorJust );
1830             rStream.WriteUnicodeOrByteText( aString );
1831         }
1832         else
1833         {
1834             if (!bString && cStrDelim != 0 && aString.Len() > 0)
1835             {
1836                 sal_Unicode c = aString.GetChar(0);
1837                 bString = (c == cStrDelim || c == ' ' ||
1838                         aString.GetChar( aString.Len()-1) == ' ' ||
1839                         aString.Search( cStrDelim) != STRING_NOTFOUND);
1840                 if (!bString && cDelim != 0)
1841                     bString = (aString.Search( cDelim) != STRING_NOTFOUND);
1842             }
1843             if ( bString )
1844             {
1845                 if ( cStrDelim != 0 ) //@ BugId 55355
1846                 {
1847                     if ( eCharSet == RTL_TEXTENCODING_UNICODE )
1848                     {
1849                         xub_StrLen nPos = aString.Search( cStrDelim );
1850                         // #i116636# quotes are needed if text delimiter (quote), field delimiter, or LF is in the cell text
1851                         bool bNeedQuotes = rAsciiOpt.bQuoteAllText ||
1852                                             ( nPos != STRING_NOTFOUND ) ||
1853                                             ( aString.Search( cDelim ) != STRING_NOTFOUND ) ||
1854                                             ( aString.Search( sal_Unicode(_LF) ) != STRING_NOTFOUND );
1855                         while ( nPos != STRING_NOTFOUND )
1856                         {
1857                             aString.Insert( cStrDelim, nPos );
1858                             nPos = aString.Search( cStrDelim, nPos+2 );
1859                         }
1860                         if ( bNeedQuotes )
1861                             rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1862                         rStream.WriteUnicodeText( aString );
1863                         if ( bNeedQuotes )
1864                             rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1865                     }
1866                     else
1867                     {
1868                         // #105549# This is nasty. The Unicode to byte encoding
1869                         // may convert typographical quotation marks to ASCII
1870                         // quotation marks, which may interfer with the delimiter,
1871                         // so we have to escape delimiters after the string has
1872                         // been encoded. Since this may happen also with UTF-8
1873                         // encoded typographical quotation marks if such was
1874                         // specified as a delimiter we have to check for the full
1875                         // encoded delimiter string, not just one character.
1876                         // Now for RTL_TEXTENCODING_ISO_2022_... and similar brain
1877                         // dead encodings where one code point (and especially a
1878                         // low ASCII value) may represent different characters, we
1879                         // have to convert forth and back and forth again. Same for
1880                         // UTF-7 since it is a context sensitive encoding too.
1881 
1882                         if ( bContextOrNotAsciiEncoding )
1883                         {
1884                             // to byte encoding
1885                             ByteString aStrEnc( aString, eCharSet );
1886                             // back to Unicode
1887                             UniString aStrDec( aStrEnc, eCharSet );
1888                             // search on re-decoded string
1889                             xub_StrLen nPos = aStrDec.Search( aStrDelimDecoded );
1890                             bool bNeedQuotes = rAsciiOpt.bQuoteAllText ||
1891                                                 ( nPos != STRING_NOTFOUND ) ||
1892                                                 ( aStrDec.Search( aDelimDecoded ) != STRING_NOTFOUND ) ||
1893                                                 ( aStrDec.Search( sal_Unicode(_LF) ) != STRING_NOTFOUND );
1894                             while ( nPos != STRING_NOTFOUND )
1895                             {
1896                                 aStrDec.Insert( aStrDelimDecoded, nPos );
1897                                 nPos = aStrDec.Search( aStrDelimDecoded,
1898                                         nPos+1+aStrDelimDecoded.Len() );
1899                             }
1900                             // write byte re-encoded
1901                             if ( bNeedQuotes )
1902                                 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1903                             rStream.WriteUnicodeOrByteText( aStrDec, eCharSet );
1904                             if ( bNeedQuotes )
1905                                 rStream.WriteUniOrByteChar( cStrDelim, eCharSet );
1906                         }
1907                         else
1908                         {
1909                             ByteString aStrEnc( aString, eCharSet );
1910                             // search on encoded string
1911                             xub_StrLen nPos = aStrEnc.Search( aStrDelimEncoded );
1912                             bool bNeedQuotes = rAsciiOpt.bQuoteAllText ||
1913                                                 ( nPos != STRING_NOTFOUND ) ||
1914                                                 ( aStrEnc.Search( aDelimEncoded ) != STRING_NOTFOUND ) ||
1915                                                 ( aStrEnc.Search( sal_Char(_LF) ) != STRING_NOTFOUND );
1916                             while ( nPos != STRING_NOTFOUND )
1917                             {
1918                                 aStrEnc.Insert( aStrDelimEncoded, nPos );
1919                                 nPos = aStrEnc.Search( aStrDelimEncoded,
1920                                         nPos+1+aStrDelimEncoded.Len() );
1921                             }
1922                             // write byte encoded
1923                             if ( bNeedQuotes )
1924                                 rStream.Write( aStrDelimEncoded.GetBuffer(),
1925                                         aStrDelimEncoded.Len() );
1926                             rStream.Write( aStrEnc.GetBuffer(), aStrEnc.Len() );
1927                             if ( bNeedQuotes )
1928                                 rStream.Write( aStrDelimEncoded.GetBuffer(),
1929                                         aStrDelimEncoded.Len() );
1930                         }
1931                     }
1932                 }
1933                 else
1934                     rStream.WriteUnicodeOrByteText( aString );
1935             }
1936             else
1937                 rStream.WriteUnicodeOrByteText( aString );
1938         }
1939 
1940         if( nCol < nEndCol )
1941         {
1942             if(cDelim!=0) //@ BugId 55355
1943                 rStream.WriteUniOrByteChar( cDelim );
1944         }
1945         else
1946             endlub( rStream );
1947 
1948         if ( bProgress )
1949             aProgress.SetStateOnPercent( nRow );
1950     }
1951 
1952     // write out empty if requested
1953     if ( nNextRow <= nEndRow )
1954     {
1955         for ( nEmptyCol = nNextCol; nEmptyCol < nEndCol; nEmptyCol++ )
1956         {   // remaining empty columns of last row
1957             if ( bFixedWidth )
1958                 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1959                         aDocument, nTab, nEmptyCol );
1960             else if ( cDelim != 0 )
1961                 rStream.WriteUniOrByteChar( cDelim );
1962         }
1963         endlub( rStream );
1964         nNextRow++;
1965     }
1966     for ( nEmptyRow = nNextRow; nEmptyRow <= nEndRow; nEmptyRow++ )
1967     {   // entire empty rows
1968         for ( nEmptyCol = nStartCol; nEmptyCol < nEndCol; nEmptyCol++ )
1969         {
1970             if ( bFixedWidth )
1971                 lcl_ScDocShell_WriteEmptyFixedWidthString( rStream,
1972                         aDocument, nTab, nEmptyCol );
1973             else if ( cDelim != 0 )
1974                 rStream.WriteUniOrByteChar( cDelim );
1975         }
1976         endlub( rStream );
1977     }
1978 
1979     rStream.SetStreamCharSet( eOldCharSet );
1980     rStream.SetNumberFormatInt( nOldNumberFormatInt );
1981 }
1982 
1983 sal_Bool __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed )
1984 {
1985     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertTo" );
1986 
1987     ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );
1988 
1989     //  #i6500# don't call DoEnterHandler here (doesn't work with AutoSave),
1990     //  it's already in ExecuteSave (as for Save and SaveAs)
1991 
1992     if (pAutoStyleList)
1993         pAutoStyleList->ExecuteAllNow();                // Vorlagen-Timeouts jetzt ausfuehren
1994     if (GetCreateMode()== SFX_CREATE_MODE_STANDARD)
1995         SfxObjectShell::SetVisArea( Rectangle() );     // normal bearbeitet -> keine VisArea
1996 
1997     DBG_ASSERT( rMed.GetFilter(), "Filter == 0" );
1998 
1999     sal_Bool bRet = sal_False;
2000     String aFltName = rMed.GetFilter()->GetFilterName();
2001 
2002 /*
2003     if (aFltName.EqualsAscii(pFilterLotus))
2004     {
2005         SvStream* pStream = rMed.GetOutStream();
2006         if (pStream)
2007         {
2008             FltError eError = ScFormatFilter::Get().ScExportLotus123( *pStream, &aDocument, ExpWK1,
2009                                                 CHARSET_IBMPC_437 );
2010             bRet = eError == eERR_OK;
2011         }
2012     }
2013     else
2014 */
2015     if (aFltName.EqualsAscii(pFilterXML))
2016     {
2017         //TODO/LATER: this shouldn't happen!
2018         DBG_ERROR("XML filter in ConvertFrom?!");
2019         bRet = SaveXML( &rMed, NULL );
2020     }
2021     else if (aFltName.EqualsAscii(pFilterExcel5) || aFltName.EqualsAscii(pFilterExcel95) ||
2022              aFltName.EqualsAscii(pFilterExcel97) || aFltName.EqualsAscii(pFilterEx5Temp) ||
2023              aFltName.EqualsAscii(pFilterEx95Temp) || aFltName.EqualsAscii(pFilterEx97Temp) ||
2024              aFltName.EqualsAscii(pFilterEx07Xml))
2025     {
2026         WaitObject aWait( GetActiveDialogParent() );
2027 
2028         bool bDoSave = true;
2029         if( ScTabViewShell* pViewShell = GetBestViewShell() )
2030         {
2031             ScExtDocOptions* pExtDocOpt = aDocument.GetExtDocOptions();
2032             if( !pExtDocOpt )
2033                 aDocument.SetExtDocOptions( pExtDocOpt = new ScExtDocOptions );
2034             pViewShell->GetViewData()->WriteExtOptions( *pExtDocOpt );
2035 
2036             /*  #115980# #i104990# If the imported document contains a medium
2037                 password, determine if we can save it, otherwise ask the users
2038                 whether they want to save without it. */
2039             if( (rMed.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION) == 0 )
2040             {
2041                 SfxItemSet* pItemSet = rMed.GetItemSet();
2042                 const SfxPoolItem* pItem = 0;
2043                 if( pItemSet && pItemSet->GetItemState( SID_PASSWORD, sal_True, &pItem ) == SFX_ITEM_SET )
2044                 {
2045                     bDoSave = ScWarnPassword::WarningOnPassword( rMed );
2046                     // #i42858# remove password from medium (warn only one time)
2047                     if( bDoSave )
2048                         pItemSet->ClearItem( SID_PASSWORD );
2049                 }
2050             }
2051 
2052 #if ENABLE_SHEET_PROTECTION
2053             if( bDoSave )
2054             {
2055                 bool bNeedRetypePassDlg = ScPassHashHelper::needsPassHashRegen( aDocument, PASSHASH_XL );
2056                 bDoSave = !bNeedRetypePassDlg || pViewShell->ExecuteRetypePassDlg( PASSHASH_XL );
2057             }
2058 #endif
2059         }
2060 
2061         if( bDoSave )
2062         {
2063             ExportFormatExcel eFormat = ExpBiff5;
2064             if( aFltName.EqualsAscii( pFilterExcel97 ) || aFltName.EqualsAscii( pFilterEx97Temp ) )
2065                 eFormat = ExpBiff8;
2066             if( aFltName.EqualsAscii( pFilterEx07Xml ) )
2067                 eFormat = Exp2007Xml;
2068             FltError eError = ScFormatFilter::Get().ScExportExcel5( rMed, &aDocument, eFormat, RTL_TEXTENCODING_MS_1252 );
2069 
2070             if( eError && !GetError() )
2071                 SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2072 
2073             // don't return false for warnings
2074             bRet = ((eError & ERRCODE_WARNING_MASK) == ERRCODE_WARNING_MASK) || (eError == eERR_OK);
2075         }
2076         else
2077         {
2078             // export aborted, i.e. "Save without password" warning
2079             SetError( ERRCODE_ABORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2080         }
2081     }
2082     else if (aFltName.EqualsAscii(pFilterAscii))
2083     {
2084         SvStream* pStream = rMed.GetOutStream();
2085         if (pStream)
2086         {
2087             String sItStr;
2088             SfxItemSet*  pSet = rMed.GetItemSet();
2089             const SfxPoolItem* pItem;
2090             if ( pSet && SFX_ITEM_SET ==
2091                  pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
2092             {
2093                 sItStr = ((const SfxStringItem*)pItem)->GetValue();
2094             }
2095 
2096             if ( sItStr.Len() == 0 )
2097             {
2098                 //  default for ascii export (from API without options):
2099                 //  ISO8859-1/MS_1252 encoding, comma, double quotes
2100 
2101                 ScImportOptions aDefOptions( ',', '"', RTL_TEXTENCODING_MS_1252 );
2102                 sItStr = aDefOptions.BuildString();
2103             }
2104 
2105             WaitObject aWait( GetActiveDialogParent() );
2106             ScImportOptions aOptions( sItStr );
2107             AsciiSave( *pStream, aOptions );
2108             bRet = sal_True;
2109 
2110             if (aDocument.GetTableCount() > 1)
2111                 if (!rMed.GetError())
2112                     rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
2113         }
2114     }
2115     else if (aFltName.EqualsAscii(pFilterDBase))
2116     {
2117         String sCharSet;
2118         SfxItemSet* pSet = rMed.GetItemSet();
2119         const SfxPoolItem* pItem;
2120         if ( pSet && SFX_ITEM_SET ==
2121              pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
2122         {
2123             sCharSet = ((const SfxStringItem*)pItem)->GetValue();
2124         }
2125 
2126         if (sCharSet.Len() == 0)
2127         {
2128             //  default for dBase export (from API without options):
2129             //  IBM_850 encoding
2130 
2131             sCharSet = ScGlobal::GetCharsetString( RTL_TEXTENCODING_IBM_850 );
2132         }
2133 
2134         WaitObject aWait( GetActiveDialogParent() );
2135 // HACK damit Sba geoffnetes TempFile ueberschreiben kann
2136         rMed.CloseOutStream();
2137         sal_Bool bHasMemo = sal_False;
2138 
2139         sal_uLong eError = DBaseExport( rMed.GetPhysicalName(),
2140                         ScGlobal::GetCharsetValue(sCharSet), bHasMemo );
2141 
2142         if ( eError != eERR_OK && (eError & ERRCODE_WARNING_MASK) )
2143         {
2144 //!         if ( !rMed.GetError() )
2145 //!             rMed.SetError( eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2146             eError = eERR_OK;
2147         }
2148 //!     else if ( aDocument.GetTableCount() > 1 && !rMed.GetError() )
2149 //!         rMed.SetError( SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2150 
2151         INetURLObject aTmpFile( rMed.GetPhysicalName(), INET_PROT_FILE );
2152         if ( bHasMemo )
2153             aTmpFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
2154         if ( eError != eERR_OK )
2155         {
2156             if (!GetError())
2157                 SetError(eError, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
2158             if ( bHasMemo && IsDocument( aTmpFile ) )
2159                 KillFile( aTmpFile );
2160         }
2161         else
2162         {
2163             bRet = sal_True;
2164             if ( bHasMemo )
2165             {
2166                 SfxStringItem* pNameItem =
2167                     (SfxStringItem*) rMed.GetItemSet()->GetItem( SID_FILE_NAME );
2168                 INetURLObject aDbtFile( pNameItem->GetValue(), INET_PROT_FILE );
2169                 aDbtFile.setExtension( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("dbt")) );
2170                 if ( IsDocument( aDbtFile ) && !KillFile( aDbtFile ) )
2171                     bRet = sal_False;
2172                 if ( bRet && !MoveFile( aTmpFile, aDbtFile ) )
2173                     bRet = sal_False;
2174                 if ( !bRet )
2175                 {
2176                     KillFile( aTmpFile );
2177                     if ( !GetError() )
2178                         SetError( SCERR_EXPORT_DATA, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2179                 }
2180             }
2181         }
2182     }
2183     else if (aFltName.EqualsAscii(pFilterDif))
2184     {
2185         SvStream* pStream = rMed.GetOutStream();
2186         if (pStream)
2187         {
2188             String sItStr;
2189             SfxItemSet*  pSet = rMed.GetItemSet();
2190             const SfxPoolItem* pItem;
2191             if ( pSet && SFX_ITEM_SET ==
2192                  pSet->GetItemState( SID_FILE_FILTEROPTIONS, sal_True, &pItem ) )
2193             {
2194                 sItStr = ((const SfxStringItem*)pItem)->GetValue();
2195             }
2196 
2197             if (sItStr.Len() == 0)
2198             {
2199                 //  default for DIF export (from API without options):
2200                 //  ISO8859-1/MS_1252 encoding
2201 
2202                 sItStr = ScGlobal::GetCharsetString( RTL_TEXTENCODING_MS_1252 );
2203             }
2204 
2205             WaitObject aWait( GetActiveDialogParent() );
2206             ScFormatFilter::Get().ScExportDif( *pStream, &aDocument, ScAddress(0,0,0),
2207                 ScGlobal::GetCharsetValue(sItStr) );
2208             bRet = sal_True;
2209 
2210             if (aDocument.GetTableCount() > 1)
2211                 if (!rMed.GetError())
2212                     rMed.SetError(SCWARN_EXPORT_ASCII, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ));
2213         }
2214     }
2215     else if (aFltName.EqualsAscii(pFilterSylk))
2216     {
2217         SvStream* pStream = rMed.GetOutStream();
2218         if ( pStream )
2219         {
2220             WaitObject aWait( GetActiveDialogParent() );
2221 
2222             SCCOL nEndCol;
2223             SCROW nEndRow;
2224             aDocument.GetCellArea( 0, nEndCol, nEndRow );
2225             ScRange aRange( 0,0,0, nEndCol,nEndRow,0 );
2226 
2227             ScImportExport aImExport( &aDocument, aRange );
2228             aImExport.SetFormulas( sal_True );
2229             bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_SYLK );
2230         }
2231     }
2232     else if (aFltName.EqualsAscii(pFilterHtml))
2233     {
2234         SvStream* pStream = rMed.GetOutStream();
2235         if ( pStream )
2236         {
2237             WaitObject aWait( GetActiveDialogParent() );
2238             ScImportExport aImExport( &aDocument );
2239             aImExport.SetStreamPath( rMed.GetName() );
2240             bRet = aImExport.ExportStream( *pStream, rMed.GetBaseURL( true ), SOT_FORMATSTR_ID_HTML );
2241             if ( bRet && aImExport.GetNonConvertibleChars().Len() )
2242                 SetError( *new StringErrorInfo(
2243                     SCWARN_EXPORT_NONCONVERTIBLE_CHARS,
2244                     aImExport.GetNonConvertibleChars(),
2245                     ERRCODE_BUTTON_OK | ERRCODE_MSG_INFO ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2246         }
2247     }
2248     else
2249     {
2250         if (GetError())
2251             SetError(SCERR_IMPORT_NI, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( OSL_LOG_PREFIX ) ) );
2252     }
2253     return bRet;
2254 }
2255 
2256 
2257 sal_Bool __EXPORT ScDocShell::SaveCompleted( const uno::Reference < embed::XStorage >& xStor )
2258 {
2259     return SfxObjectShell::SaveCompleted( xStor );
2260 }
2261 
2262 
2263 sal_Bool __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor )
2264 {
2265     sal_Bool bRet = SfxObjectShell::DoSaveCompleted( pNewStor );
2266 
2267     //  SC_HINT_DOC_SAVED fuer Wechsel ReadOnly -> Read/Write
2268     Broadcast( SfxSimpleHint( SC_HINT_DOC_SAVED ) );
2269     return bRet;
2270 }
2271 
2272 
2273 sal_Bool ScDocShell::QuerySlotExecutable( sal_uInt16 nSlotId )
2274 {
2275     // #i112634# ask VBA event handlers whether to save or print the document
2276 
2277     using namespace ::com::sun::star::script::vba;
2278 
2279     sal_Int32 nVbaEventId = VBAEventId::NO_EVENT;
2280     uno::Sequence< uno::Any > aArgs;
2281     switch( nSlotId )
2282     {
2283         case SID_SAVEDOC:
2284         case SID_SAVEASDOC:
2285             nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE;
2286             aArgs.realloc( 1 );
2287             aArgs[ 0 ] <<= (nSlotId == SID_SAVEASDOC);
2288         break;
2289         case SID_PRINTDOC:
2290         case SID_PRINTDOCDIRECT:
2291             nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT;
2292         break;
2293     }
2294 
2295     sal_Bool bSlotExecutable = sal_True;
2296     if( nVbaEventId != VBAEventId::NO_EVENT ) try
2297     {
2298         uno::Reference< XVBAEventProcessor > xEventProcessor( aDocument.GetVbaEventProcessor(), uno::UNO_QUERY_THROW );
2299         xEventProcessor->processVbaEvent( nVbaEventId, aArgs );
2300     }
2301     catch( util::VetoException& )
2302     {
2303         bSlotExecutable = sal_False;
2304     }
2305     catch( uno::Exception& )
2306     {
2307     }
2308     return bSlotExecutable;
2309 }
2310 
2311 
2312 sal_uInt16 __EXPORT ScDocShell::PrepareClose( sal_Bool bUI, sal_Bool bForBrowsing )
2313 {
2314     if(SC_MOD()->GetCurRefDlgId()>0)
2315     {
2316         SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this );
2317         if( pFrame )
2318         {
2319             SfxViewShell* p = pFrame->GetViewShell();
2320             ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p);
2321             if(pViewSh!=NULL)
2322             {
2323                 Window *pWin=pViewSh->GetWindow();
2324                 if(pWin!=NULL) pWin->GrabFocus();
2325             }
2326         }
2327 
2328         return sal_False;
2329     }
2330     if ( aDocument.IsInLinkUpdate() || aDocument.IsInInterpreter() )
2331     {
2332         ErrorMessage(STR_CLOSE_ERROR_LINK);
2333         return sal_False;
2334     }
2335 
2336     DoEnterHandler();
2337 
2338     // start 'Workbook_BeforeClose' VBA event handler for possible veto
2339     if( !IsInPrepareClose() )
2340     {
2341         try
2342         {
2343             uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( aDocument.GetVbaEventProcessor(), uno::UNO_SET_THROW );
2344             uno::Sequence< uno::Any > aArgs;
2345             xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs );
2346         }
2347         catch( util::VetoException& )
2348         {
2349             // if event processor throws VetoException, macro has vetoed close
2350             return sal_False;
2351         }
2352         catch( uno::Exception& )
2353         {
2354         }
2355     }
2356     // end handler code
2357 
2358     sal_uInt16 nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing );
2359     if (nRet == sal_True)                       // sal_True = schliessen
2360         aDocument.DisableIdle(sal_True);        // nicht mehr drin rumpfuschen !!!
2361 
2362     return nRet;
2363 }
2364 
2365 void ScDocShell::PrepareReload()
2366 {
2367     SfxObjectShell::PrepareReload();    // tut nichts?
2368 
2369     //  Das Disconnect von DDE-Links kann Reschedule ausloesen.
2370     //  Wenn die DDE-Links erst im Dokument-dtor geloescht werden, kann beim Reload
2371     //  aus diesem Reschedule das DDE-Link-Update fuer das neue Dokument ausgeloest
2372     //  werden. Dabei verklemmt sicht dann irgendwas.
2373     //  -> Beim Reload die DDE-Links des alten Dokuments vorher disconnecten
2374 
2375     aDocument.DisconnectDdeLinks();
2376 }
2377 
2378 
2379 String ScDocShell::GetOwnFilterName()           // static
2380 {
2381     return String::CreateFromAscii(pFilterSc50);
2382 }
2383 
2384 String ScDocShell::GetHtmlFilterName()
2385 {
2386     return String::CreateFromAscii(pFilterHtml);
2387 }
2388 
2389 String ScDocShell::GetWebQueryFilterName()      // static
2390 {
2391     return String::CreateFromAscii(pFilterHtmlWebQ);
2392 }
2393 
2394 String ScDocShell::GetAsciiFilterName()         // static
2395 {
2396     return String::CreateFromAscii(pFilterAscii);
2397 }
2398 
2399 String ScDocShell::GetLotusFilterName()         // static
2400 {
2401     return String::CreateFromAscii(pFilterLotus);
2402 }
2403 
2404 String ScDocShell::GetDBaseFilterName()         // static
2405 {
2406     return String::CreateFromAscii(pFilterDBase);
2407 }
2408 
2409 String ScDocShell::GetDifFilterName()           // static
2410 {
2411     return String::CreateFromAscii(pFilterDif);
2412 }
2413 
2414 sal_Bool ScDocShell::HasAutomaticTableName( const String& rFilter )     // static
2415 {
2416     //  sal_True for those filters that keep the default table name
2417     //  (which is language specific)
2418 
2419     return rFilter.EqualsAscii( pFilterAscii )
2420         || rFilter.EqualsAscii( pFilterLotus )
2421         || rFilter.EqualsAscii( pFilterExcel4 )
2422         || rFilter.EqualsAscii( pFilterEx4Temp )
2423         || rFilter.EqualsAscii( pFilterDBase )
2424         || rFilter.EqualsAscii( pFilterDif )
2425         || rFilter.EqualsAscii( pFilterSylk )
2426         || rFilter.EqualsAscii( pFilterHtml )
2427         || rFilter.EqualsAscii( pFilterRtf );
2428 }
2429 
2430 //==================================================================
2431 
2432 #define __SCDOCSHELL_INIT \
2433         aDocument       ( SCDOCMODE_DOCUMENT, this ), \
2434         aDdeTextFmt(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("TEXT"))), \
2435         nPrtToScreenFactor( 1.0 ), \
2436         pImpl           ( new DocShell_Impl ), \
2437         bHeaderOn       ( sal_True ), \
2438         bFooterOn       ( sal_True ), \
2439         bNoInformLost   ( sal_True ), \
2440         bIsEmpty        ( sal_True ), \
2441         bIsInUndo       ( sal_False ), \
2442         bDocumentModifiedPending( sal_False ), \
2443         nDocumentLock   ( 0 ), \
2444         nCanUpdate (com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG), \
2445         bUpdateEnabled  ( sal_True ), \
2446         pOldAutoDBRange ( NULL ), \
2447         pDocHelper      ( NULL ), \
2448         pAutoStyleList  ( NULL ), \
2449         pPaintLockData  ( NULL ), \
2450         pOldJobSetup    ( NULL ), \
2451         pSolverSaveData ( NULL ), \
2452         pSheetSaveData  ( NULL ), \
2453         pModificator    ( NULL )
2454 
2455 //------------------------------------------------------------------
2456 
2457 ScDocShell::ScDocShell( const ScDocShell& rShell )
2458     :   SvRefBase(),
2459         SotObject(),
2460         SfxObjectShell( rShell.GetCreateMode() ),
2461         SfxListener(),
2462         __SCDOCSHELL_INIT
2463 {
2464     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );
2465 
2466     SetPool( &SC_MOD()->GetPool() );
2467 
2468     bIsInplace = rShell.bIsInplace;
2469 
2470     pDocFunc = new ScDocFunc(*this);
2471 
2472     //  SetBaseModel needs exception handling
2473     ScModelObj::CreateAndSet( this );
2474 
2475     StartListening(*this);
2476     SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
2477     if (pStlPool)
2478         StartListening(*pStlPool);
2479 
2480     GetPageOnFromPageStyleSet( NULL, 0, bHeaderOn, bFooterOn );
2481     SetHelpId( HID_SCSHELL_DOCSH );
2482 
2483     //  InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
2484 }
2485 
2486 //------------------------------------------------------------------
2487 
2488 ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags )
2489     :   SfxObjectShell( i_nSfxCreationFlags )
2490     ,   __SCDOCSHELL_INIT
2491 {
2492     RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" );
2493 
2494     SetPool( &SC_MOD()->GetPool() );
2495 
2496     bIsInplace = (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED);
2497     //  wird zurueckgesetzt, wenn nicht inplace
2498 
2499     pDocFunc = new ScDocFunc(*this);
2500 
2501     //  SetBaseModel needs exception handling
2502     ScModelObj::CreateAndSet( this );
2503 
2504     StartListening(*this);
2505     SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
2506     if (pStlPool)
2507         StartListening(*pStlPool);
2508     SetHelpId( HID_SCSHELL_DOCSH );
2509 
2510     aDocument.GetDBCollection()->SetRefreshHandler(
2511         LINK( this, ScDocShell, RefreshDBDataHdl ) );
2512 
2513     //  InitItems und CalcOutputFactor werden jetzt nach bei Load/ConvertFrom/InitNew gerufen
2514 }
2515 
2516 //------------------------------------------------------------------
2517 
2518 __EXPORT ScDocShell::~ScDocShell()
2519 {
2520     ResetDrawObjectShell(); // #55570# falls der Drawing-Layer noch versucht, darauf zuzugreifen
2521 
2522     SfxStyleSheetPool* pStlPool = aDocument.GetStyleSheetPool();
2523     if (pStlPool)
2524         EndListening(*pStlPool);
2525     EndListening(*this);
2526 
2527     delete pAutoStyleList;
2528 
2529     SfxApplication *pSfxApp = SFX_APP();
2530     if ( pSfxApp->GetDdeService() )             // DDE vor Dokument loeschen
2531         pSfxApp->RemoveDdeTopic( this );
2532 
2533     delete pDocFunc;
2534     delete aDocument.mpUndoManager;
2535     aDocument.mpUndoManager = 0;
2536     delete pImpl;
2537 
2538     delete pPaintLockData;
2539 
2540     delete pOldJobSetup;        // gesetzt nur bei Fehler in StartJob()
2541 
2542     delete pSolverSaveData;
2543     delete pSheetSaveData;
2544     delete pOldAutoDBRange;
2545 
2546     if (pModificator)
2547     {
2548         DBG_ERROR("The Modificator should not exist");
2549         delete pModificator;
2550     }
2551 }
2552 
2553 //------------------------------------------------------------------
2554 
2555 ::svl::IUndoManager* __EXPORT ScDocShell::GetUndoManager()
2556 {
2557     return aDocument.GetUndoManager();
2558 }
2559 
2560 void ScDocShell::SetModified( sal_Bool bModified )
2561 {
2562     if ( SfxObjectShell::IsEnableSetModified() )
2563     {
2564         SfxObjectShell::SetModified( bModified );
2565         Broadcast( SfxSimpleHint( SFX_HINT_DOCCHANGED ) );
2566     }
2567 }
2568 
2569 
2570 void ScDocShell::SetDocumentModified( sal_Bool bIsModified /* = sal_True */ )
2571 {
2572     //  BroadcastUno muss auch mit pPaintLockData sofort passieren
2573     //! auch bei SetDrawModified, wenn Drawing angebunden ist
2574     //! dann eigener Hint???
2575 
2576     if ( pPaintLockData && bIsModified )
2577     {
2578         // #i115009# broadcast BCA_BRDCST_ALWAYS, so a component can read recalculated results
2579         // of RecalcModeAlways formulas (like OFFSET) after modifying cells
2580         aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
2581         aDocument.InvalidateTableArea();    // #i105279# needed here
2582         aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
2583 
2584         pPaintLockData->SetModified();          // spaeter...
2585         return;
2586     }
2587 
2588     SetDrawModified( bIsModified );
2589 
2590     if ( bIsModified )
2591     {
2592         if ( aDocument.IsAutoCalcShellDisabled() )
2593             SetDocumentModifiedPending( sal_True );
2594         else
2595         {
2596             SetDocumentModifiedPending( sal_False );
2597             aDocument.InvalidateStyleSheetUsage();
2598             aDocument.InvalidateTableArea();
2599             aDocument.InvalidateLastTableOpParams();
2600             aDocument.Broadcast( SC_HINT_DATACHANGED, BCA_BRDCST_ALWAYS, NULL );
2601             if ( aDocument.IsForcedFormulaPending() && aDocument.GetAutoCalc() )
2602                 aDocument.CalcFormulaTree( sal_True );
2603             PostDataChanged();
2604 
2605             //  Detective AutoUpdate:
2606             //  Update if formulas were modified (DetectiveDirty) or the list contains
2607             //  "Trace Error" entries (#75362# - Trace Error can look completely different
2608             //  after changes to non-formula cells).
2609 
2610             ScDetOpList* pList = aDocument.GetDetOpList();
2611             if ( pList && ( aDocument.IsDetectiveDirty() || pList->HasAddError() ) &&
2612                  pList->Count() && !IsInUndo() && SC_MOD()->GetAppOptions().GetDetectiveAuto() )
2613             {
2614                 GetDocFunc().DetectiveRefresh(sal_True);    // sal_True = caused by automatic update
2615             }
2616             aDocument.SetDetectiveDirty(sal_False);         // always reset, also if not refreshed
2617         }
2618 
2619         // #b6697848# notify UNO objects after BCA_BRDCST_ALWAYS etc.
2620         aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
2621     }
2622 }
2623 
2624 //  SetDrawModified - ohne Formel-Update
2625 //  (Drawing muss auch beim normalen SetDocumentModified upgedated werden,
2626 //   z.B. bei Tabelle loeschen etc.)
2627 
2628 void ScDocShell::SetDrawModified( sal_Bool bIsModified /* = sal_True */ )
2629 {
2630     sal_Bool bUpdate = ( bIsModified != IsModified() );
2631 
2632     SetModified( bIsModified );
2633 
2634     SfxBindings* pBindings = GetViewBindings();
2635     if (bUpdate)
2636     {
2637         if (pBindings)
2638         {
2639             pBindings->Invalidate( SID_SAVEDOC );
2640             pBindings->Invalidate( SID_DOC_MODIFIED );
2641         }
2642     }
2643 
2644     if (bIsModified)
2645     {
2646         if (pBindings)
2647         {
2648             // #i105960# Undo etc used to be volatile.
2649             // They always have to be invalidated, including drawing layer or row height changes
2650             // (but not while pPaintLockData is set).
2651             pBindings->Invalidate( SID_UNDO );
2652             pBindings->Invalidate( SID_REDO );
2653             pBindings->Invalidate( SID_REPEAT );
2654         }
2655 
2656         if ( aDocument.IsChartListenerCollectionNeedsUpdate() )
2657         {
2658             aDocument.UpdateChartListenerCollection();
2659             SFX_APP()->Broadcast(SfxSimpleHint( SC_HINT_DRAW_CHANGED ));    // Navigator
2660         }
2661         SC_MOD()->AnythingChanged();
2662     }
2663 }
2664 
2665 void ScDocShell::SetInUndo(sal_Bool bSet)
2666 {
2667     bIsInUndo = bSet;
2668 }
2669 
2670 
2671 void ScDocShell::GetDocStat( ScDocStat& rDocStat )
2672 {
2673     SfxPrinter* pPrinter = GetPrinter();
2674 
2675     aDocument.GetDocStat( rDocStat );
2676     rDocStat.nPageCount = 0;
2677 
2678     if ( pPrinter )
2679         for ( SCTAB i=0; i<rDocStat.nTableCount; i++ )
2680             rDocStat.nPageCount = sal::static_int_cast<sal_uInt16>( rDocStat.nPageCount +
2681                 (sal_uInt16) ScPrintFunc( this, pPrinter, i ).GetTotalPages() );
2682 }
2683 
2684 
2685 SfxDocumentInfoDialog* __EXPORT ScDocShell::CreateDocumentInfoDialog(
2686                                          Window *pParent, const SfxItemSet &rSet )
2687 {
2688     SfxDocumentInfoDialog* pDlg   = new SfxDocumentInfoDialog( pParent, rSet );
2689     ScDocShell*            pDocSh = PTR_CAST(ScDocShell,SfxObjectShell::Current());
2690 
2691     //nur mit Statistik, wenn dieses Doc auch angezeigt wird, nicht
2692     //aus dem Doc-Manager
2693 
2694     if( pDocSh == this )
2695     {
2696         ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
2697         DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
2698         ::CreateTabPage ScDocStatPageCreate =   pFact->GetTabPageCreatorFunc( RID_SCPAGE_STAT );
2699         DBG_ASSERT(ScDocStatPageCreate, "Tabpage create fail!");//CHINA001
2700         pDlg->AddTabPage( 42,
2701             ScGlobal::GetRscString( STR_DOC_STAT ),
2702             ScDocStatPageCreate,
2703             NULL);
2704 //CHINA001      pDlg->AddTabPage( 42,
2705 //CHINA001      ScGlobal::GetRscString( STR_DOC_STAT ),
2706 //CHINA001      ScDocStatPage::Create,
2707 //CHINA001      NULL );
2708     }
2709     return pDlg;
2710 }
2711 
2712 Window* ScDocShell::GetActiveDialogParent()
2713 {
2714     ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2715     if ( pViewSh )
2716         return pViewSh->GetDialogParent();
2717     else
2718         return Application::GetDefDialogParent();
2719 }
2720 
2721 void ScDocShell::SetSolverSaveData( const ScOptSolverSave& rData )
2722 {
2723     delete pSolverSaveData;
2724     pSolverSaveData = new ScOptSolverSave( rData );
2725 }
2726 
2727 ScSheetSaveData* ScDocShell::GetSheetSaveData()
2728 {
2729     if (!pSheetSaveData)
2730         pSheetSaveData = new ScSheetSaveData;
2731 
2732     return pSheetSaveData;
2733 }
2734 
2735 void ScDocShell::UseSheetSaveEntries()
2736 {
2737     if (pSheetSaveData)
2738     {
2739         pSheetSaveData->UseSaveEntries();   // use positions from saved file for next saving
2740 
2741         bool bHasEntries = false;
2742         SCTAB nTabCount = aDocument.GetTableCount();
2743         SCTAB nTab;
2744         for (nTab = 0; nTab < nTabCount; ++nTab)
2745             if (pSheetSaveData->HasStreamPos(nTab))
2746                 bHasEntries = true;
2747 
2748         if (!bHasEntries)
2749         {
2750             // if no positions were set (for example, export to other format),
2751             // reset all "valid" flags
2752 
2753             for (nTab = 0; nTab < nTabCount; ++nTab)
2754                 if (aDocument.IsStreamValid(nTab))
2755                     aDocument.SetStreamValid(nTab, sal_False);
2756         }
2757     }
2758 }
2759 
2760 // --- ScDocShellModificator ------------------------------------------
2761 
2762 ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS )
2763         :
2764         rDocShell( rDS ),
2765         aProtector( rDS.GetDocument()->GetRefreshTimerControlAddress() )
2766 {
2767     ScDocument* pDoc = rDocShell.GetDocument();
2768     bAutoCalcShellDisabled = pDoc->IsAutoCalcShellDisabled();
2769     bIdleDisabled = pDoc->IsIdleDisabled();
2770     pDoc->SetAutoCalcShellDisabled( sal_True );
2771     pDoc->DisableIdle( sal_True );
2772 }
2773 
2774 
2775 ScDocShellModificator::~ScDocShellModificator()
2776 {
2777     ScDocument* pDoc = rDocShell.GetDocument();
2778     pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
2779     if ( !bAutoCalcShellDisabled && rDocShell.IsDocumentModifiedPending() )
2780         rDocShell.SetDocumentModified();    // last one shuts off the lights
2781     pDoc->DisableIdle( bIdleDisabled );
2782 }
2783 
2784 
2785 void ScDocShellModificator::SetDocumentModified()
2786 {
2787     ScDocument* pDoc = rDocShell.GetDocument();
2788     if ( !pDoc->IsImportingXML() )
2789     {
2790         // AutoCalcShellDisabled temporaer restaurieren
2791         sal_Bool bDisabled = pDoc->IsAutoCalcShellDisabled();
2792         pDoc->SetAutoCalcShellDisabled( bAutoCalcShellDisabled );
2793         rDocShell.SetDocumentModified();
2794         pDoc->SetAutoCalcShellDisabled( bDisabled );
2795     }
2796     else
2797     {
2798         // uno broadcast is necessary for api to work
2799         // -> must also be done during xml import
2800         pDoc->BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
2801     }
2802 }
2803 
2804 //<!--Added by PengYunQuan for Validity Cell Range Picker
2805 sal_Bool ScDocShell::AcceptStateUpdate() const
2806 {
2807     if( SfxObjectShell::AcceptStateUpdate() )
2808         return sal_True;
2809 
2810     if( SC_MOD()->Find1RefWindow( SFX_APP()->GetTopWindow() ) )
2811         return sal_True;
2812 
2813     return sal_False;
2814 }
2815 //-->Added by PengYunQuan for Validity Cell Range Picker
2816 
2817 
2818 bool ScDocShell::IsChangeRecording() const
2819 {
2820     ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
2821     return pChangeTrack != NULL;
2822 }
2823 
2824 
2825 bool ScDocShell::HasChangeRecordProtection() const
2826 {
2827     bool bRes = false;
2828     ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
2829     if (pChangeTrack)
2830         bRes = pChangeTrack->IsProtected();
2831     return bRes;
2832 }
2833 
2834 
2835 void ScDocShell::SetChangeRecording( bool bActivate )
2836 {
2837     bool bOldChangeRecording = IsChangeRecording();
2838 
2839     if (bActivate)
2840     {
2841         aDocument.StartChangeTracking();
2842         ScChangeViewSettings aChangeViewSet;
2843         aChangeViewSet.SetShowChanges(sal_True);
2844         aDocument.SetChangeViewSettings(aChangeViewSet);
2845     }
2846     else
2847     {
2848         aDocument.EndChangeTracking();
2849         PostPaintGridAll();
2850     }
2851 
2852     if (bOldChangeRecording != IsChangeRecording())
2853     {
2854         UpdateAcceptChangesDialog();
2855         // Slots invalidieren
2856         SfxBindings* pBindings = GetViewBindings();
2857         if (pBindings)
2858             pBindings->InvalidateAll(sal_False);
2859     }
2860 }
2861 
2862 
2863 bool ScDocShell::SetProtectionPassword( const String &rNewPassword )
2864 {
2865     bool bRes = false;
2866     ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
2867     if (pChangeTrack)
2868     {
2869         sal_Bool bProtected = pChangeTrack->IsProtected();
2870 
2871         if (rNewPassword.Len())
2872         {
2873             // when password protection is applied change tracking must always be active
2874             SetChangeRecording( true );
2875 
2876             ::com::sun::star::uno::Sequence< sal_Int8 > aProtectionHash;
2877             SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword );
2878             pChangeTrack->SetProtection( aProtectionHash );
2879         }
2880         else
2881         {
2882             pChangeTrack->SetProtection( ::com::sun::star::uno::Sequence< sal_Int8 >() );
2883         }
2884         bRes = true;
2885 
2886         if ( bProtected != pChangeTrack->IsProtected() )
2887         {
2888             UpdateAcceptChangesDialog();
2889             SetDocumentModified();
2890         }
2891     }
2892 
2893     return bRes;
2894 }
2895 
2896 
2897 bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash )
2898 {
2899     bool bRes = false;
2900     ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack();
2901     if (pChangeTrack && pChangeTrack->IsProtected())
2902     {
2903         rPasswordHash = pChangeTrack->GetProtection();
2904         bRes = true;
2905     }
2906     return bRes;
2907 }
2908 
2909 
2910