Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / sc / source / ui / view / viewutil.cxx
blobd5ad7829edc95614dc5ef3b5fa9d5beb332e5780
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 .
21 #include "scitems.hxx"
22 #include <sfx2/bindings.hxx>
23 #include <sfx2/viewsh.hxx>
24 #include <sfx2/dispatch.hxx>
25 #include <editeng/fontitem.hxx>
26 #include <editeng/langitem.hxx>
27 #include <editeng/scripttypeitem.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/msgbox.hxx>
34 #include <vcl/wrkwin.hxx>
35 #include <sfx2/request.hxx>
36 #include <sfx2/objsh.hxx>
37 #include <svl/stritem.hxx>
38 #include <svl/eitem.hxx>
40 #include <com/sun/star/i18n/TransliterationModules.hpp>
41 #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
44 #include "viewutil.hxx"
45 #include "global.hxx"
46 #include "chgtrack.hxx"
47 #include "chgviset.hxx"
48 #include "markdata.hxx"
50 #include <svx/svxdlg.hxx>
51 #include <svx/dialogs.hrc>
52 // STATIC DATA -----------------------------------------------------------
54 //==================================================================
56 void ScViewUtil::PutItemScript( SfxItemSet& rShellSet, const SfxItemSet& rCoreSet,
57 sal_uInt16 nWhichId, sal_uInt16 nScript )
59 // take the effective item from rCoreSet according to nScript
60 // and put in rShellSet under the (base) nWhichId
62 SfxItemPool& rPool = *rShellSet.GetPool();
63 SvxScriptSetItem aSetItem( rPool.GetSlotId(nWhichId), rPool );
64 // use PutExtended with eDefaultAs = SFX_ITEM_SET, so defaults from rCoreSet
65 // (document pool) are read and put into rShellSet (MessagePool)
66 aSetItem.GetItemSet().PutExtended( rCoreSet, SFX_ITEM_DONTCARE, SFX_ITEM_SET );
67 const SfxPoolItem* pI = aSetItem.GetItemOfScript( nScript );
68 if (pI)
69 rShellSet.Put( *pI, nWhichId );
70 else
71 rShellSet.InvalidateItem( nWhichId );
74 sal_uInt16 ScViewUtil::GetEffLanguage( ScDocument* pDoc, const ScAddress& rPos )
76 // used for thesaurus
78 sal_uInt8 nScript = pDoc->GetScriptType( rPos.Col(), rPos.Row(), rPos.Tab() );
79 sal_uInt16 nWhich = ( nScript == SCRIPTTYPE_ASIAN ) ? ATTR_CJK_FONT_LANGUAGE :
80 ( ( nScript == SCRIPTTYPE_COMPLEX ) ? ATTR_CTL_FONT_LANGUAGE : ATTR_FONT_LANGUAGE );
81 const SfxPoolItem* pItem = pDoc->GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), nWhich);
82 SvxLanguageItem* pLangIt = PTR_CAST( SvxLanguageItem, pItem );
83 LanguageType eLnge;
84 if (pLangIt)
86 eLnge = (LanguageType) pLangIt->GetValue();
87 if (eLnge == LANGUAGE_DONTKNOW) //! can this happen?
89 LanguageType eLatin, eCjk, eCtl;
90 pDoc->GetLanguage( eLatin, eCjk, eCtl );
91 eLnge = ( nScript == SCRIPTTYPE_ASIAN ) ? eCjk :
92 ( ( nScript == SCRIPTTYPE_COMPLEX ) ? eCtl : eLatin );
95 else
96 eLnge = LANGUAGE_ENGLISH_US;
97 if ( eLnge == LANGUAGE_SYSTEM )
98 eLnge = Application::GetSettings().GetLanguageTag().getLanguageType(); // never use SYSTEM for spelling
100 return eLnge;
103 sal_Int32 ScViewUtil::GetTransliterationType( sal_uInt16 nSlotID )
105 sal_Int32 nType = 0;
106 switch ( nSlotID )
108 case SID_TRANSLITERATE_SENTENCE_CASE:
109 nType = com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE;
110 break;
111 case SID_TRANSLITERATE_TITLE_CASE:
112 nType = com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE;
113 break;
114 case SID_TRANSLITERATE_TOGGLE_CASE:
115 nType = com::sun::star::i18n::TransliterationModulesExtra::TOGGLE_CASE;
116 break;
117 case SID_TRANSLITERATE_UPPER:
118 nType = com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE;
119 break;
120 case SID_TRANSLITERATE_LOWER:
121 nType = com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE;
122 break;
123 case SID_TRANSLITERATE_HALFWIDTH:
124 nType = com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH;
125 break;
126 case SID_TRANSLITERATE_FULLWIDTH:
127 nType = com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH;
128 break;
129 case SID_TRANSLITERATE_HIRAGANA:
130 nType = com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA;
131 break;
132 case SID_TRANSLITERATE_KATAGANA:
133 nType = com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA;
134 break;
136 return nType;
139 sal_Bool ScViewUtil::IsActionShown( const ScChangeAction& rAction,
140 const ScChangeViewSettings& rSettings,
141 ScDocument& rDocument )
143 // abgelehnte werden durch eine invertierende akzeptierte Action dargestellt,
144 // die Reihenfolge von ShowRejected/ShowAccepted ist deswegen wichtig
146 if ( !rSettings.IsShowRejected() && rAction.IsRejecting() )
147 return false;
149 if ( !rSettings.IsShowAccepted() && rAction.IsAccepted() && !rAction.IsRejecting() )
150 return false;
152 if ( rSettings.HasAuthor() )
154 if ( rSettings.IsEveryoneButMe() )
156 // GetUser() am ChangeTrack ist der aktuelle Benutzer
157 ScChangeTrack* pTrack = rDocument.GetChangeTrack();
158 if ( !pTrack || rAction.GetUser().equals(pTrack->GetUser()) )
159 return false;
161 else if ( !rAction.GetUser().equals(rSettings.GetTheAuthorToShow()) )
162 return false;
165 if ( rSettings.HasComment() )
167 rtl::OUStringBuffer aBuf(rAction.GetComment());
168 aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(" ("));
169 rtl::OUString aTmp;
170 rAction.GetDescription(aTmp, &rDocument);
171 aBuf.append(aTmp);
172 aBuf.append(sal_Unicode(')'));
173 rtl::OUString aComStr = aBuf.makeStringAndClear();
175 if(!rSettings.IsValidComment(&aComStr))
176 return false;
179 if ( rSettings.HasRange() )
180 if ( !rSettings.GetTheRangeList().Intersects( rAction.GetBigRange().MakeRange() ) )
181 return false;
183 if ( rSettings.HasDate() && rSettings.GetTheDateMode() != SCDM_NO_DATEMODE )
185 DateTime aDateTime = rAction.GetDateTime();
186 const DateTime& rFirst = rSettings.GetTheFirstDateTime();
187 const DateTime& rLast = rSettings.GetTheLastDateTime();
188 switch ( rSettings.GetTheDateMode() )
189 { // korrespondiert mit ScHighlightChgDlg::OKBtnHdl
190 case SCDM_DATE_BEFORE:
191 if ( aDateTime > rFirst )
192 return false;
193 break;
195 case SCDM_DATE_SINCE:
196 if ( aDateTime < rFirst )
197 return false;
198 break;
200 case SCDM_DATE_EQUAL:
201 case SCDM_DATE_BETWEEN:
202 if ( aDateTime < rFirst || aDateTime > rLast )
203 return false;
204 break;
206 case SCDM_DATE_NOTEQUAL:
207 if ( aDateTime >= rFirst && aDateTime <= rLast )
208 return false;
209 break;
211 case SCDM_DATE_SAVE:
213 ScChangeTrack* pTrack = rDocument.GetChangeTrack();
214 if ( !pTrack || pTrack->GetLastSavedActionNumber() >=
215 rAction.GetActionNumber() )
216 return false;
218 break;
220 default:
222 // added to avoid warnings
227 if ( rSettings.HasActionRange() )
229 sal_uLong nAction = rAction.GetActionNumber();
230 sal_uLong nFirstAction;
231 sal_uLong nLastAction;
232 rSettings.GetTheActionRange( nFirstAction, nLastAction );
233 if ( nAction < nFirstAction || nAction > nLastAction )
235 return false;
239 return sal_True;
242 void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc )
244 rMark.MarkToMulti();
246 ScRange aMultiArea;
247 rMark.GetMultiMarkArea( aMultiArea );
248 SCCOL nStartCol = aMultiArea.aStart.Col();
249 SCROW nStartRow = aMultiArea.aStart.Row();
250 SCCOL nEndCol = aMultiArea.aEnd.Col();
251 SCROW nEndRow = aMultiArea.aEnd.Row();
253 bool bChanged = false;
254 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
255 for (; itr != itrEnd; ++itr)
257 SCTAB nTab = *itr;
258 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
260 SCROW nLastRow = nRow;
261 if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow))
263 // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns
264 // (visible in repaint for indentation)
265 rMark.SetMultiMarkArea(
266 ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false);
267 bChanged = true;
268 nRow = nLastRow;
273 if ( bChanged && !rMark.HasAnyMultiMarks() )
274 rMark.ResetMark();
276 rMark.MarkToSimple();
280 bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows )
282 SCTAB nTab = rRange.aStart.Tab();
283 bool bOneTabOnly = (nTab == rRange.aEnd.Tab());
284 // Always fit the range on its first sheet.
285 OSL_ENSURE( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet");
286 SCROW nStartRow = rRange.aStart.Row();
287 SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab);
288 if (ValidRow(nLastRow))
289 rRange.aEnd.SetRow(nLastRow);
290 SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab);
291 return static_cast<size_t>(nCount) == nRows && bOneTabOnly;
294 bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc )
296 SCROW nStartRow = rRange.aStart.Row();
297 SCROW nEndRow = rRange.aEnd.Row();
298 for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++)
300 if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab))
301 return true;
304 return false;
307 void ScViewUtil::HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, sal_uInt16 nSlotId )
309 SvtCJKOptions aCJKOptions;
310 SvtCTLOptions aCTLOptions;
311 bool bEnabled = true;
313 switch( nSlotId )
315 case SID_CHINESE_CONVERSION:
316 case SID_HANGUL_HANJA_CONVERSION:
317 bEnabled = aCJKOptions.IsAnyEnabled();
318 break;
320 case SID_TRANSLITERATE_HALFWIDTH:
321 case SID_TRANSLITERATE_FULLWIDTH:
322 case SID_TRANSLITERATE_HIRAGANA:
323 case SID_TRANSLITERATE_KATAGANA:
324 bEnabled = aCJKOptions.IsChangeCaseMapEnabled();
325 break;
327 case SID_INSERT_RLM:
328 case SID_INSERT_LRM:
329 case SID_INSERT_ZWNBSP:
330 case SID_INSERT_ZWSP:
331 bEnabled = aCTLOptions.IsCTLFontEnabled();
332 break;
334 default:
335 OSL_FAIL( "ScViewUtil::HideDisabledSlot - unknown slot ID" );
336 return;
339 rBindings.SetVisibleState( nSlotId, bEnabled );
340 if( !bEnabled )
341 rSet.DisableItem( nSlotId );
344 //==================================================================
346 sal_Bool ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont,
347 SfxViewFrame& rFrame,
348 SvxFontItem& rNewFont,
349 String& rString )
351 sal_Bool bRet = false;
352 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
353 if(pFact)
355 SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() );
356 aSet.Put( SfxBoolItem( FN_PARAM_1, false ) );
357 aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) );
358 SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP );
359 if ( pDlg->Execute() == RET_OK )
361 SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, false );
362 SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pFontItem, SvxFontItem, SID_ATTR_CHAR_FONT, false );
363 if ( pItem )
364 rString = pItem->GetValue();
365 if ( pFontItem )
366 rNewFont = SvxFontItem( pFontItem->GetFamily(), pFontItem->GetFamilyName(), pFontItem->GetStyleName(), pFontItem->GetPitch(), pFontItem->GetCharSet(), rNewFont.Which() );
367 bRet = sal_True;
369 delete pDlg;
371 return bRet;
374 bool ScViewUtil::IsFullScreen( SfxViewShell& rViewShell )
376 SfxBindings& rBindings = rViewShell.GetViewFrame()->GetBindings();
377 SfxPoolItem* pItem = 0;
378 bool bIsFullScreen = false;
380 if (rBindings.QueryState( SID_WIN_FULLSCREEN, pItem ) >= SFX_ITEM_DEFAULT)
381 bIsFullScreen = static_cast< SfxBoolItem* >( pItem )->GetValue();
382 return bIsFullScreen;
385 void ScViewUtil::SetFullScreen( SfxViewShell& rViewShell, bool bSet )
387 if( IsFullScreen( rViewShell ) != bSet )
389 SfxBoolItem aItem( SID_WIN_FULLSCREEN, bSet );
390 rViewShell.GetDispatcher()->Execute( SID_WIN_FULLSCREEN, SFX_CALLMODE_RECORD, &aItem, 0L );
394 //------------------------------------------------------------------
396 ScUpdateRect::ScUpdateRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
398 PutInOrder( nX1, nX2 );
399 PutInOrder( nY1, nY2 );
401 nOldStartX = nX1;
402 nOldStartY = nY1;
403 nOldEndX = nX2;
404 nOldEndY = nY2;
407 void ScUpdateRect::SetNew( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 )
409 PutInOrder( nX1, nX2 );
410 PutInOrder( nY1, nY2 );
412 nNewStartX = nX1;
413 nNewStartY = nY1;
414 nNewEndX = nX2;
415 nNewEndY = nY2;
418 sal_Bool ScUpdateRect::GetDiff( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 )
420 if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX &&
421 nNewStartY == nOldStartY && nNewEndY == nOldEndY )
423 rX1 = nNewStartX;
424 rY1 = nNewStartY;
425 rX2 = nNewStartX;
426 rY2 = nNewStartY;
427 return false;
430 rX1 = Min(nNewStartX,nOldStartX);
431 rY1 = Min(nNewStartY,nOldStartY);
432 rX2 = Max(nNewEndX,nOldEndX);
433 rY2 = Max(nNewEndY,nOldEndY);
435 if ( nNewStartX == nOldStartX && nNewEndX == nOldEndX )
437 if ( nNewStartY == nOldStartY )
439 rY1 = Min( nNewEndY, nOldEndY );
440 rY2 = Max( nNewEndY, nOldEndY );
442 else if ( nNewEndY == nOldEndY )
444 rY1 = Min( nNewStartY, nOldStartY );
445 rY2 = Max( nNewStartY, nOldStartY );
448 else if ( nNewStartY == nOldStartY && nNewEndY == nOldEndY )
450 if ( nNewStartX == nOldStartX )
452 rX1 = Min( nNewEndX, nOldEndX );
453 rX2 = Max( nNewEndX, nOldEndX );
455 else if ( nNewEndX == nOldEndX )
457 rX1 = Min( nNewStartX, nOldStartX );
458 rX2 = Max( nNewStartX, nOldStartX );
462 return sal_True;
465 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */