File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 113, column 13 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
2 | /* | ||||||
3 | * This file is part of the LibreOffice project. | ||||||
4 | * | ||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
8 | * | ||||||
9 | * This file incorporates work covered by the following license notice: | ||||||
10 | * | ||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||
13 | * with this work for additional information regarding copyright | ||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||
18 | */ | ||||||
19 | |||||||
20 | #include <com/sun/star/accessibility/AccessibleEventId.hpp> | ||||||
21 | #include <com/sun/star/uno/Any.h> | ||||||
22 | |||||||
23 | #include <comphelper/fileformat.h> | ||||||
24 | #include <comphelper/accessibletexthelper.hxx> | ||||||
25 | #include <rtl/ustrbuf.hxx> | ||||||
26 | #include <rtl/ustring.hxx> | ||||||
27 | #include <sal/log.hxx> | ||||||
28 | #include <unotools/eventcfg.hxx> | ||||||
29 | #include <sfx2/event.hxx> | ||||||
30 | #include <sfx2/app.hxx> | ||||||
31 | #include <sfx2/bindings.hxx> | ||||||
32 | #include <sfx2/docfile.hxx> | ||||||
33 | #include <sfx2/docfilt.hxx> | ||||||
34 | #include <sfx2/msg.hxx> | ||||||
35 | #include <sfx2/objface.hxx> | ||||||
36 | #include <sfx2/printer.hxx> | ||||||
37 | #include <sfx2/request.hxx> | ||||||
38 | #include <sfx2/viewfrm.hxx> | ||||||
39 | #include <comphelper/classids.hxx> | ||||||
40 | #include <sot/formats.hxx> | ||||||
41 | #include <sot/storage.hxx> | ||||||
42 | #include <svl/eitem.hxx> | ||||||
43 | #include <svl/intitem.hxx> | ||||||
44 | #include <svl/itempool.hxx> | ||||||
45 | #include <svl/slstitm.hxx> | ||||||
46 | #include <svl/hint.hxx> | ||||||
47 | #include <svl/stritem.hxx> | ||||||
48 | #include <svl/undo.hxx> | ||||||
49 | #include <svl/whiter.hxx> | ||||||
50 | #include <editeng/editeng.hxx> | ||||||
51 | #include <editeng/editstat.hxx> | ||||||
52 | #include <editeng/eeitem.hxx> | ||||||
53 | #include <editeng/fhgtitem.hxx> | ||||||
54 | #include <editeng/fontitem.hxx> | ||||||
55 | #include <vcl/mapmod.hxx> | ||||||
56 | #include <vcl/svapp.hxx> | ||||||
57 | #include <vcl/virdev.hxx> | ||||||
58 | #include <tools/mapunit.hxx> | ||||||
59 | #include <vcl/settings.hxx> | ||||||
60 | |||||||
61 | #include <document.hxx> | ||||||
62 | #include <action.hxx> | ||||||
63 | #include <dialog.hxx> | ||||||
64 | #include <format.hxx> | ||||||
65 | #include <starmath.hrc> | ||||||
66 | #include <strings.hrc> | ||||||
67 | #include <smmod.hxx> | ||||||
68 | #include <symbol.hxx> | ||||||
69 | #include <unomodel.hxx> | ||||||
70 | #include <utility.hxx> | ||||||
71 | #include <view.hxx> | ||||||
72 | #include "mathtype.hxx" | ||||||
73 | #include "ooxmlexport.hxx" | ||||||
74 | #include "ooxmlimport.hxx" | ||||||
75 | #include "rtfexport.hxx" | ||||||
76 | #include "mathmlimport.hxx" | ||||||
77 | #include "mathmlexport.hxx" | ||||||
78 | #include <svx/svxids.hrc> | ||||||
79 | #include <cursor.hxx> | ||||||
80 | #include <tools/diagnose_ex.h> | ||||||
81 | #include <visitors.hxx> | ||||||
82 | #include "accessibility.hxx" | ||||||
83 | #include "cfgitem.hxx" | ||||||
84 | #include <memory> | ||||||
85 | #include <utility> | ||||||
86 | #include <oox/mathml/export.hxx> | ||||||
87 | |||||||
88 | using namespace ::com::sun::star; | ||||||
89 | using namespace ::com::sun::star::accessibility; | ||||||
90 | using namespace ::com::sun::star::uno; | ||||||
91 | |||||||
92 | #define ShellClass_SmDocShell | ||||||
93 | #include <smslots.hxx> | ||||||
94 | |||||||
95 | |||||||
96 | SFX_IMPL_SUPERCLASS_INTERFACE(SmDocShell, SfxObjectShell)SfxInterface* SmDocShell::pInterface = nullptr; SfxInterface* SmDocShell::GetStaticInterface() { if ( !pInterface ) { pInterface = new SfxInterface( "SmDocShell", true, GetInterfaceId(), SfxObjectShell ::GetStaticInterface(), aSmDocShellSlots_Impl[0], sal_uInt16( sizeof(aSmDocShellSlots_Impl) / sizeof(SfxSlot) ) ); InitInterface_Impl (); } return pInterface; } SfxInterface* SmDocShell::GetInterface () const { return GetStaticInterface(); } void SmDocShell::RegisterInterface (const SfxModule* pMod) { GetStaticInterface()->Register(pMod ); } | ||||||
97 | |||||||
98 | void SmDocShell::InitInterface_Impl() | ||||||
99 | { | ||||||
100 | GetStaticInterface()->RegisterPopupMenu("view"); | ||||||
101 | } | ||||||
102 | |||||||
103 | SFX_IMPL_OBJECTFACTORY(SmDocShell, SvGlobalName(SO3_SM_CLASSID), "smath" )SfxObjectFactory& SmDocShell::Factory() { static SfxObjectFactory aObjectFactory(SvGlobalName(0x078B7ABA, 0x54FC, 0x457F, 0x85 , 0x51, 0x61, 0x47, 0xE7, 0x76, 0xA9, 0x97), "smath"); return aObjectFactory; } | ||||||
104 | |||||||
105 | void SmDocShell::Notify(SfxBroadcaster&, const SfxHint& rHint) | ||||||
106 | { | ||||||
107 | if (rHint.GetId() == SfxHintId::MathFormatChanged) | ||||||
108 | { | ||||||
109 | SetFormulaArranged(false); | ||||||
110 | |||||||
111 | mnModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState | ||||||
112 | |||||||
113 | Repaint(); | ||||||
114 | } | ||||||
115 | } | ||||||
116 | |||||||
117 | void SmDocShell::LoadSymbols() | ||||||
118 | { | ||||||
119 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
120 | pp->GetSymbolManager().Load(); | ||||||
121 | } | ||||||
122 | |||||||
123 | |||||||
124 | OUString SmDocShell::GetComment() const | ||||||
125 | { | ||||||
126 | uno::Reference<document::XDocumentPropertiesSupplier> xDPS( | ||||||
127 | GetModel(), uno::UNO_QUERY_THROW); | ||||||
128 | uno::Reference<document::XDocumentProperties> xDocProps( | ||||||
129 | xDPS->getDocumentProperties()); | ||||||
130 | return xDocProps->getDescription(); | ||||||
131 | } | ||||||
132 | |||||||
133 | |||||||
134 | void SmDocShell::SetText(const OUString& rBuffer) | ||||||
135 | { | ||||||
136 | if (rBuffer == maText) | ||||||
137 | return; | ||||||
138 | |||||||
139 | bool bIsEnabled = IsEnableSetModified(); | ||||||
140 | if( bIsEnabled ) | ||||||
141 | EnableSetModified( false ); | ||||||
142 | |||||||
143 | maText = rBuffer; | ||||||
144 | SetFormulaArranged( false ); | ||||||
145 | |||||||
146 | Parse(); | ||||||
147 | |||||||
148 | SmViewShell *pViewSh = SmGetActiveView(); | ||||||
149 | if( pViewSh ) | ||||||
150 | { | ||||||
151 | pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_TEXT((30000 + 256) + 100)); | ||||||
152 | if ( SfxObjectCreateMode::EMBEDDED == GetCreateMode() ) | ||||||
153 | { | ||||||
154 | // have SwOleClient::FormatChanged() to align the modified formula properly | ||||||
155 | // even if the visible area does not change (e.g. when formula text changes from | ||||||
156 | // "{a over b + c} over d" to "d over {a over b + c}" | ||||||
157 | SfxGetpApp()->NotifyEvent(SfxEventHint( SfxEventHintId::VisAreaChanged, GlobalEventConfig::GetEventName(GlobalEventId::VISAREACHANGED), this)); | ||||||
158 | |||||||
159 | Repaint(); | ||||||
160 | } | ||||||
161 | else | ||||||
162 | pViewSh->GetGraphicWindow().Invalidate(); | ||||||
163 | } | ||||||
164 | |||||||
165 | if ( bIsEnabled ) | ||||||
166 | EnableSetModified( bIsEnabled ); | ||||||
167 | SetModified(); | ||||||
168 | |||||||
169 | // launch accessible event if necessary | ||||||
170 | SmGraphicAccessible *pAcc = pViewSh ? pViewSh->GetGraphicWindow().GetAccessible_Impl() : nullptr; | ||||||
171 | if (pAcc) | ||||||
172 | { | ||||||
173 | Any aOldValue, aNewValue; | ||||||
174 | if ( comphelper::OCommonAccessibleText::implInitTextChangedEvent( maText, rBuffer, aOldValue, aNewValue ) ) | ||||||
175 | { | ||||||
176 | pAcc->LaunchEvent( AccessibleEventId::TEXT_CHANGED, | ||||||
177 | aOldValue, aNewValue ); | ||||||
178 | } | ||||||
179 | } | ||||||
180 | |||||||
181 | if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED ) | ||||||
182 | OnDocumentPrinterChanged(nullptr); | ||||||
183 | } | ||||||
184 | |||||||
185 | void SmDocShell::SetFormat(SmFormat const & rFormat) | ||||||
186 | { | ||||||
187 | maFormat = rFormat; | ||||||
188 | SetFormulaArranged( false ); | ||||||
189 | SetModified(); | ||||||
190 | |||||||
191 | mnModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState | ||||||
192 | |||||||
193 | // don't use SmGetActiveView since the view shell might not be active (0 pointer) | ||||||
194 | // if for example the Basic Macro dialog currently has the focus. Thus: | ||||||
195 | SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); | ||||||
196 | while (pFrm) | ||||||
197 | { | ||||||
198 | pFrm->GetBindings().Invalidate(SID_GAPHIC_SM((30000 + 256) + 101)); | ||||||
199 | pFrm = SfxViewFrame::GetNext( *pFrm, this ); | ||||||
200 | } | ||||||
201 | } | ||||||
202 | |||||||
203 | OUString const & SmDocShell::GetAccessibleText() | ||||||
204 | { | ||||||
205 | ArrangeFormula(); | ||||||
206 | if (maAccText.isEmpty()) | ||||||
207 | { | ||||||
208 | OSL_ENSURE( mpTree, "Tree missing" )do { if (true && (!(mpTree))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "208" ": "), "%s", "Tree missing"); } } while (false); | ||||||
209 | if (mpTree) | ||||||
210 | { | ||||||
211 | OUStringBuffer aBuf; | ||||||
212 | mpTree->GetAccessibleText(aBuf); | ||||||
213 | maAccText = aBuf.makeStringAndClear(); | ||||||
214 | } | ||||||
215 | } | ||||||
216 | return maAccText; | ||||||
217 | } | ||||||
218 | |||||||
219 | void SmDocShell::Parse() | ||||||
220 | { | ||||||
221 | mpTree.reset(); | ||||||
222 | ReplaceBadChars(); | ||||||
223 | mpTree = maParser.Parse(maText); | ||||||
224 | mnModifyCount++; //! see comment for SID_GAPHIC_SM in SmDocShell::GetState | ||||||
225 | SetFormulaArranged( false ); | ||||||
226 | InvalidateCursor(); | ||||||
227 | maUsedSymbols = maParser.GetUsedSymbols(); | ||||||
228 | } | ||||||
229 | |||||||
230 | |||||||
231 | void SmDocShell::ArrangeFormula() | ||||||
232 | { | ||||||
233 | if (mbFormulaArranged) | ||||||
234 | return; | ||||||
235 | |||||||
236 | // Only for the duration of the existence of this object the correct settings | ||||||
237 | // at the printer are guaranteed! | ||||||
238 | SmPrinterAccess aPrtAcc(*this); | ||||||
239 | OutputDevice* pOutDev = aPrtAcc.GetRefDev(); | ||||||
240 | |||||||
241 | SAL_WARN_IF( !pOutDev, "starmath", "!! SmDocShell::ArrangeFormula: reference device missing !!")do { if (true && (!pOutDev)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "starmath")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "!! SmDocShell::ArrangeFormula: reference device missing !!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "241" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "!! SmDocShell::ArrangeFormula: reference device missing !!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "!! SmDocShell::ArrangeFormula: reference device missing !!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "241" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "!! SmDocShell::ArrangeFormula: reference device missing !!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "241" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "!! SmDocShell::ArrangeFormula: reference device missing !!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "!! SmDocShell::ArrangeFormula: reference device missing !!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("starmath" ), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "241" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
242 | |||||||
243 | // if necessary get another OutputDevice for which we format | ||||||
244 | if (!pOutDev
| ||||||
245 | { | ||||||
246 | SmViewShell *pView = SmGetActiveView(); | ||||||
247 | if (pView) | ||||||
248 | pOutDev = &pView->GetGraphicWindow(); | ||||||
249 | else | ||||||
250 | { | ||||||
251 | pOutDev = &SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) )->GetDefaultVirtualDev(); | ||||||
252 | pOutDev->SetMapMode( MapMode(MapUnit::Map100thMM) ); | ||||||
253 | } | ||||||
254 | } | ||||||
255 | OSL_ENSURE(pOutDev->GetMapMode().GetMapUnit() == MapUnit::Map100thMM,do { if (true && (!(pOutDev->GetMapMode().GetMapUnit () == MapUnit::Map100thMM))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "256" ": "), "%s", "Sm : wrong MapMode"); } } while (false ) | ||||||
256 | "Sm : wrong MapMode")do { if (true && (!(pOutDev->GetMapMode().GetMapUnit () == MapUnit::Map100thMM))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "256" ": "), "%s", "Sm : wrong MapMode"); } } while (false ); | ||||||
257 | |||||||
258 | const SmFormat &rFormat = GetFormat(); | ||||||
259 | mpTree->Prepare(rFormat, *this, 0); | ||||||
260 | |||||||
261 | // format/draw formulas always from left to right, | ||||||
262 | // and numbers should not be converted | ||||||
263 | ComplexTextLayoutFlags nLayoutMode = pOutDev->GetLayoutMode(); | ||||||
264 | pOutDev->SetLayoutMode( ComplexTextLayoutFlags::Default ); | ||||||
265 | LanguageType nDigitLang = pOutDev->GetDigitLanguage(); | ||||||
266 | pOutDev->SetDigitLanguage( LANGUAGE_ENGLISHLanguageType(0x0009) ); | ||||||
267 | |||||||
268 | mpTree->Arrange(*pOutDev, rFormat); | ||||||
269 | |||||||
270 | pOutDev->SetLayoutMode( nLayoutMode ); | ||||||
271 | pOutDev->SetDigitLanguage( nDigitLang ); | ||||||
272 | |||||||
273 | SetFormulaArranged(true); | ||||||
274 | |||||||
275 | // invalidate accessible text | ||||||
276 | maAccText.clear(); | ||||||
277 | } | ||||||
278 | |||||||
279 | void SmDocShell::UpdateEditEngineDefaultFonts(const Color& aTextColor) | ||||||
280 | { | ||||||
281 | assert(mpEditEngineItemPool)(static_cast <bool> (mpEditEngineItemPool) ? void (0) : __assert_fail ("mpEditEngineItemPool", "/home/maarten/src/libreoffice/core/starmath/source/document.cxx" , 281, __extension__ __PRETTY_FUNCTION__)); | ||||||
282 | if (!mpEditEngineItemPool) | ||||||
283 | return; | ||||||
284 | |||||||
285 | // set fonts to be used | ||||||
286 | struct FontDta { | ||||||
287 | LanguageType nFallbackLang; | ||||||
288 | LanguageType nLang; | ||||||
289 | DefaultFontType nFontType; | ||||||
290 | sal_uInt16 nFontInfoId; | ||||||
291 | } aTable[3] = | ||||||
292 | { | ||||||
293 | // info to get western font to be used | ||||||
294 | { LANGUAGE_ENGLISH_USLanguageType(0x0409), LANGUAGE_NONELanguageType(0x00FF), | ||||||
295 | DefaultFontType::FIXED, EE_CHAR_FONTINFO }, | ||||||
296 | // info to get CJK font to be used | ||||||
297 | { LANGUAGE_JAPANESELanguageType(0x0411), LANGUAGE_NONELanguageType(0x00FF), | ||||||
298 | DefaultFontType::CJK_TEXT, EE_CHAR_FONTINFO_CJK }, | ||||||
299 | // info to get CTL font to be used | ||||||
300 | { LANGUAGE_ARABIC_SAUDI_ARABIALanguageType(0x0401), LANGUAGE_NONELanguageType(0x00FF), | ||||||
301 | DefaultFontType::CTL_TEXT, EE_CHAR_FONTINFO_CTL } | ||||||
302 | }; | ||||||
303 | |||||||
304 | aTable[0].nLang = maLinguOptions.nDefaultLanguage; | ||||||
305 | aTable[1].nLang = maLinguOptions.nDefaultLanguage_CJK; | ||||||
306 | aTable[2].nLang = maLinguOptions.nDefaultLanguage_CTL; | ||||||
307 | |||||||
308 | for (const FontDta & rFntDta : aTable) | ||||||
309 | { | ||||||
310 | LanguageType nLang = (LANGUAGE_NONELanguageType(0x00FF) == rFntDta.nLang) ? | ||||||
311 | rFntDta.nFallbackLang : rFntDta.nLang; | ||||||
312 | vcl::Font aFont = OutputDevice::GetDefaultFont( | ||||||
313 | rFntDta.nFontType, nLang, GetDefaultFontFlags::OnlyOne ); | ||||||
314 | aFont.SetColor(aTextColor); | ||||||
315 | mpEditEngineItemPool->SetPoolDefaultItem( | ||||||
316 | SvxFontItem( aFont.GetFamilyType(), aFont.GetFamilyName(), | ||||||
317 | aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(), | ||||||
318 | rFntDta.nFontInfoId ) ); | ||||||
319 | } | ||||||
320 | |||||||
321 | // set font heights | ||||||
322 | SvxFontHeightItem aFontHeigt( | ||||||
323 | Application::GetDefaultDevice()->LogicToPixel( | ||||||
324 | Size( 0, 11 ), MapMode( MapUnit::MapPoint ) ).Height(), 100, | ||||||
325 | EE_CHAR_FONTHEIGHT ); | ||||||
326 | mpEditEngineItemPool->SetPoolDefaultItem( aFontHeigt ); | ||||||
327 | aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CJK ); | ||||||
328 | mpEditEngineItemPool->SetPoolDefaultItem( aFontHeigt ); | ||||||
329 | aFontHeigt.SetWhich( EE_CHAR_FONTHEIGHT_CTL ); | ||||||
330 | mpEditEngineItemPool->SetPoolDefaultItem( aFontHeigt ); | ||||||
331 | } | ||||||
332 | |||||||
333 | EditEngine& SmDocShell::GetEditEngine() | ||||||
334 | { | ||||||
335 | if (!mpEditEngine) | ||||||
336 | { | ||||||
337 | //! | ||||||
338 | //! see also SmEditWindow::DataChanged ! | ||||||
339 | //! | ||||||
340 | |||||||
341 | mpEditEngineItemPool = EditEngine::CreatePool(); | ||||||
342 | |||||||
343 | const StyleSettings& rStyleSettings = Application::GetDefaultDevice()->GetSettings().GetStyleSettings(); | ||||||
344 | UpdateEditEngineDefaultFonts(rStyleSettings.GetFieldTextColor()); | ||||||
345 | |||||||
346 | mpEditEngine.reset( new EditEngine( mpEditEngineItemPool ) ); | ||||||
347 | |||||||
348 | mpEditEngine->SetAddExtLeading(true); | ||||||
349 | |||||||
350 | mpEditEngine->EnableUndo( true ); | ||||||
351 | mpEditEngine->SetDefTab( sal_uInt16( | ||||||
352 | Application::GetDefaultDevice()->GetTextWidth("XXXX")) ); | ||||||
353 | |||||||
354 | mpEditEngine->SetBackgroundColor(rStyleSettings.GetFieldColor()); | ||||||
355 | |||||||
356 | mpEditEngine->SetControlWord( | ||||||
357 | (mpEditEngine->GetControlWord() | EEControlBits::AUTOINDENTING) & | ||||||
358 | EEControlBits(~EEControlBits::UNDOATTRIBS) & | ||||||
359 | EEControlBits(~EEControlBits::PASTESPECIAL) ); | ||||||
360 | |||||||
361 | mpEditEngine->SetWordDelimiters(" .=+-*/(){}[];\""); | ||||||
362 | mpEditEngine->SetRefMapMode(MapMode(MapUnit::MapPixel)); | ||||||
363 | |||||||
364 | mpEditEngine->SetPaperSize( Size( 800, 0 ) ); | ||||||
365 | |||||||
366 | mpEditEngine->EraseVirtualDevice(); | ||||||
367 | |||||||
368 | // set initial text if the document already has some... | ||||||
369 | // (may be the case when reloading a doc) | ||||||
370 | OUString aTxt( GetText() ); | ||||||
371 | if (!aTxt.isEmpty()) | ||||||
372 | mpEditEngine->SetText( aTxt ); | ||||||
373 | |||||||
374 | mpEditEngine->ClearModifyFlag(); | ||||||
375 | |||||||
376 | } | ||||||
377 | return *mpEditEngine; | ||||||
378 | } | ||||||
379 | |||||||
380 | |||||||
381 | void SmDocShell::DrawFormula(OutputDevice &rDev, Point &rPosition, bool bDrawSelection) | ||||||
382 | { | ||||||
383 | if (!mpTree) | ||||||
384 | Parse(); | ||||||
385 | OSL_ENSURE(mpTree, "Sm : NULL pointer")do { if (true && (!(mpTree))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "385" ": "), "%s", "Sm : NULL pointer"); } } while (false ); | ||||||
386 | |||||||
387 | ArrangeFormula(); | ||||||
388 | |||||||
389 | // Problem: What happens to WYSIWYG? While we're active inplace, we don't have a reference | ||||||
390 | // device and aren't aligned to that either. So now there can be a difference between the | ||||||
391 | // VisArea (i.e. the size within the client) and the current size. | ||||||
392 | // Idea: The difference could be adapted with SmNod::SetSize (no long-term solution) | ||||||
393 | |||||||
394 | rPosition.AdjustX(maFormat.GetDistance( DIS_LEFTSPACE19 ) ); | ||||||
395 | rPosition.AdjustY(maFormat.GetDistance( DIS_TOPSPACE21 ) ); | ||||||
396 | |||||||
397 | //! in case of high contrast-mode (accessibility option!) | ||||||
398 | //! the draw mode needs to be set to default, because when embedding | ||||||
399 | //! Math for example in Calc in "a over b" the fraction bar may not | ||||||
400 | //! be visible else. More generally: the FillColor may have been changed. | ||||||
401 | DrawModeFlags nOldDrawMode = DrawModeFlags::Default; | ||||||
402 | bool bRestoreDrawMode = false; | ||||||
403 | if (OUTDEV_WINDOW == rDev.GetOutDevType() && | ||||||
404 | static_cast<vcl::Window &>(rDev).GetSettings().GetStyleSettings().GetHighContrastMode()) | ||||||
405 | { | ||||||
406 | nOldDrawMode = rDev.GetDrawMode(); | ||||||
407 | rDev.SetDrawMode( DrawModeFlags::Default ); | ||||||
408 | bRestoreDrawMode = true; | ||||||
409 | } | ||||||
410 | |||||||
411 | // format/draw formulas always from left to right | ||||||
412 | // and numbers should not be converted | ||||||
413 | ComplexTextLayoutFlags nLayoutMode = rDev.GetLayoutMode(); | ||||||
414 | rDev.SetLayoutMode( ComplexTextLayoutFlags::Default ); | ||||||
415 | LanguageType nDigitLang = rDev.GetDigitLanguage(); | ||||||
416 | rDev.SetDigitLanguage( LANGUAGE_ENGLISHLanguageType(0x0009) ); | ||||||
417 | |||||||
418 | //Set selection if any | ||||||
419 | if(mpCursor && bDrawSelection){ | ||||||
420 | mpCursor->AnnotateSelection(); | ||||||
421 | SmSelectionDrawingVisitor(rDev, mpTree.get(), rPosition); | ||||||
422 | } | ||||||
423 | |||||||
424 | //Drawing using visitor | ||||||
425 | SmDrawingVisitor(rDev, rPosition, mpTree.get()); | ||||||
426 | |||||||
427 | |||||||
428 | rDev.SetLayoutMode( nLayoutMode ); | ||||||
429 | rDev.SetDigitLanguage( nDigitLang ); | ||||||
430 | |||||||
431 | if (bRestoreDrawMode) | ||||||
432 | rDev.SetDrawMode( nOldDrawMode ); | ||||||
433 | } | ||||||
434 | |||||||
435 | Size SmDocShell::GetSize() | ||||||
436 | { | ||||||
437 | Size aRet; | ||||||
438 | |||||||
439 | if (!mpTree) | ||||||
440 | Parse(); | ||||||
441 | |||||||
442 | if (mpTree) | ||||||
443 | { | ||||||
444 | ArrangeFormula(); | ||||||
445 | aRet = mpTree->GetSize(); | ||||||
446 | |||||||
447 | if ( !aRet.Width() ) | ||||||
448 | aRet.setWidth( 2000 ); | ||||||
449 | else | ||||||
450 | aRet.AdjustWidth(maFormat.GetDistance( DIS_LEFTSPACE19 ) + | ||||||
451 | maFormat.GetDistance( DIS_RIGHTSPACE20 ) ); | ||||||
452 | if ( !aRet.Height() ) | ||||||
453 | aRet.setHeight( 1000 ); | ||||||
454 | else | ||||||
455 | aRet.AdjustHeight(maFormat.GetDistance( DIS_TOPSPACE21 ) + | ||||||
456 | maFormat.GetDistance( DIS_BOTTOMSPACE22 ) ); | ||||||
457 | } | ||||||
458 | |||||||
459 | return aRet; | ||||||
460 | } | ||||||
461 | |||||||
462 | void SmDocShell::InvalidateCursor(){ | ||||||
463 | mpCursor.reset(); | ||||||
464 | } | ||||||
465 | |||||||
466 | SmCursor& SmDocShell::GetCursor(){ | ||||||
467 | if(!mpCursor) | ||||||
468 | mpCursor.reset(new SmCursor(mpTree.get(), this)); | ||||||
469 | return *mpCursor; | ||||||
470 | } | ||||||
471 | |||||||
472 | bool SmDocShell::HasCursor() const { return mpCursor != nullptr; } | ||||||
473 | |||||||
474 | SmPrinterAccess::SmPrinterAccess( SmDocShell &rDocShell ) | ||||||
475 | { | ||||||
476 | pPrinter = rDocShell.GetPrt(); | ||||||
477 | if ( pPrinter ) | ||||||
478 | { | ||||||
479 | pPrinter->Push( PushFlags::MAPMODE ); | ||||||
480 | if ( SfxObjectCreateMode::EMBEDDED == rDocShell.GetCreateMode() ) | ||||||
481 | { | ||||||
482 | // if it is an embedded object (without its own printer) | ||||||
483 | // we change the MapMode temporarily. | ||||||
484 | //!If it is a document with its own printer the MapMode should | ||||||
485 | //!be set correct (once) elsewhere(!), in order to avoid numerous | ||||||
486 | //!superfluous pushing and popping of the MapMode when using | ||||||
487 | //!this class. | ||||||
488 | |||||||
489 | const MapUnit eOld = pPrinter->GetMapMode().GetMapUnit(); | ||||||
490 | if ( MapUnit::Map100thMM != eOld ) | ||||||
491 | { | ||||||
492 | MapMode aMap( pPrinter->GetMapMode() ); | ||||||
493 | aMap.SetMapUnit( MapUnit::Map100thMM ); | ||||||
494 | Point aTmp( aMap.GetOrigin() ); | ||||||
495 | aTmp.setX( OutputDevice::LogicToLogic( aTmp.X(), eOld, MapUnit::Map100thMM ) ); | ||||||
496 | aTmp.setY( OutputDevice::LogicToLogic( aTmp.Y(), eOld, MapUnit::Map100thMM ) ); | ||||||
497 | aMap.SetOrigin( aTmp ); | ||||||
498 | pPrinter->SetMapMode( aMap ); | ||||||
499 | } | ||||||
500 | } | ||||||
501 | } | ||||||
502 | pRefDev = rDocShell.GetRefDev(); | ||||||
503 | if ( !pRefDev || pPrinter.get() == pRefDev.get() ) | ||||||
504 | return; | ||||||
505 | |||||||
506 | pRefDev->Push( PushFlags::MAPMODE ); | ||||||
507 | if ( SfxObjectCreateMode::EMBEDDED != rDocShell.GetCreateMode() ) | ||||||
508 | return; | ||||||
509 | |||||||
510 | // if it is an embedded object (without its own printer) | ||||||
511 | // we change the MapMode temporarily. | ||||||
512 | //!If it is a document with its own printer the MapMode should | ||||||
513 | //!be set correct (once) elsewhere(!), in order to avoid numerous | ||||||
514 | //!superfluous pushing and popping of the MapMode when using | ||||||
515 | //!this class. | ||||||
516 | |||||||
517 | const MapUnit eOld = pRefDev->GetMapMode().GetMapUnit(); | ||||||
518 | if ( MapUnit::Map100thMM != eOld ) | ||||||
519 | { | ||||||
520 | MapMode aMap( pRefDev->GetMapMode() ); | ||||||
521 | aMap.SetMapUnit( MapUnit::Map100thMM ); | ||||||
522 | Point aTmp( aMap.GetOrigin() ); | ||||||
523 | aTmp.setX( OutputDevice::LogicToLogic( aTmp.X(), eOld, MapUnit::Map100thMM ) ); | ||||||
524 | aTmp.setY( OutputDevice::LogicToLogic( aTmp.Y(), eOld, MapUnit::Map100thMM ) ); | ||||||
525 | aMap.SetOrigin( aTmp ); | ||||||
526 | pRefDev->SetMapMode( aMap ); | ||||||
527 | } | ||||||
528 | } | ||||||
529 | |||||||
530 | SmPrinterAccess::~SmPrinterAccess() | ||||||
531 | { | ||||||
532 | if ( pPrinter ) | ||||||
533 | pPrinter->Pop(); | ||||||
534 | if ( pRefDev && pRefDev != pPrinter ) | ||||||
535 | pRefDev->Pop(); | ||||||
536 | } | ||||||
537 | |||||||
538 | Printer* SmDocShell::GetPrt() | ||||||
539 | { | ||||||
540 | if (SfxObjectCreateMode::EMBEDDED == GetCreateMode()) | ||||||
541 | { | ||||||
542 | // Normally the server provides the printer. But if it doesn't provide one (e.g. because | ||||||
543 | // there is no connection) it still can be the case that we know the printer because it | ||||||
544 | // has been passed on by the server in OnDocumentPrinterChanged and being kept temporarily. | ||||||
545 | Printer* pPrt = GetDocumentPrinter(); | ||||||
546 | if (!pPrt && mpTmpPrinter) | ||||||
547 | pPrt = mpTmpPrinter; | ||||||
548 | return pPrt; | ||||||
549 | } | ||||||
550 | else if (!mpPrinter) | ||||||
551 | { | ||||||
552 | auto pOptions = std::make_unique<SfxItemSet>( | ||||||
553 | GetPool(), | ||||||
554 | svl::Items< | ||||||
555 | SID_PRINTTITLE((30000 + 256) + 112), SID_PRINTZOOM((30000 + 256) + 116), | ||||||
556 | SID_NO_RIGHT_SPACES((30000 + 256) + 124), SID_SAVE_ONLY_USED_SYMBOLS((30000 + 256) + 125), | ||||||
557 | SID_AUTO_CLOSE_BRACKETS((30000 + 256) + 127), SID_AUTO_CLOSE_BRACKETS((30000 + 256) + 127)>{}); | ||||||
558 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
559 | pp->GetConfig()->ConfigToItemSet(*pOptions); | ||||||
560 | mpPrinter = VclPtr<SfxPrinter>::Create(std::move(pOptions)); | ||||||
561 | mpPrinter->SetMapMode(MapMode(MapUnit::Map100thMM)); | ||||||
562 | } | ||||||
563 | return mpPrinter; | ||||||
564 | } | ||||||
565 | |||||||
566 | OutputDevice* SmDocShell::GetRefDev() | ||||||
567 | { | ||||||
568 | if (SfxObjectCreateMode::EMBEDDED == GetCreateMode()) | ||||||
569 | { | ||||||
570 | OutputDevice* pOutDev = GetDocumentRefDev(); | ||||||
571 | if (pOutDev) | ||||||
572 | return pOutDev; | ||||||
573 | } | ||||||
574 | |||||||
575 | return GetPrt(); | ||||||
576 | } | ||||||
577 | |||||||
578 | void SmDocShell::SetPrinter( SfxPrinter *pNew ) | ||||||
579 | { | ||||||
580 | mpPrinter.disposeAndClear(); | ||||||
581 | mpPrinter = pNew; //Transfer ownership | ||||||
582 | mpPrinter->SetMapMode( MapMode(MapUnit::Map100thMM) ); | ||||||
583 | SetFormulaArranged(false); | ||||||
584 | Repaint(); | ||||||
585 | } | ||||||
586 | |||||||
587 | void SmDocShell::OnDocumentPrinterChanged( Printer *pPrt ) | ||||||
588 | { | ||||||
589 | mpTmpPrinter = pPrt; | ||||||
590 | SetFormulaArranged(false); | ||||||
591 | Size aOldSize = GetVisArea().GetSize(); | ||||||
592 | Repaint(); | ||||||
593 | if( aOldSize != GetVisArea().GetSize() && !maText.isEmpty() ) | ||||||
594 | SetModified(); | ||||||
595 | mpTmpPrinter = nullptr; | ||||||
596 | } | ||||||
597 | |||||||
598 | void SmDocShell::Repaint() | ||||||
599 | { | ||||||
600 | bool bIsEnabled = IsEnableSetModified(); | ||||||
601 | if (bIsEnabled) | ||||||
602 | EnableSetModified( false ); | ||||||
603 | |||||||
604 | SetFormulaArranged(false); | ||||||
605 | |||||||
606 | Size aVisSize = GetSize(); | ||||||
607 | SetVisAreaSize(aVisSize); | ||||||
608 | SmViewShell* pViewSh = SmGetActiveView(); | ||||||
609 | if (pViewSh) | ||||||
610 | pViewSh->GetGraphicWindow().Invalidate(); | ||||||
611 | |||||||
612 | if (bIsEnabled) | ||||||
613 | EnableSetModified(bIsEnabled); | ||||||
614 | } | ||||||
615 | |||||||
616 | SmDocShell::SmDocShell( SfxModelFlags i_nSfxCreationFlags ) | ||||||
617 | : SfxObjectShell(i_nSfxCreationFlags) | ||||||
618 | , mpEditEngineItemPool(nullptr) | ||||||
619 | , mpPrinter(nullptr) | ||||||
620 | , mpTmpPrinter(nullptr) | ||||||
621 | , mnModifyCount(0) | ||||||
622 | , mbFormulaArranged(false) | ||||||
623 | { | ||||||
624 | SvtLinguConfig().GetOptions(maLinguOptions); | ||||||
625 | |||||||
626 | SetPool(&SfxGetpApp()->GetPool()); | ||||||
627 | |||||||
628 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
629 | maFormat = pp->GetConfig()->GetStandardFormat(); | ||||||
630 | |||||||
631 | StartListening(maFormat); | ||||||
632 | StartListening(*pp->GetConfig()); | ||||||
633 | |||||||
634 | SetBaseModel(new SmModel(this)); | ||||||
635 | } | ||||||
636 | |||||||
637 | SmDocShell::~SmDocShell() | ||||||
638 | { | ||||||
639 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
640 | |||||||
641 | EndListening(maFormat); | ||||||
642 | EndListening(*pp->GetConfig()); | ||||||
643 | |||||||
644 | mpCursor.reset(); | ||||||
645 | mpEditEngine.reset(); | ||||||
646 | SfxItemPool::Free(mpEditEngineItemPool); | ||||||
647 | mpPrinter.disposeAndClear(); | ||||||
648 | } | ||||||
649 | |||||||
650 | bool SmDocShell::ConvertFrom(SfxMedium &rMedium) | ||||||
651 | { | ||||||
652 | bool bSuccess = false; | ||||||
653 | const OUString& rFltName = rMedium.GetFilter()->GetFilterName(); | ||||||
654 | |||||||
655 | OSL_ENSURE( rFltName != STAROFFICE_XML, "Wrong filter!")do { if (true && (!(rFltName != "StarOffice XML (Math)" ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "655" ": "), "%s", "Wrong filter!"); } } while (false); | ||||||
656 | |||||||
657 | if ( rFltName == MATHML_XML"MathML XML (Math)" ) | ||||||
658 | { | ||||||
659 | if (mpTree) | ||||||
660 | { | ||||||
661 | mpTree.reset(); | ||||||
662 | InvalidateCursor(); | ||||||
663 | } | ||||||
664 | Reference<css::frame::XModel> xModel(GetModel()); | ||||||
665 | SmXMLImportWrapper aEquation(xModel); | ||||||
666 | bSuccess = ( ERRCODE_NONEErrCode(0) == aEquation.Import(rMedium) ); | ||||||
667 | } | ||||||
668 | else | ||||||
669 | { | ||||||
670 | SvStream *pStream = rMedium.GetInStream(); | ||||||
671 | if ( pStream ) | ||||||
672 | { | ||||||
673 | if ( SotStorage::IsStorageFile( pStream ) ) | ||||||
674 | { | ||||||
675 | tools::SvRef<SotStorage> aStorage = new SotStorage( pStream, false ); | ||||||
676 | if ( aStorage->IsStream("Equation Native") ) | ||||||
677 | { | ||||||
678 | // is this a MathType Storage? | ||||||
679 | OUStringBuffer aBuffer; | ||||||
680 | MathType aEquation(aBuffer); | ||||||
681 | bSuccess = aEquation.Parse( aStorage.get() ); | ||||||
682 | if ( bSuccess ) | ||||||
683 | { | ||||||
684 | maText = aBuffer.makeStringAndClear(); | ||||||
685 | Parse(); | ||||||
686 | } | ||||||
687 | } | ||||||
688 | } | ||||||
689 | } | ||||||
690 | } | ||||||
691 | |||||||
692 | if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED ) | ||||||
693 | { | ||||||
694 | SetFormulaArranged( false ); | ||||||
695 | Repaint(); | ||||||
696 | } | ||||||
697 | |||||||
698 | FinishedLoading(); | ||||||
699 | return bSuccess; | ||||||
700 | } | ||||||
701 | |||||||
702 | |||||||
703 | bool SmDocShell::InitNew( const uno::Reference < embed::XStorage >& xStorage ) | ||||||
704 | { | ||||||
705 | bool bRet = false; | ||||||
706 | if ( SfxObjectShell::InitNew( xStorage ) ) | ||||||
707 | { | ||||||
708 | bRet = true; | ||||||
709 | SetVisArea(tools::Rectangle(Point(0, 0), Size(2000, 1000))); | ||||||
710 | } | ||||||
711 | return bRet; | ||||||
712 | } | ||||||
713 | |||||||
714 | |||||||
715 | bool SmDocShell::Load( SfxMedium& rMedium ) | ||||||
716 | { | ||||||
717 | bool bRet = false; | ||||||
718 | if( SfxObjectShell::Load( rMedium )) | ||||||
719 | { | ||||||
720 | uno::Reference < embed::XStorage > xStorage = GetMedium()->GetStorage(); | ||||||
721 | if (xStorage->hasByName("content.xml") && xStorage->isStreamElement("content.xml")) | ||||||
722 | { | ||||||
723 | // is this a fabulous math package ? | ||||||
724 | Reference<css::frame::XModel> xModel(GetModel()); | ||||||
725 | SmXMLImportWrapper aEquation(xModel); | ||||||
726 | auto nError = aEquation.Import(rMedium); | ||||||
727 | bRet = ERRCODE_NONEErrCode(0) == nError; | ||||||
728 | SetError(nError); | ||||||
729 | } | ||||||
730 | } | ||||||
731 | |||||||
732 | if ( GetCreateMode() == SfxObjectCreateMode::EMBEDDED ) | ||||||
733 | { | ||||||
734 | SetFormulaArranged( false ); | ||||||
735 | Repaint(); | ||||||
736 | } | ||||||
737 | |||||||
738 | FinishedLoading(); | ||||||
739 | return bRet; | ||||||
740 | } | ||||||
741 | |||||||
742 | |||||||
743 | bool SmDocShell::Save() | ||||||
744 | { | ||||||
745 | //! apply latest changes if necessary | ||||||
746 | UpdateText(); | ||||||
747 | |||||||
748 | if ( SfxObjectShell::Save() ) | ||||||
749 | { | ||||||
750 | if (!mpTree) | ||||||
751 | Parse(); | ||||||
752 | if( mpTree ) | ||||||
753 | ArrangeFormula(); | ||||||
754 | |||||||
755 | Reference<css::frame::XModel> xModel(GetModel()); | ||||||
756 | SmXMLExportWrapper aEquation(xModel); | ||||||
757 | aEquation.SetFlat(false); | ||||||
758 | return aEquation.Export(*GetMedium()); | ||||||
759 | } | ||||||
760 | |||||||
761 | return false; | ||||||
762 | } | ||||||
763 | |||||||
764 | /* | ||||||
765 | * replace bad characters that can not be saved. (#i74144) | ||||||
766 | * */ | ||||||
767 | void SmDocShell::ReplaceBadChars() | ||||||
768 | { | ||||||
769 | bool bReplace = false; | ||||||
770 | |||||||
771 | if (!mpEditEngine) | ||||||
772 | return; | ||||||
773 | |||||||
774 | OUStringBuffer aBuf( mpEditEngine->GetText() ); | ||||||
775 | |||||||
776 | for (sal_Int32 i = 0; i < aBuf.getLength(); ++i) | ||||||
777 | { | ||||||
778 | if (aBuf[i] < ' ' && aBuf[i] != '\r' && aBuf[i] != '\n' && aBuf[i] != '\t') | ||||||
779 | { | ||||||
780 | aBuf[i] = ' '; | ||||||
781 | bReplace = true; | ||||||
782 | } | ||||||
783 | } | ||||||
784 | |||||||
785 | if (bReplace) | ||||||
786 | maText = aBuf.makeStringAndClear(); | ||||||
787 | } | ||||||
788 | |||||||
789 | |||||||
790 | void SmDocShell::UpdateText() | ||||||
791 | { | ||||||
792 | if (mpEditEngine && mpEditEngine->IsModified()) | ||||||
793 | { | ||||||
794 | OUString aEngTxt( mpEditEngine->GetText() ); | ||||||
795 | if (GetText() != aEngTxt) | ||||||
796 | SetText( aEngTxt ); | ||||||
797 | } | ||||||
798 | } | ||||||
799 | |||||||
800 | |||||||
801 | bool SmDocShell::SaveAs( SfxMedium& rMedium ) | ||||||
802 | { | ||||||
803 | bool bRet = false; | ||||||
804 | |||||||
805 | //! apply latest changes if necessary | ||||||
806 | UpdateText(); | ||||||
807 | |||||||
808 | if ( SfxObjectShell::SaveAs( rMedium ) ) | ||||||
809 | { | ||||||
810 | if (!mpTree) | ||||||
811 | Parse(); | ||||||
812 | if( mpTree ) | ||||||
813 | ArrangeFormula(); | ||||||
814 | |||||||
815 | Reference<css::frame::XModel> xModel(GetModel()); | ||||||
816 | SmXMLExportWrapper aEquation(xModel); | ||||||
817 | aEquation.SetFlat(false); | ||||||
818 | bRet = aEquation.Export(rMedium); | ||||||
819 | } | ||||||
820 | return bRet; | ||||||
821 | } | ||||||
822 | |||||||
823 | bool SmDocShell::ConvertTo( SfxMedium &rMedium ) | ||||||
824 | { | ||||||
825 | bool bRet = false; | ||||||
826 | std::shared_ptr<const SfxFilter> pFlt = rMedium.GetFilter(); | ||||||
827 | if( pFlt ) | ||||||
828 | { | ||||||
829 | if( !mpTree ) | ||||||
830 | Parse(); | ||||||
831 | if( mpTree ) | ||||||
832 | ArrangeFormula(); | ||||||
833 | |||||||
834 | const OUString& rFltName = pFlt->GetFilterName(); | ||||||
835 | if(rFltName == STAROFFICE_XML"StarOffice XML (Math)") | ||||||
836 | { | ||||||
837 | Reference<css::frame::XModel> xModel(GetModel()); | ||||||
838 | SmXMLExportWrapper aEquation(xModel); | ||||||
839 | aEquation.SetFlat(false); | ||||||
840 | bRet = aEquation.Export(rMedium); | ||||||
841 | } | ||||||
842 | else if(rFltName == MATHML_XML"MathML XML (Math)") | ||||||
843 | { | ||||||
844 | Reference<css::frame::XModel> xModel(GetModel()); | ||||||
845 | SmXMLExportWrapper aEquation(xModel); | ||||||
846 | aEquation.SetFlat(true); | ||||||
847 | bRet = aEquation.Export(rMedium); | ||||||
848 | } | ||||||
849 | else if (pFlt->GetFilterName() == "MathType 3.x") | ||||||
850 | bRet = WriteAsMathType3( rMedium ); | ||||||
851 | } | ||||||
852 | return bRet; | ||||||
853 | } | ||||||
854 | |||||||
855 | void SmDocShell::writeFormulaOoxml( | ||||||
856 | ::sax_fastparser::FSHelperPtr const& pSerializer, | ||||||
857 | oox::core::OoxmlVersion const version, | ||||||
858 | oox::drawingml::DocumentType const documentType, | ||||||
859 | const sal_Int8 nAlign) | ||||||
860 | { | ||||||
861 | if( !mpTree ) | ||||||
862 | Parse(); | ||||||
863 | if( mpTree ) | ||||||
864 | ArrangeFormula(); | ||||||
865 | SmOoxmlExport aEquation(mpTree.get(), version, documentType); | ||||||
866 | if(documentType == oox::drawingml::DOCUMENT_DOCX) | ||||||
867 | aEquation.ConvertFromStarMath( pSerializer, nAlign); | ||||||
868 | else | ||||||
869 | aEquation.ConvertFromStarMath(pSerializer, oox::FormulaExportBase::eFormulaAlign::INLINE); | ||||||
870 | } | ||||||
871 | |||||||
872 | void SmDocShell::writeFormulaRtf(OStringBuffer& rBuffer, rtl_TextEncoding nEncoding) | ||||||
873 | { | ||||||
874 | if (!mpTree) | ||||||
875 | Parse(); | ||||||
876 | if (mpTree) | ||||||
877 | ArrangeFormula(); | ||||||
878 | SmRtfExport aEquation(mpTree.get()); | ||||||
879 | aEquation.ConvertFromStarMath(rBuffer, nEncoding); | ||||||
880 | } | ||||||
881 | |||||||
882 | void SmDocShell::readFormulaOoxml( oox::formulaimport::XmlStream& stream ) | ||||||
883 | { | ||||||
884 | SmOoxmlImport aEquation( stream ); | ||||||
885 | SetText( aEquation.ConvertToStarMath()); | ||||||
886 | } | ||||||
887 | |||||||
888 | void SmDocShell::Execute(SfxRequest& rReq) | ||||||
889 | { | ||||||
890 | switch (rReq.GetSlot()) | ||||||
891 | { | ||||||
892 | case SID_TEXTMODE((30000 + 256) + 57): | ||||||
893 | { | ||||||
894 | SmFormat aOldFormat = GetFormat(); | ||||||
895 | SmFormat aNewFormat( aOldFormat ); | ||||||
896 | aNewFormat.SetTextmode(!aOldFormat.IsTextmode()); | ||||||
897 | |||||||
898 | SfxUndoManager *pTmpUndoMgr = GetUndoManager(); | ||||||
899 | if (pTmpUndoMgr) | ||||||
900 | pTmpUndoMgr->AddUndoAction( | ||||||
901 | std::make_unique<SmFormatAction>(this, aOldFormat, aNewFormat)); | ||||||
902 | |||||||
903 | SetFormat( aNewFormat ); | ||||||
904 | Repaint(); | ||||||
905 | } | ||||||
906 | break; | ||||||
907 | |||||||
908 | case SID_AUTO_REDRAW((30000 + 256) + 55) : | ||||||
909 | { | ||||||
910 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
911 | bool bRedraw = pp->GetConfig()->IsAutoRedraw(); | ||||||
912 | pp->GetConfig()->SetAutoRedraw(!bRedraw); | ||||||
913 | } | ||||||
914 | break; | ||||||
915 | |||||||
916 | case SID_LOADSYMBOLS((30000 + 256) + 107): | ||||||
917 | LoadSymbols(); | ||||||
918 | break; | ||||||
919 | |||||||
920 | case SID_SAVESYMBOLS((30000 + 256) + 108): | ||||||
921 | SaveSymbols(); | ||||||
922 | break; | ||||||
923 | |||||||
924 | case SID_FONT((30000 + 256) + 50): | ||||||
925 | { | ||||||
926 | // get device used to retrieve the FontList | ||||||
927 | OutputDevice *pDev = GetPrinter(); | ||||||
928 | if (!pDev || pDev->GetDevFontCount() == 0) | ||||||
929 | pDev = &SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) )->GetDefaultVirtualDev(); | ||||||
930 | OSL_ENSURE (pDev, "device for font list missing" )do { if (true && (!(pDev))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "930" ": "), "%s", "device for font list missing"); } } while (false); | ||||||
931 | |||||||
932 | SmFontTypeDialog aFontTypeDialog(rReq.GetFrameWeld(), pDev); | ||||||
933 | |||||||
934 | SmFormat aOldFormat = GetFormat(); | ||||||
935 | aFontTypeDialog.ReadFrom( aOldFormat ); | ||||||
936 | if (aFontTypeDialog.run() == RET_OK) | ||||||
937 | { | ||||||
938 | SmFormat aNewFormat( aOldFormat ); | ||||||
939 | |||||||
940 | aFontTypeDialog.WriteTo(aNewFormat); | ||||||
941 | SfxUndoManager *pTmpUndoMgr = GetUndoManager(); | ||||||
942 | if (pTmpUndoMgr) | ||||||
943 | pTmpUndoMgr->AddUndoAction( | ||||||
944 | std::make_unique<SmFormatAction>(this, aOldFormat, aNewFormat)); | ||||||
945 | |||||||
946 | SetFormat( aNewFormat ); | ||||||
947 | Repaint(); | ||||||
948 | } | ||||||
949 | } | ||||||
950 | break; | ||||||
951 | |||||||
952 | case SID_FONTSIZE((30000 + 256) + 51): | ||||||
953 | { | ||||||
954 | SmFontSizeDialog aFontSizeDialog(rReq.GetFrameWeld()); | ||||||
955 | |||||||
956 | SmFormat aOldFormat = GetFormat(); | ||||||
957 | aFontSizeDialog.ReadFrom( aOldFormat ); | ||||||
958 | if (aFontSizeDialog.run() == RET_OK) | ||||||
959 | { | ||||||
960 | SmFormat aNewFormat( aOldFormat ); | ||||||
961 | |||||||
962 | aFontSizeDialog.WriteTo(aNewFormat); | ||||||
963 | |||||||
964 | SfxUndoManager *pTmpUndoMgr = GetUndoManager(); | ||||||
965 | if (pTmpUndoMgr) | ||||||
966 | pTmpUndoMgr->AddUndoAction( | ||||||
967 | std::make_unique<SmFormatAction>(this, aOldFormat, aNewFormat)); | ||||||
968 | |||||||
969 | SetFormat( aNewFormat ); | ||||||
970 | Repaint(); | ||||||
971 | } | ||||||
972 | } | ||||||
973 | break; | ||||||
974 | |||||||
975 | case SID_DISTANCE((30000 + 256) + 52): | ||||||
976 | { | ||||||
977 | SmDistanceDialog aDistanceDialog(rReq.GetFrameWeld()); | ||||||
978 | |||||||
979 | SmFormat aOldFormat = GetFormat(); | ||||||
980 | aDistanceDialog.ReadFrom( aOldFormat ); | ||||||
981 | if (aDistanceDialog.run() == RET_OK) | ||||||
982 | { | ||||||
983 | SmFormat aNewFormat( aOldFormat ); | ||||||
984 | |||||||
985 | aDistanceDialog.WriteTo(aNewFormat); | ||||||
986 | |||||||
987 | SfxUndoManager *pTmpUndoMgr = GetUndoManager(); | ||||||
988 | if (pTmpUndoMgr) | ||||||
989 | pTmpUndoMgr->AddUndoAction( | ||||||
990 | std::make_unique<SmFormatAction>(this, aOldFormat, aNewFormat)); | ||||||
991 | |||||||
992 | SetFormat( aNewFormat ); | ||||||
993 | Repaint(); | ||||||
994 | } | ||||||
995 | } | ||||||
996 | break; | ||||||
997 | |||||||
998 | case SID_ALIGN((30000 + 256) + 53): | ||||||
999 | { | ||||||
1000 | SmAlignDialog aAlignDialog(rReq.GetFrameWeld()); | ||||||
1001 | |||||||
1002 | SmFormat aOldFormat = GetFormat(); | ||||||
1003 | aAlignDialog.ReadFrom( aOldFormat ); | ||||||
1004 | if (aAlignDialog.run() == RET_OK) | ||||||
1005 | { | ||||||
1006 | SmFormat aNewFormat( aOldFormat ); | ||||||
1007 | |||||||
1008 | aAlignDialog.WriteTo(aNewFormat); | ||||||
1009 | |||||||
1010 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
1011 | SmFormat aFmt( pp->GetConfig()->GetStandardFormat() ); | ||||||
1012 | aAlignDialog.WriteTo( aFmt ); | ||||||
1013 | pp->GetConfig()->SetStandardFormat( aFmt ); | ||||||
1014 | |||||||
1015 | SfxUndoManager *pTmpUndoMgr = GetUndoManager(); | ||||||
1016 | if (pTmpUndoMgr) | ||||||
1017 | pTmpUndoMgr->AddUndoAction( | ||||||
1018 | std::make_unique<SmFormatAction>(this, aOldFormat, aNewFormat)); | ||||||
1019 | |||||||
1020 | SetFormat( aNewFormat ); | ||||||
1021 | Repaint(); | ||||||
1022 | } | ||||||
1023 | } | ||||||
1024 | break; | ||||||
1025 | |||||||
1026 | case SID_TEXT((30000 + 256) + 100): | ||||||
1027 | { | ||||||
1028 | const SfxStringItem& rItem = static_cast<const SfxStringItem&>(rReq.GetArgs()->Get(SID_TEXT((30000 + 256) + 100))); | ||||||
1029 | if (GetText() != rItem.GetValue()) | ||||||
1030 | SetText(rItem.GetValue()); | ||||||
1031 | } | ||||||
1032 | break; | ||||||
1033 | |||||||
1034 | case SID_UNDO(5000 + 701): | ||||||
1035 | case SID_REDO(5000 + 700): | ||||||
1036 | { | ||||||
1037 | SfxUndoManager* pTmpUndoMgr = GetUndoManager(); | ||||||
1038 | if( pTmpUndoMgr ) | ||||||
1039 | { | ||||||
1040 | sal_uInt16 nId = rReq.GetSlot(), nCnt = 1; | ||||||
1041 | const SfxItemSet* pArgs = rReq.GetArgs(); | ||||||
1042 | const SfxPoolItem* pItem; | ||||||
1043 | if( pArgs && SfxItemState::SET == pArgs->GetItemState( nId, false, &pItem )) | ||||||
1044 | nCnt = static_cast<const SfxUInt16Item*>(pItem)->GetValue(); | ||||||
1045 | |||||||
1046 | bool (SfxUndoManager::*fnDo)(); | ||||||
1047 | |||||||
1048 | size_t nCount; | ||||||
1049 | if( SID_UNDO(5000 + 701) == rReq.GetSlot() ) | ||||||
1050 | { | ||||||
1051 | nCount = pTmpUndoMgr->GetUndoActionCount(); | ||||||
1052 | fnDo = &SfxUndoManager::Undo; | ||||||
1053 | } | ||||||
1054 | else | ||||||
1055 | { | ||||||
1056 | nCount = pTmpUndoMgr->GetRedoActionCount(); | ||||||
1057 | fnDo = &SfxUndoManager::Redo; | ||||||
1058 | } | ||||||
1059 | |||||||
1060 | try | ||||||
1061 | { | ||||||
1062 | for( ; nCnt && nCount; --nCnt, --nCount ) | ||||||
1063 | (pTmpUndoMgr->*fnDo)(); | ||||||
1064 | } | ||||||
1065 | catch( const Exception& ) | ||||||
1066 | { | ||||||
1067 | DBG_UNHANDLED_EXCEPTION("starmath")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/starmath/source/document.cxx" ":" "1067" ": ", "starmath" );; | ||||||
1068 | } | ||||||
1069 | } | ||||||
1070 | Repaint(); | ||||||
1071 | UpdateText(); | ||||||
1072 | SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); | ||||||
1073 | while( pFrm ) | ||||||
1074 | { | ||||||
1075 | SfxBindings& rBind = pFrm->GetBindings(); | ||||||
1076 | rBind.Invalidate(SID_UNDO(5000 + 701)); | ||||||
1077 | rBind.Invalidate(SID_REDO(5000 + 700)); | ||||||
1078 | rBind.Invalidate(SID_REPEAT(5000 + 702)); | ||||||
1079 | rBind.Invalidate(SID_CLEARHISTORY(5000 + 703)); | ||||||
1080 | pFrm = SfxViewFrame::GetNext( *pFrm, this ); | ||||||
1081 | } | ||||||
1082 | } | ||||||
1083 | break; | ||||||
1084 | } | ||||||
1085 | |||||||
1086 | rReq.Done(); | ||||||
1087 | } | ||||||
1088 | |||||||
1089 | |||||||
1090 | void SmDocShell::GetState(SfxItemSet &rSet) | ||||||
1091 | { | ||||||
1092 | SfxWhichIter aIter(rSet); | ||||||
1093 | |||||||
1094 | for (sal_uInt16 nWh = aIter.FirstWhich(); 0 != nWh; nWh = aIter.NextWhich()) | ||||||
1095 | { | ||||||
1096 | switch (nWh) | ||||||
1097 | { | ||||||
1098 | case SID_TEXTMODE((30000 + 256) + 57): | ||||||
1099 | rSet.Put(SfxBoolItem(SID_TEXTMODE((30000 + 256) + 57), GetFormat().IsTextmode())); | ||||||
1100 | break; | ||||||
1101 | |||||||
1102 | case SID_DOCTEMPLATE(5000 + 538) : | ||||||
1103 | rSet.DisableItem(SID_DOCTEMPLATE(5000 + 538)); | ||||||
1104 | break; | ||||||
1105 | |||||||
1106 | case SID_AUTO_REDRAW((30000 + 256) + 55) : | ||||||
1107 | { | ||||||
1108 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
1109 | bool bRedraw = pp->GetConfig()->IsAutoRedraw(); | ||||||
1110 | |||||||
1111 | rSet.Put(SfxBoolItem(SID_AUTO_REDRAW((30000 + 256) + 55), bRedraw)); | ||||||
1112 | } | ||||||
1113 | break; | ||||||
1114 | |||||||
1115 | case SID_MODIFYSTATUS((30000 + 256) + 110): | ||||||
1116 | { | ||||||
1117 | sal_Unicode cMod = ' '; | ||||||
1118 | if (IsModified()) | ||||||
1119 | cMod = '*'; | ||||||
1120 | rSet.Put(SfxStringItem(SID_MODIFYSTATUS((30000 + 256) + 110), OUString(cMod))); | ||||||
1121 | } | ||||||
1122 | break; | ||||||
1123 | |||||||
1124 | case SID_TEXT((30000 + 256) + 100): | ||||||
1125 | rSet.Put(SfxStringItem(SID_TEXT((30000 + 256) + 100), GetText())); | ||||||
1126 | break; | ||||||
1127 | |||||||
1128 | case SID_GAPHIC_SM((30000 + 256) + 101): | ||||||
1129 | //! very old (pre UNO) and ugly hack to invalidate the SmGraphicWindow. | ||||||
1130 | //! If mnModifyCount gets changed then the call below will implicitly notify | ||||||
1131 | //! SmGraphicController::StateChanged and there the window gets invalidated. | ||||||
1132 | //! Thus all the 'mnModifyCount++' before invalidating this slot. | ||||||
1133 | rSet.Put(SfxInt16Item(SID_GAPHIC_SM((30000 + 256) + 101), mnModifyCount)); | ||||||
1134 | break; | ||||||
1135 | |||||||
1136 | case SID_UNDO(5000 + 701): | ||||||
1137 | case SID_REDO(5000 + 700): | ||||||
1138 | { | ||||||
1139 | SfxViewFrame* pFrm = SfxViewFrame::GetFirst( this ); | ||||||
1140 | if( pFrm ) | ||||||
1141 | pFrm->GetSlotState( nWh, nullptr, &rSet ); | ||||||
1142 | else | ||||||
1143 | rSet.DisableItem( nWh ); | ||||||
1144 | } | ||||||
1145 | break; | ||||||
1146 | |||||||
1147 | case SID_GETUNDOSTRINGS( 10000 + 923 ): | ||||||
1148 | case SID_GETREDOSTRINGS( 10000 + 924 ): | ||||||
1149 | { | ||||||
1150 | SfxUndoManager* pTmpUndoMgr = GetUndoManager(); | ||||||
1151 | if( pTmpUndoMgr ) | ||||||
1152 | { | ||||||
1153 | OUString(SfxUndoManager::*fnGetComment)( size_t, bool const ) const; | ||||||
1154 | |||||||
1155 | size_t nCount; | ||||||
1156 | if( SID_GETUNDOSTRINGS( 10000 + 923 ) == nWh ) | ||||||
1157 | { | ||||||
1158 | nCount = pTmpUndoMgr->GetUndoActionCount(); | ||||||
1159 | fnGetComment = &SfxUndoManager::GetUndoActionComment; | ||||||
1160 | } | ||||||
1161 | else | ||||||
1162 | { | ||||||
1163 | nCount = pTmpUndoMgr->GetRedoActionCount(); | ||||||
1164 | fnGetComment = &SfxUndoManager::GetRedoActionComment; | ||||||
1165 | } | ||||||
1166 | if (nCount) | ||||||
1167 | { | ||||||
1168 | OUStringBuffer aBuf; | ||||||
1169 | for (size_t n = 0; n < nCount; ++n) | ||||||
1170 | { | ||||||
1171 | aBuf.append((pTmpUndoMgr->*fnGetComment)( n, SfxUndoManager::TopLevel )); | ||||||
1172 | aBuf.append('\n'); | ||||||
1173 | } | ||||||
1174 | |||||||
1175 | SfxStringListItem aItem( nWh ); | ||||||
1176 | aItem.SetString( aBuf.makeStringAndClear() ); | ||||||
1177 | rSet.Put( aItem ); | ||||||
1178 | } | ||||||
1179 | } | ||||||
1180 | else | ||||||
1181 | rSet.DisableItem( nWh ); | ||||||
1182 | } | ||||||
1183 | break; | ||||||
1184 | } | ||||||
1185 | } | ||||||
1186 | } | ||||||
1187 | |||||||
1188 | |||||||
1189 | SfxUndoManager *SmDocShell::GetUndoManager() | ||||||
1190 | { | ||||||
1191 | if (!mpEditEngine) | ||||||
1192 | GetEditEngine(); | ||||||
1193 | return &mpEditEngine->GetUndoManager(); | ||||||
1194 | } | ||||||
1195 | |||||||
1196 | |||||||
1197 | void SmDocShell::SaveSymbols() | ||||||
1198 | { | ||||||
1199 | SmModule *pp = SM_MOD()( static_cast<SmModule*>(SfxApplication::GetModule(SfxToolsModule ::Math)) ); | ||||||
1200 | pp->GetSymbolManager().Save(); | ||||||
1201 | } | ||||||
1202 | |||||||
1203 | |||||||
1204 | void SmDocShell::Draw(OutputDevice *pDevice, | ||||||
1205 | const JobSetup &, | ||||||
1206 | sal_uInt16 /*nAspect*/) | ||||||
1207 | { | ||||||
1208 | pDevice->IntersectClipRegion(GetVisArea()); | ||||||
1209 | Point atmppoint; | ||||||
1210 | DrawFormula(*pDevice, atmppoint); | ||||||
| |||||||
1211 | } | ||||||
1212 | |||||||
1213 | SfxItemPool& SmDocShell::GetPool() | ||||||
1214 | { | ||||||
1215 | return SfxGetpApp()->GetPool(); | ||||||
1216 | } | ||||||
1217 | |||||||
1218 | void SmDocShell::SetVisArea(const tools::Rectangle & rVisArea) | ||||||
1219 | { | ||||||
1220 | tools::Rectangle aNewRect(rVisArea); | ||||||
1221 | |||||||
1222 | aNewRect.SetPos(Point()); | ||||||
1223 | |||||||
1224 | if (aNewRect.IsWidthEmpty()) | ||||||
1225 | aNewRect.SetRight( 2000 ); | ||||||
1226 | if (aNewRect.IsHeightEmpty()) | ||||||
1227 | aNewRect.SetBottom( 1000 ); | ||||||
1228 | |||||||
1229 | bool bIsEnabled = IsEnableSetModified(); | ||||||
1230 | if ( bIsEnabled ) | ||||||
1231 | EnableSetModified( false ); | ||||||
1232 | |||||||
1233 | //TODO/LATER: it's unclear how this interacts with the SFX code | ||||||
1234 | // If outplace editing, then don't resize the OutplaceWindow. But the | ||||||
1235 | // ObjectShell has to resize. | ||||||
1236 | bool bUnLockFrame; | ||||||
1237 | if( GetCreateMode() == SfxObjectCreateMode::EMBEDDED && !IsInPlaceActive() && GetFrame() ) | ||||||
1238 | { | ||||||
1239 | GetFrame()->LockAdjustPosSizePixel(); | ||||||
1240 | bUnLockFrame = true; | ||||||
1241 | } | ||||||
1242 | else | ||||||
1243 | bUnLockFrame = false; | ||||||
1244 | |||||||
1245 | SfxObjectShell::SetVisArea( aNewRect ); | ||||||
1246 | |||||||
1247 | if( bUnLockFrame ) | ||||||
1248 | GetFrame()->UnlockAdjustPosSizePixel(); | ||||||
1249 | |||||||
1250 | if ( bIsEnabled ) | ||||||
1251 | EnableSetModified( bIsEnabled ); | ||||||
1252 | } | ||||||
1253 | |||||||
1254 | |||||||
1255 | void SmDocShell::FillClass(SvGlobalName* pClassName, | ||||||
1256 | SotClipboardFormatId* pFormat, | ||||||
1257 | OUString* pFullTypeName, | ||||||
1258 | sal_Int32 nFileFormat, | ||||||
1259 | bool bTemplate /* = false */) const | ||||||
1260 | { | ||||||
1261 | if (nFileFormat == SOFFICE_FILEFORMAT_606200 ) | ||||||
1262 | { | ||||||
1263 | *pClassName = SvGlobalName(SO3_SM_CLASSID_600x078B7ABA, 0x54FC, 0x457F, 0x85, 0x51, 0x61, 0x47, 0xE7, 0x76 , 0xA9, 0x97); | ||||||
1264 | *pFormat = SotClipboardFormatId::STARMATH_60; | ||||||
1265 | *pFullTypeName = SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENTreinterpret_cast<char const *>("STR_MATH_DOCUMENT_FULLTYPE_CURRENT" "\004" u8"%PRODUCTNAME %PRODUCTVERSION Formula")); | ||||||
1266 | } | ||||||
1267 | else if (nFileFormat == SOFFICE_FILEFORMAT_86800 ) | ||||||
1268 | { | ||||||
1269 | *pClassName = SvGlobalName(SO3_SM_CLASSID_600x078B7ABA, 0x54FC, 0x457F, 0x85, 0x51, 0x61, 0x47, 0xE7, 0x76 , 0xA9, 0x97); | ||||||
1270 | *pFormat = bTemplate ? SotClipboardFormatId::STARMATH_8_TEMPLATE : SotClipboardFormatId::STARMATH_8; | ||||||
1271 | *pFullTypeName = SmResId(STR_MATH_DOCUMENT_FULLTYPE_CURRENTreinterpret_cast<char const *>("STR_MATH_DOCUMENT_FULLTYPE_CURRENT" "\004" u8"%PRODUCTNAME %PRODUCTVERSION Formula")); | ||||||
1272 | } | ||||||
1273 | } | ||||||
1274 | |||||||
1275 | void SmDocShell::SetModified(bool bModified) | ||||||
1276 | { | ||||||
1277 | if( IsEnableSetModified() ) | ||||||
1278 | { | ||||||
1279 | SfxObjectShell::SetModified( bModified ); | ||||||
1280 | Broadcast(SfxHint(SfxHintId::DocChanged)); | ||||||
1281 | } | ||||||
1282 | } | ||||||
1283 | |||||||
1284 | bool SmDocShell::WriteAsMathType3( SfxMedium& rMedium ) | ||||||
1285 | { | ||||||
1286 | OUStringBuffer aTextAsBuffer(maText); | ||||||
1287 | MathType aEquation(aTextAsBuffer, mpTree.get()); | ||||||
1288 | return aEquation.ConvertFromStarMath( rMedium ); | ||||||
1289 | } | ||||||
1290 | |||||||
1291 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||||||||
2 | /* | ||||||||||||
3 | * This file is part of the LibreOffice project. | ||||||||||||
4 | * | ||||||||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||||||||
8 | * | ||||||||||||
9 | * This file incorporates work covered by the following license notice: | ||||||||||||
10 | * | ||||||||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||||||||
13 | * with this work for additional information regarding copyright | ||||||||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||||||||
18 | */ | ||||||||||||
19 | |||||||||||||
20 | #ifndef INCLUDED_RTL_REF_HXX | ||||||||||||
21 | #define INCLUDED_RTL_REF_HXX | ||||||||||||
22 | |||||||||||||
23 | #include "sal/config.h" | ||||||||||||
24 | |||||||||||||
25 | #include <cassert> | ||||||||||||
26 | #include <cstddef> | ||||||||||||
27 | #include <functional> | ||||||||||||
28 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
29 | #include <type_traits> | ||||||||||||
30 | #endif | ||||||||||||
31 | |||||||||||||
32 | #include "sal/types.h" | ||||||||||||
33 | |||||||||||||
34 | namespace rtl | ||||||||||||
35 | { | ||||||||||||
36 | |||||||||||||
37 | /** Template reference class for reference type. | ||||||||||||
38 | */ | ||||||||||||
39 | template <class reference_type> | ||||||||||||
40 | class Reference | ||||||||||||
41 | { | ||||||||||||
42 | /** The <b>reference_type</b> body pointer. | ||||||||||||
43 | */ | ||||||||||||
44 | reference_type * m_pBody; | ||||||||||||
45 | |||||||||||||
46 | |||||||||||||
47 | public: | ||||||||||||
48 | /** Constructor... | ||||||||||||
49 | */ | ||||||||||||
50 | Reference() | ||||||||||||
51 | : m_pBody (NULL__null) | ||||||||||||
52 | {} | ||||||||||||
53 | |||||||||||||
54 | |||||||||||||
55 | /** Constructor... | ||||||||||||
56 | */ | ||||||||||||
57 | Reference (reference_type * pBody, __sal_NoAcquire) | ||||||||||||
58 | : m_pBody (pBody) | ||||||||||||
59 | { | ||||||||||||
60 | } | ||||||||||||
61 | |||||||||||||
62 | /** Constructor... | ||||||||||||
63 | */ | ||||||||||||
64 | Reference (reference_type * pBody) | ||||||||||||
65 | : m_pBody (pBody) | ||||||||||||
66 | { | ||||||||||||
67 | if (m_pBody) | ||||||||||||
68 | m_pBody->acquire(); | ||||||||||||
69 | } | ||||||||||||
70 | |||||||||||||
71 | /** Copy constructor... | ||||||||||||
72 | */ | ||||||||||||
73 | Reference (const Reference<reference_type> & handle) | ||||||||||||
74 | : m_pBody (handle.m_pBody) | ||||||||||||
75 | { | ||||||||||||
76 | if (m_pBody) | ||||||||||||
77 | m_pBody->acquire(); | ||||||||||||
78 | } | ||||||||||||
79 | |||||||||||||
80 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
81 | /** Move constructor... | ||||||||||||
82 | */ | ||||||||||||
83 | Reference (Reference<reference_type> && handle) noexcept | ||||||||||||
84 | : m_pBody (handle.m_pBody) | ||||||||||||
85 | { | ||||||||||||
86 | handle.m_pBody = nullptr; | ||||||||||||
87 | } | ||||||||||||
88 | #endif | ||||||||||||
89 | |||||||||||||
90 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
91 | /** Up-casting conversion constructor: Copies interface reference. | ||||||||||||
92 | |||||||||||||
93 | Does not work for up-casts to ambiguous bases. | ||||||||||||
94 | |||||||||||||
95 | @param rRef another reference | ||||||||||||
96 | */ | ||||||||||||
97 | template< class derived_type > | ||||||||||||
98 | inline Reference( | ||||||||||||
99 | const Reference< derived_type > & rRef, | ||||||||||||
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) | ||||||||||||
101 | : m_pBody (rRef.get()) | ||||||||||||
102 | { | ||||||||||||
103 | if (m_pBody) | ||||||||||||
104 | m_pBody->acquire(); | ||||||||||||
105 | } | ||||||||||||
106 | #endif | ||||||||||||
107 | |||||||||||||
108 | /** Destructor... | ||||||||||||
109 | */ | ||||||||||||
110 | ~Reference() COVERITY_NOEXCEPT_FALSE | ||||||||||||
111 | { | ||||||||||||
112 | if (m_pBody
| ||||||||||||
113 | m_pBody->release(); | ||||||||||||
| |||||||||||||
114 | } | ||||||||||||
115 | |||||||||||||
116 | /** Set... | ||||||||||||
117 | Similar to assignment. | ||||||||||||
118 | */ | ||||||||||||
119 | Reference<reference_type> & | ||||||||||||
120 | SAL_CALL set (reference_type * pBody) | ||||||||||||
121 | { | ||||||||||||
122 | if (pBody) | ||||||||||||
123 | pBody->acquire(); | ||||||||||||
124 | reference_type * const pOld = m_pBody; | ||||||||||||
125 | m_pBody = pBody; | ||||||||||||
126 | if (pOld) | ||||||||||||
127 | pOld->release(); | ||||||||||||
128 | return *this; | ||||||||||||
129 | } | ||||||||||||
130 | |||||||||||||
131 | /** Assignment. | ||||||||||||
132 | Unbinds this instance from its body (if bound) and | ||||||||||||
133 | bind it to the body represented by the handle. | ||||||||||||
134 | */ | ||||||||||||
135 | Reference<reference_type> & | ||||||||||||
136 | SAL_CALL operator= (const Reference<reference_type> & handle) | ||||||||||||
137 | { | ||||||||||||
138 | return set( handle.m_pBody ); | ||||||||||||
139 | } | ||||||||||||
140 | |||||||||||||
141 | #ifdef LIBO_INTERNAL_ONLY1 | ||||||||||||
142 | /** Assignment. | ||||||||||||
143 | * Unbinds this instance from its body (if bound), | ||||||||||||
144 | * bind it to the body represented by the handle, and | ||||||||||||
145 | * set the body represented by the handle to nullptr. | ||||||||||||
146 | */ | ||||||||||||
147 | Reference<reference_type> & | ||||||||||||
148 | operator= (Reference<reference_type> && handle) | ||||||||||||
149 | { | ||||||||||||
150 | // self-movement guts ourself | ||||||||||||
151 | if (m_pBody) | ||||||||||||
152 | m_pBody->release(); | ||||||||||||
153 | m_pBody = handle.m_pBody; | ||||||||||||
154 | handle.m_pBody = nullptr; | ||||||||||||
155 | return *this; | ||||||||||||
156 | } | ||||||||||||
157 | #endif | ||||||||||||
158 | |||||||||||||
159 | /** Assignment... | ||||||||||||
160 | */ | ||||||||||||
161 | Reference<reference_type> & | ||||||||||||
162 | SAL_CALL operator= (reference_type * pBody) | ||||||||||||
163 | { | ||||||||||||
164 | return set( pBody ); | ||||||||||||
165 | } | ||||||||||||
166 | |||||||||||||
167 | /** Unbind the body from this handle. | ||||||||||||
168 | Note that for a handle representing a large body, | ||||||||||||
169 | "handle.clear().set(new body());" _might_ | ||||||||||||
170 | perform a little bit better than "handle.set(new body());", | ||||||||||||
171 | since in the second case two large objects exist in memory | ||||||||||||
172 | (the old body and the new body). | ||||||||||||
173 | */ | ||||||||||||
174 | Reference<reference_type> & SAL_CALL clear() | ||||||||||||
175 | { | ||||||||||||
176 | if (m_pBody) | ||||||||||||
177 | { | ||||||||||||
178 | reference_type * const pOld = m_pBody; | ||||||||||||
179 | m_pBody = NULL__null; | ||||||||||||
180 | pOld->release(); | ||||||||||||
181 | } | ||||||||||||
182 | return *this; | ||||||||||||
183 | } | ||||||||||||
184 | |||||||||||||
185 | |||||||||||||
186 | /** Get the body. Can be used instead of operator->(). | ||||||||||||
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() | ||||||||||||
188 | are the same. | ||||||||||||
189 | */ | ||||||||||||
190 | reference_type * SAL_CALL get() const | ||||||||||||
191 | { | ||||||||||||
192 | return m_pBody; | ||||||||||||
193 | } | ||||||||||||
194 | |||||||||||||
195 | |||||||||||||
196 | /** Probably most common used: handle->someBodyOp(). | ||||||||||||
197 | */ | ||||||||||||
198 | reference_type * SAL_CALL operator->() const | ||||||||||||
199 | { | ||||||||||||
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
201 | return m_pBody; | ||||||||||||
202 | } | ||||||||||||
203 | |||||||||||||
204 | |||||||||||||
205 | /** Allows (*handle).someBodyOp(). | ||||||||||||
206 | */ | ||||||||||||
207 | reference_type & SAL_CALL operator*() const | ||||||||||||
208 | { | ||||||||||||
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
210 | return *m_pBody; | ||||||||||||
211 | } | ||||||||||||
212 | |||||||||||||
213 | |||||||||||||
214 | /** Returns True if the handle does point to a valid body. | ||||||||||||
215 | */ | ||||||||||||
216 | bool SAL_CALL is() const | ||||||||||||
217 | { | ||||||||||||
218 | return (m_pBody != NULL__null); | ||||||||||||
219 | } | ||||||||||||
220 | |||||||||||||
221 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
222 | /** Returns True if the handle does point to a valid body. | ||||||||||||
223 | */ | ||||||||||||
224 | explicit operator bool() const | ||||||||||||
225 | { | ||||||||||||
226 | return is(); | ||||||||||||
227 | } | ||||||||||||
228 | #endif | ||||||||||||
229 | |||||||||||||
230 | /** Returns True if this points to pBody. | ||||||||||||
231 | */ | ||||||||||||
232 | bool SAL_CALL operator== (const reference_type * pBody) const | ||||||||||||
233 | { | ||||||||||||
234 | return (m_pBody == pBody); | ||||||||||||
235 | } | ||||||||||||
236 | |||||||||||||
237 | |||||||||||||
238 | /** Returns True if handle points to the same body. | ||||||||||||
239 | */ | ||||||||||||
240 | bool | ||||||||||||
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const | ||||||||||||
242 | { | ||||||||||||
243 | return (m_pBody == handle.m_pBody); | ||||||||||||
244 | } | ||||||||||||
245 | |||||||||||||
246 | |||||||||||||
247 | /** Needed to place References into STL collection. | ||||||||||||
248 | */ | ||||||||||||
249 | bool | ||||||||||||
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const | ||||||||||||
251 | { | ||||||||||||
252 | return (m_pBody != handle.m_pBody); | ||||||||||||
253 | } | ||||||||||||
254 | |||||||||||||
255 | |||||||||||||
256 | /** Needed to place References into STL collection. | ||||||||||||
257 | */ | ||||||||||||
258 | bool | ||||||||||||
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const | ||||||||||||
260 | { | ||||||||||||
261 | return (m_pBody < handle.m_pBody); | ||||||||||||
262 | } | ||||||||||||
263 | |||||||||||||
264 | |||||||||||||
265 | /** Needed to place References into STL collection. | ||||||||||||
266 | */ | ||||||||||||
267 | bool | ||||||||||||
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const | ||||||||||||
269 | { | ||||||||||||
270 | return (m_pBody > handle.m_pBody); | ||||||||||||
271 | } | ||||||||||||
272 | }; | ||||||||||||
273 | |||||||||||||
274 | } // namespace rtl | ||||||||||||
275 | |||||||||||||
276 | #if defined LIBO_INTERNAL_ONLY1 | ||||||||||||
277 | namespace std | ||||||||||||
278 | { | ||||||||||||
279 | |||||||||||||
280 | /// @cond INTERNAL | ||||||||||||
281 | /** | ||||||||||||
282 | Make rtl::Reference hashable by default for use in STL containers. | ||||||||||||
283 | |||||||||||||
284 | @since LibreOffice 6.3 | ||||||||||||
285 | */ | ||||||||||||
286 | template<typename T> | ||||||||||||
287 | struct hash<::rtl::Reference<T>> | ||||||||||||
288 | { | ||||||||||||
289 | std::size_t operator()(::rtl::Reference<T> const & s) const | ||||||||||||
290 | { return std::size_t(s.get()); } | ||||||||||||
291 | }; | ||||||||||||
292 | /// @endcond | ||||||||||||
293 | |||||||||||||
294 | } | ||||||||||||
295 | |||||||||||||
296 | #endif | ||||||||||||
297 | |||||||||||||
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ | ||||||||||||
299 | |||||||||||||
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |