tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / viewutil.cxx
blob6ccf629c11a0e2c2b3939a8efaefe2036de4f209
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <scitems.hxx>
21 #include <sfx2/bindings.hxx>
22 #include <sfx2/viewsh.hxx>
23 #include <sfx2/dispatch.hxx>
24 #include <editeng/fontitem.hxx>
25 #include <editeng/langitem.hxx>
26 #include <editeng/scripttypeitem.hxx>
27 #include <i18nutil/transliteration.hxx>
28 #include <svl/itempool.hxx>
29 #include <svl/itemset.hxx>
30 #include <svl/cjkoptions.hxx>
31 #include <svl/ctloptions.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/settings.hxx>
34 #include <sfx2/objsh.hxx>
35 #include <sfx2/viewfrm.hxx>
36 #include <svl/eitem.hxx>
37 #include <osl/diagnose.h>
39 #include <viewutil.hxx>
40 #include <chgtrack.hxx>
41 #include <chgviset.hxx>
42 #include <markdata.hxx>
43 #include <document.hxx>
44 #include <tabvwsh.hxx>
46 #include <svx/svxdlg.hxx>
47 #include <svx/svxids.hrc>
48 #include <memory>
50 void ScViewUtil::PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet,
51 sal_uInt16 nWhichId, SvtScriptType nScript )
53 // take the effective item from rCoreSet according to nScript
54 // and put in rShellSet under the (base) nWhichId
56 SfxItemPool& rPool = *rShellSet.GetPool();
57 SvxScriptSetItem aSetItem( rPool.GetSlotId(nWhichId), rPool );
58 // use PutExtended with eDefaultAs = SfxItemState::SET, so defaults from rCoreSet
59 // (document pool) are read and put into rShellSet (MessagePool)
60 aSetItem.GetItemSet().PutExtended( rCoreSet, SfxItemState::INVALID, SfxItemState::SET );
61 const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
62 if (pI)
64 rShellSet.Put( pI->CloneSetWhich(nWhichId) );
66 else
67 rShellSet.InvalidateItem( nWhichId );
70 LanguageType ScViewUtil::GetEffLanguage( ScDocument& rDoc, const ScAddress& rPos )
72 // used for thesaurus
74 SvtScriptType nScript = rDoc.GetScriptType(rPos.Col(), rPos.Row(), rPos.Tab());
75 sal_uInt16 nWhich = ( nScript == SvtScriptType::ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
76 ( ( nScript == SvtScriptType::COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : ATTR_FONT_LANGUAGE );
77 const SfxPoolItem* pItem = rDoc.GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
78 const SvxLanguageItem* pLangIt = dynamic_cast<const SvxLanguageItem*>( pItem );
79 LanguageType eLnge;
80 if (pLangIt)
82 eLnge = pLangIt->GetValue();
83 if (eLnge == LANGUAGE_DONTKNOW) //! can this happen?
85 LanguageType eLatin, eCjk, eCtl;
86 rDoc.GetLanguage( eLatin, eCjk, eCtl );
87 eLnge = ( nScript == SvtScriptType::ASIAN ) ? eCjk :
88 ( ( nScript == SvtScriptType::COMPLEX ) ? eCtl : eLatin );
91 else
92 eLnge = LANGUAGE_ENGLISH_US;
93 if ( eLnge == LANGUAGE_SYSTEM )
94 eLnge = Application::GetSettings().GetLanguageTag().getLanguageType(); // never use SYSTEM for spelling
96 return eLnge;
99 TransliterationFlags ScViewUtil::GetTransliterationType( sal_uInt16 nSlotID )
101 TransliterationFlags nType = TransliterationFlags::NONE;
102 switch ( nSlotID )
104 case SID_TRANSLITERATE_SENTENCE_CASE:
105 nType = TransliterationFlags::SENTENCE_CASE;
106 break;
107 case SID_TRANSLITERATE_TITLE_CASE:
108 nType = TransliterationFlags::TITLE_CASE;
109 break;
110 case SID_TRANSLITERATE_TOGGLE_CASE:
111 nType = TransliterationFlags::TOGGLE_CASE;
112 break;
113 case SID_TRANSLITERATE_UPPER:
114 nType = TransliterationFlags::LOWERCASE_UPPERCASE;
115 break;
116 case SID_TRANSLITERATE_LOWER:
117 nType = TransliterationFlags::UPPERCASE_LOWERCASE;
118 break;
119 case SID_TRANSLITERATE_HALFWIDTH:
120 nType = TransliterationFlags::FULLWIDTH_HALFWIDTH;
121 break;
122 case SID_TRANSLITERATE_FULLWIDTH:
123 nType = TransliterationFlags::HALFWIDTH_FULLWIDTH;
124 break;
125 case SID_TRANSLITERATE_HIRAGANA:
126 nType = TransliterationFlags::KATAKANA_HIRAGANA;
127 break;
128 case SID_TRANSLITERATE_KATAKANA:
129 nType = TransliterationFlags::HIRAGANA_KATAKANA;
130 break;
132 return nType;
135 bool ScViewUtil::IsActionShown( const ScChangeAction& rAction,
136 const ScChangeViewSettings& rSettings,
137 ScDocument& rDocument )
139 // discarded are displayed as inverted accepted action, because of this
140 // order of ShowRejected/ShowAccepted is important
142 if ( !rSettings.IsShowRejected() && rAction.IsRejecting() )
143 return false;
145 if ( !rSettings.IsShowAccepted() && rAction.IsAccepted() && !rAction.IsRejecting() )
146 return false;
148 if ( rSettings.HasAuthor() && rAction.GetUser() != rSettings.GetTheAuthorToShow() )
149 return false;
151 if ( rSettings.HasComment() )
153 OUString aTmp = rAction.GetDescription(rDocument);
154 OUString aComStr = rAction.GetComment() + " (" + aTmp + ")";
156 if(!rSettings.IsValidComment(&aComStr))
157 return false;
160 if ( rSettings.HasRange() )
161 if ( !rSettings.GetTheRangeList().Intersects( rAction.GetBigRange().MakeRange( rDocument ) ) )
162 return false;
164 if (rSettings.HasDate() && rSettings.GetTheDateMode() != SvxRedlinDateMode::NONE)
166 DateTime aDateTime = rAction.GetDateTime();
167 const DateTime& rFirst = rSettings.GetTheFirstDateTime();
168 const DateTime& rLast = rSettings.GetTheLastDateTime();
169 switch ( rSettings.GetTheDateMode() )
170 { // corresponds with ScHighlightChgDlg::OKBtnHdl
171 case SvxRedlinDateMode::BEFORE:
172 if ( aDateTime > rFirst )
173 return false;
174 break;
176 case SvxRedlinDateMode::SINCE:
177 if ( aDateTime < rFirst )
178 return false;
179 break;
181 case SvxRedlinDateMode::EQUAL:
182 case SvxRedlinDateMode::BETWEEN:
183 if ( aDateTime < rFirst || aDateTime > rLast )
184 return false;
185 break;
187 case SvxRedlinDateMode::NOTEQUAL:
188 if ( aDateTime >= rFirst && aDateTime <= rLast )
189 return false;
190 break;
192 case SvxRedlinDateMode::SAVE:
194 ScChangeTrack* pTrack = rDocument.GetChangeTrack();
195 if ( !pTrack || pTrack->GetLastSavedActionNumber() >=
196 rAction.GetActionNumber() )
197 return false;
199 break;
201 default:
203 // added to avoid warnings
208 if ( rSettings.HasActionRange() )
210 sal_uLong nAction = rAction.GetActionNumber();
211 sal_uLong nFirstAction;
212 sal_uLong nLastAction;
213 rSettings.GetTheActionRange( nFirstAction, nLastAction );
214 if ( nAction < nFirstAction || nAction > nLastAction )
216 return false;
220 return true;
223 void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, const ScDocument& rDoc )
225 rMark.MarkToMulti();
227 const ScRange& aMultiArea = rMark.GetMultiMarkArea();
228 SCCOL nStartCol = aMultiArea.aStart.Col();
229 SCROW nStartRow = aMultiArea.aStart.Row();
230 SCCOL nEndCol = aMultiArea.aEnd.Col();
231 SCROW nEndRow = aMultiArea.aEnd.Row();
233 bool bChanged = false;
234 for (const SCTAB& nTab : rMark)
236 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
238 SCROW nLastRow = nRow;
239 if (rDoc.RowFiltered(nRow, nTab, nullptr, &nLastRow))
241 // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns
242 // (visible in repaint for indentation)
243 rMark.SetMultiMarkArea(
244 ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false);
245 bChanged = true;
246 nRow = nLastRow;
251 if ( bChanged && !rMark.HasAnyMultiMarks() )
252 rMark.ResetMark();
254 rMark.MarkToSimple();
257 bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, const ScDocument& rDoc, size_t nRows )
259 SCTAB nTab = rRange.aStart.Tab();
260 bool bOneTabOnly = (nTab == rRange.aEnd.Tab());
261 // Always fit the range on its first sheet.
262 OSL_ENSURE( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet");
263 SCROW nStartRow = rRange.aStart.Row();
264 SCROW nLastRow = rDoc.LastNonFilteredRow(nStartRow, rDoc.MaxRow(), nTab);
265 if (rDoc.ValidRow(nLastRow))
266 rRange.aEnd.SetRow(nLastRow);
267 SCROW nCount = rDoc.CountNonFilteredRows(nStartRow, rDoc.MaxRow(), nTab);
268 return static_cast<size_t>(nCount) == nRows && bOneTabOnly;
271 bool ScViewUtil::HasFiltered( const ScRange& rRange, const ScDocument& rDoc )
273 SCROW nStartRow = rRange.aStart.Row();
274 SCROW nEndRow = rRange.aEnd.Row();
275 for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++)
277 if (rDoc.HasFilteredRows(nStartRow, nEndRow, nTab))
278 return true;
281 return false;
284 void ScViewUtil::HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, sal_uInt16 nSlotId )
286 SvtCTLOptions aCTLOptions;
287 bool bEnabled = true;
289 switch( nSlotId )
291 case SID_CHINESE_CONVERSION:
292 case SID_HANGUL_HANJA_CONVERSION:
293 bEnabled = SvtCJKOptions::IsAnyEnabled();
294 break;
296 case SID_TRANSLITERATE_HALFWIDTH:
297 case SID_TRANSLITERATE_FULLWIDTH:
298 case SID_TRANSLITERATE_HIRAGANA:
299 case SID_TRANSLITERATE_KATAKANA:
300 bEnabled = SvtCJKOptions::IsChangeCaseMapEnabled();
301 break;
303 case SID_INSERT_RLM:
304 case SID_INSERT_LRM:
305 bEnabled = SvtCTLOptions::IsCTLFontEnabled();
306 break;
308 default:
309 OSL_FAIL( "ScViewUtil::HideDisabledSlot - unknown slot ID" );
310 return;
313 rBindings.SetVisibleState( nSlotId, bEnabled );
314 if( !bEnabled )
315 rSet.DisableItem( nSlotId );
318 void ScViewUtil::ExecuteCharMap(const SvxFontItem& rOldFont,
319 const ScTabViewShell& rShell)
321 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
322 SfxViewFrame& rFrame = rShell.GetViewFrame();
323 SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() );
324 aSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
325 aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhichIDFromSlotID( SID_ATTR_CHAR_FONT ) ) );
326 auto xFrame = rFrame.GetFrame().GetFrameInterface();
327 VclPtr<SfxAbstractDialog> pDlg(pFact->CreateCharMapDialog(rShell.GetFrameWeld(), aSet, xFrame));
328 pDlg->StartExecuteAsync(
329 [pDlg] (sal_Int32 /*nResult*/)->void
331 pDlg->disposeOnce();
336 bool ScViewUtil::IsFullScreen( const SfxViewShell& rViewShell )
338 SfxBindings& rBindings = rViewShell.GetViewFrame().GetBindings();
339 std::unique_ptr<SfxBoolItem> pItem;
340 bool bIsFullScreen = false;
342 if (rBindings.QueryState( SID_WIN_FULLSCREEN, pItem ) >= SfxItemState::DEFAULT)
343 bIsFullScreen = pItem->GetValue();
345 return bIsFullScreen;
348 void ScViewUtil::SetFullScreen( const SfxViewShell& rViewShell, bool bSet )
350 if( IsFullScreen( rViewShell ) != bSet )
352 SfxBoolItem aItem( SID_WIN_FULLSCREEN, bSet );
353 rViewShell.GetDispatcher()->ExecuteList(SID_WIN_FULLSCREEN,
354 SfxCallMode::RECORD, { &aItem });
358 ScUpdateRect::ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
359 : nNewStartX(0)
360 , nNewStartY(0)
361 , nNewEndX(0)
362 , nNewEndY(0)
364 PutInOrder( nX1, nX2 );
365 PutInOrder( nY1, nY2 );
367 nOldStartX = nX1;
368 nOldStartY = nY1;
369 nOldEndX = nX2;
370 nOldEndY = nY2;
373 void ScUpdateRect::SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
375 PutInOrder( nX1, nX2 );
376 PutInOrder( nY1, nY2 );
378 nNewStartX = nX1;
379 nNewStartY = nY1;
380 nNewEndX = nX2;
381 nNewEndY = nY2;
384 bool ScUpdateRect::GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
386 if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
387 nNewStartY == nOldStartY && nNewEndY == nOldEndY )
389 rX1 = nNewStartX;
390 rY1 = nNewStartY;
391 rX2 = nNewStartX;
392 rY2 = nNewStartY;
393 return false;
396 rX1 = std::min(nNewStartX,nOldStartX);
397 rY1 = std::min(nNewStartY,nOldStartY);
398 rX2 = std::max(nNewEndX,nOldEndX);
399 rY2 = std::max(nNewEndY,nOldEndY);
401 if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX )
403 if ( nNewStartY == nOldStartY )
405 rY1 = std::min( nNewEndY, nOldEndY );
406 rY2 = std::max( nNewEndY, nOldEndY );
408 else if ( nNewEndY == nOldEndY )
410 rY1 = std::min( nNewStartY, nOldStartY );
411 rY2 = std::max( nNewStartY, nOldStartY );
414 else if ( nNewStartY == nOldStartY && nNewEndY == nOldEndY )
416 if ( nNewStartX == nOldStartX )
418 rX1 = std::min( nNewEndX, nOldEndX );
419 rX2 = std::max( nNewEndX, nOldEndX );
421 else if ( nNewEndX == nOldEndX )
423 rX1 = std::min( nNewStartX, nOldStartX );
424 rX2 = std::max( nNewStartX, nOldStartX );
428 return true;
431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */