1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: viewutil.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
37 #include <tools/list.hxx>
38 #include "scitems.hxx"
39 #include <sfx2/bindings.hxx>
40 #include <sfx2/viewsh.hxx>
41 #include <sfx2/dispatch.hxx>
42 #include <svx/charmap.hxx>
43 #include <svx/fontitem.hxx>
44 #include <svx/langitem.hxx>
45 #include <svx/scripttypeitem.hxx>
46 #include <svtools/itempool.hxx>
47 #include <svtools/itemset.hxx>
48 #include <svtools/cjkoptions.hxx>
49 #include <svtools/ctloptions.hxx>
50 #include <vcl/svapp.hxx>
51 #include <vcl/msgbox.hxx>
52 #include <vcl/wrkwin.hxx>
53 #include <sfx2/request.hxx>
54 #include <sfx2/objsh.hxx>
55 #include <svtools/stritem.hxx>
56 #include <svtools/eitem.hxx>
58 #include <com/sun/star/i18n/TransliterationModules.hpp>
60 #include "viewutil.hxx"
62 #include "chgtrack.hxx"
63 #include "chgviset.hxx"
64 #include "markdata.hxx"
66 #include <svx/svxdlg.hxx> //CHINA001
67 #include <svx/dialogs.hrc> //CHINA001
68 // STATIC DATA -----------------------------------------------------------
70 //==================================================================
73 void ScViewUtil::PutItemScript( SfxItemSet
& rShellSet
, const SfxItemSet
& rCoreSet
,
74 USHORT nWhichId
, USHORT nScript
)
76 // take the effective item from rCoreSet according to nScript
77 // and put in rShellSet under the (base) nWhichId
79 SfxItemPool
& rPool
= *rShellSet
.GetPool();
80 SvxScriptSetItem
aSetItem( rPool
.GetSlotId(nWhichId
), rPool
);
81 // use PutExtended with eDefaultAs = SFX_ITEM_SET, so defaults from rCoreSet
82 // (document pool) are read and put into rShellSet (MessagePool)
83 aSetItem
.GetItemSet().PutExtended( rCoreSet
, SFX_ITEM_DONTCARE
, SFX_ITEM_SET
);
84 const SfxPoolItem
* pI
= aSetItem
.GetItemOfScript( nScript
);
86 rShellSet
.Put( *pI
, nWhichId
);
88 rShellSet
.InvalidateItem( nWhichId
);
92 USHORT
ScViewUtil::GetEffLanguage( ScDocument
* pDoc
, const ScAddress
& rPos
)
96 BYTE nScript
= pDoc
->GetScriptType( rPos
.Col(), rPos
.Row(), rPos
.Tab() );
97 USHORT nWhich
= ( nScript
== SCRIPTTYPE_ASIAN
) ? ATTR_CJK_FONT_LANGUAGE
:
98 ( ( nScript
== SCRIPTTYPE_COMPLEX
) ? ATTR_CTL_FONT_LANGUAGE
: ATTR_FONT_LANGUAGE
);
99 const SfxPoolItem
* pItem
= pDoc
->GetAttr( rPos
.Col(), rPos
.Row(), rPos
.Tab(), nWhich
);
100 SvxLanguageItem
* pLangIt
= PTR_CAST( SvxLanguageItem
, pItem
);
104 eLnge
= (LanguageType
) pLangIt
->GetValue();
105 if (eLnge
== LANGUAGE_DONTKNOW
) //! can this happen?
107 LanguageType eLatin
, eCjk
, eCtl
;
108 pDoc
->GetLanguage( eLatin
, eCjk
, eCtl
);
109 eLnge
= ( nScript
== SCRIPTTYPE_ASIAN
) ? eCjk
:
110 ( ( nScript
== SCRIPTTYPE_COMPLEX
) ? eCtl
: eLatin
);
114 eLnge
= LANGUAGE_ENGLISH_US
;
115 if ( eLnge
== LANGUAGE_SYSTEM
)
116 eLnge
= Application::GetSettings().GetLanguage(); // never use SYSTEM for spelling
122 sal_Int32
ScViewUtil::GetTransliterationType( USHORT nSlotID
)
127 case SID_TRANSLITERATE_UPPER
:
128 nType
= com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE
;
130 case SID_TRANSLITERATE_LOWER
:
131 nType
= com::sun::star::i18n::TransliterationModules_UPPERCASE_LOWERCASE
;
133 case SID_TRANSLITERATE_HALFWIDTH
:
134 nType
= com::sun::star::i18n::TransliterationModules_FULLWIDTH_HALFWIDTH
;
136 case SID_TRANSLITERATE_FULLWIDTH
:
137 nType
= com::sun::star::i18n::TransliterationModules_HALFWIDTH_FULLWIDTH
;
139 case SID_TRANSLITERATE_HIRAGANA
:
140 nType
= com::sun::star::i18n::TransliterationModules_KATAKANA_HIRAGANA
;
142 case SID_TRANSLITERATE_KATAGANA
:
143 nType
= com::sun::star::i18n::TransliterationModules_HIRAGANA_KATAKANA
;
150 BOOL
ScViewUtil::IsActionShown( const ScChangeAction
& rAction
,
151 const ScChangeViewSettings
& rSettings
,
152 ScDocument
& rDocument
)
154 // abgelehnte werden durch eine invertierende akzeptierte Action dargestellt,
155 // die Reihenfolge von ShowRejected/ShowAccepted ist deswegen wichtig
157 if ( !rSettings
.IsShowRejected() && rAction
.IsRejecting() )
160 if ( !rSettings
.IsShowAccepted() && rAction
.IsAccepted() && !rAction
.IsRejecting() )
163 if ( rSettings
.HasAuthor() )
165 if ( rSettings
.IsEveryoneButMe() )
167 // GetUser() am ChangeTrack ist der aktuelle Benutzer
168 ScChangeTrack
* pTrack
= rDocument
.GetChangeTrack();
169 if ( !pTrack
|| rAction
.GetUser() == pTrack
->GetUser() )
172 else if ( rAction
.GetUser() != rSettings
.GetTheAuthorToShow() )
176 if ( rSettings
.HasComment() )
178 String aComStr
=rAction
.GetComment();
179 aComStr
.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " (" ));
180 rAction
.GetDescription( aComStr
, &rDocument
);
183 if(!rSettings
.IsValidComment(&aComStr
))
187 if ( rSettings
.HasRange() )
188 if ( !rSettings
.GetTheRangeList().Intersects( rAction
.GetBigRange().MakeRange() ) )
191 if ( rSettings
.HasDate() && rSettings
.GetTheDateMode() != SCDM_NO_DATEMODE
)
193 DateTime aDateTime
= rAction
.GetDateTime();
194 const DateTime
& rFirst
= rSettings
.GetTheFirstDateTime();
195 const DateTime
& rLast
= rSettings
.GetTheLastDateTime();
196 switch ( rSettings
.GetTheDateMode() )
197 { // korrespondiert mit ScHighlightChgDlg::OKBtnHdl
198 case SCDM_DATE_BEFORE
:
199 if ( aDateTime
> rFirst
)
203 case SCDM_DATE_SINCE
:
204 if ( aDateTime
< rFirst
)
208 case SCDM_DATE_EQUAL
:
209 case SCDM_DATE_BETWEEN
:
210 if ( aDateTime
< rFirst
|| aDateTime
> rLast
)
214 case SCDM_DATE_NOTEQUAL
:
215 if ( aDateTime
>= rFirst
&& aDateTime
<= rLast
)
221 ScChangeTrack
* pTrack
= rDocument
.GetChangeTrack();
222 if ( !pTrack
|| pTrack
->GetLastSavedActionNumber() >=
223 rAction
.GetActionNumber() )
230 // added to avoid warnings
235 if ( rSettings
.HasActionRange() )
237 ULONG nAction
= rAction
.GetActionNumber();
240 rSettings
.GetTheActionRange( nFirstAction
, nLastAction
);
241 if ( nAction
< nFirstAction
|| nAction
> nLastAction
)
251 void ScViewUtil::UnmarkFiltered( ScMarkData
& rMark
, ScDocument
* pDoc
)
256 rMark
.GetMultiMarkArea( aMultiArea
);
257 SCCOL nStartCol
= aMultiArea
.aStart
.Col();
258 SCROW nStartRow
= aMultiArea
.aStart
.Row();
259 SCCOL nEndCol
= aMultiArea
.aEnd
.Col();
260 SCROW nEndRow
= aMultiArea
.aEnd
.Row();
262 bool bChanged
= false;
263 SCTAB nTabCount
= pDoc
->GetTableCount();
264 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
265 if ( rMark
.GetTableSelect(nTab
) )
267 for (SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
269 SCROW nLastRow
= nRow
;
270 if (pDoc
->RowFiltered(nRow
, nTab
, NULL
, &nLastRow
))
272 // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns
273 // (visible in repaint for indentation)
274 rMark
.SetMultiMarkArea(
275 ScRange(nStartCol
, nRow
, nTab
, nEndCol
, nLastRow
, nTab
), false);
282 if ( bChanged
&& !rMark
.HasAnyMultiMarks() )
285 rMark
.MarkToSimple();
290 bool ScViewUtil::FitToUnfilteredRows( ScRange
& rRange
, ScDocument
* pDoc
, size_t nRows
)
292 SCTAB nTab
= rRange
.aStart
.Tab();
293 bool bOneTabOnly
= (nTab
== rRange
.aEnd
.Tab());
294 // Always fit the range on its first sheet.
295 DBG_ASSERT( bOneTabOnly
, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet");
296 SCROW nStartRow
= rRange
.aStart
.Row();
298 SCROW nLastRow
= pDoc
->LastNonFilteredRow(nStartRow
, MAXROW
, nTab
);
299 if (ValidRow(nLastRow
))
300 rRange
.aEnd
.SetRow(nLastRow
);
301 SCROW nCount
= pDoc
->CountNonFilteredRows(nStartRow
, MAXROW
, nTab
);
303 // FillArrayForCondition() usually is the fastest to determine such a set
304 // in one pass, even if the array isn't used but the last element.
305 SCROW
* pArr
= new SCROW
[nRows
];
306 size_t nCount
= pDoc
->GetRowFlagsArray( nTab
).FillArrayForCondition(
307 nStartRow
, MAXROW
, CR_FILTERED
, 0, pArr
, nRows
);
309 rRange
.aEnd
.SetRow( pArr
[nCount
-1]);
312 return nCount
== nRows
&& bOneTabOnly
;
317 bool ScViewUtil::HasFiltered( const ScRange
& rRange
, ScDocument
* pDoc
)
319 SCROW nStartRow
= rRange
.aStart
.Row();
320 SCROW nEndRow
= rRange
.aEnd
.Row();
321 for (SCTAB nTab
=rRange
.aStart
.Tab(); nTab
<=rRange
.aEnd
.Tab(); nTab
++)
323 if (pDoc
->HasFilteredRows(nStartRow
, nEndRow
, nTab
))
331 void ScViewUtil::HideDisabledSlot( SfxItemSet
& rSet
, SfxBindings
& rBindings
, USHORT nSlotId
)
333 SvtCJKOptions aCJKOptions
;
334 SvtCTLOptions aCTLOptions
;
335 bool bEnabled
= true;
339 case SID_CHINESE_CONVERSION
:
340 case SID_HANGUL_HANJA_CONVERSION
:
341 bEnabled
= aCJKOptions
.IsAnyEnabled();
344 case SID_TRANSLITERATE_HALFWIDTH
:
345 case SID_TRANSLITERATE_FULLWIDTH
:
346 case SID_TRANSLITERATE_HIRAGANA
:
347 case SID_TRANSLITERATE_KATAGANA
:
348 bEnabled
= aCJKOptions
.IsChangeCaseMapEnabled();
353 case SID_INSERT_ZWNBSP
:
354 case SID_INSERT_ZWSP
:
355 bEnabled
= aCTLOptions
.IsCTLFontEnabled();
359 DBG_ERRORFILE( "ScViewUtil::HideDisabledSlot - unknown slot ID" );
363 rBindings
.SetVisibleState( nSlotId
, bEnabled
);
365 rSet
.DisableItem( nSlotId
);
368 //==================================================================
370 BOOL
ScViewUtil::ExecuteCharMap( const SvxFontItem
& rOldFont
,
371 SfxViewFrame
& rFrame
,
372 SvxFontItem
& rNewFont
,
376 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
379 SfxAllItemSet
aSet( rFrame
.GetObjectShell()->GetPool() );
380 aSet
.Put( SfxBoolItem( FN_PARAM_1
, FALSE
) );
381 aSet
.Put( SvxFontItem( rOldFont
.GetFamily(), rOldFont
.GetFamilyName(), rOldFont
.GetStyleName(), rOldFont
.GetPitch(), rOldFont
.GetCharSet(), aSet
.GetPool()->GetWhich( SID_ATTR_CHAR_FONT
) ) );
382 SfxAbstractDialog
* pDlg
= pFact
->CreateSfxDialog( &rFrame
.GetWindow(), aSet
, rFrame
.GetFrame()->GetFrameInterface(), RID_SVXDLG_CHARMAP
);
383 if ( pDlg
->Execute() == RET_OK
)
385 SFX_ITEMSET_ARG( pDlg
->GetOutputItemSet(), pItem
, SfxStringItem
, SID_CHARMAP
, FALSE
);
386 SFX_ITEMSET_ARG( pDlg
->GetOutputItemSet(), pFontItem
, SvxFontItem
, SID_ATTR_CHAR_FONT
, FALSE
);
388 rString
= pItem
->GetValue();
390 rNewFont
= SvxFontItem( pFontItem
->GetFamily(), pFontItem
->GetFamilyName(), pFontItem
->GetStyleName(), pFontItem
->GetPitch(), pFontItem
->GetCharSet(), rNewFont
.Which() );
398 bool ScViewUtil::IsFullScreen( SfxViewShell
& rViewShell
)
400 SfxBindings
& rBindings
= rViewShell
.GetViewFrame()->GetBindings();
401 SfxPoolItem
* pItem
= 0;
402 bool bIsFullScreen
= false;
404 if (rBindings
.QueryState( SID_WIN_FULLSCREEN
, pItem
) >= SFX_ITEM_DEFAULT
)
405 bIsFullScreen
= static_cast< SfxBoolItem
* >( pItem
)->GetValue();
406 return bIsFullScreen
;
409 void ScViewUtil::SetFullScreen( SfxViewShell
& rViewShell
, bool bSet
)
411 if( IsFullScreen( rViewShell
) != bSet
)
413 SfxBoolItem
aItem( SID_WIN_FULLSCREEN
, bSet
);
414 rViewShell
.GetDispatcher()->Execute( SID_WIN_FULLSCREEN
, SFX_CALLMODE_RECORD
, &aItem
, 0L );
418 //------------------------------------------------------------------
420 ScUpdateRect::ScUpdateRect( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
)
422 PutInOrder( nX1
, nX2
);
423 PutInOrder( nY1
, nY2
);
431 void ScUpdateRect::SetNew( SCCOL nX1
, SCROW nY1
, SCCOL nX2
, SCROW nY2
)
433 PutInOrder( nX1
, nX2
);
434 PutInOrder( nY1
, nY2
);
442 BOOL
ScUpdateRect::GetDiff( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
444 if ( nNewStartX
== nOldStartX
&& nNewEndX
== nOldEndX
&&
445 nNewStartY
== nOldStartY
&& nNewEndY
== nOldEndY
)
454 rX1
= Min(nNewStartX
,nOldStartX
);
455 rY1
= Min(nNewStartY
,nOldStartY
);
456 rX2
= Max(nNewEndX
,nOldEndX
);
457 rY2
= Max(nNewEndY
,nOldEndY
);
459 if ( nNewStartX
== nOldStartX
&& nNewEndX
== nOldEndX
)
461 if ( nNewStartY
== nOldStartY
)
463 rY1
= Min( nNewEndY
, nOldEndY
);
464 rY2
= Max( nNewEndY
, nOldEndY
);
466 else if ( nNewEndY
== nOldEndY
)
468 rY1
= Min( nNewStartY
, nOldStartY
);
469 rY2
= Max( nNewStartY
, nOldStartY
);
472 else if ( nNewStartY
== nOldStartY
&& nNewEndY
== nOldEndY
)
474 if ( nNewStartX
== nOldStartX
)
476 rX1
= Min( nNewEndX
, nOldEndX
);
477 rX2
= Max( nNewEndX
, nOldEndX
);
479 else if ( nNewEndX
== nOldEndX
)
481 rX1
= Min( nNewStartX
, nOldStartX
);
482 rX2
= Max( nNewStartX
, nOldStartX
);
489 #ifdef OLD_SELECTION_PAINT
490 BOOL
ScUpdateRect::GetXorDiff( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
, BOOL
& rCont
)
494 if (nNewStartX
== nOldStartX
&& nNewEndX
== nOldEndX
&&
495 nNewStartY
== nOldStartY
&& nNewEndY
== nOldEndY
)
504 rX1
= Min(nNewStartX
,nOldStartX
);
505 rY1
= Min(nNewStartY
,nOldStartY
);
506 rX2
= Max(nNewEndX
,nOldEndX
);
507 rY2
= Max(nNewEndY
,nOldEndY
);
509 if (nNewStartX
== nOldStartX
&& nNewEndX
== nOldEndX
) // nur vertikal
511 if (nNewStartY
== nOldStartY
)
513 rY1
= Min( nNewEndY
, nOldEndY
) + 1;
514 rY2
= Max( nNewEndY
, nOldEndY
);
516 else if (nNewEndY
== nOldEndY
)
518 rY1
= Min( nNewStartY
, nOldStartY
);
519 rY2
= Max( nNewStartY
, nOldStartY
) - 1;
523 rY1
= Min( nNewStartY
, nOldStartY
);
524 rY2
= Max( nNewStartY
, nOldStartY
) - 1;
526 nContY1
= Min( nNewEndY
, nOldEndY
) + 1;
527 nContY2
= Max( nNewEndY
, nOldEndY
);
532 else if (nNewStartY
== nOldStartY
&& nNewEndY
== nOldEndY
) // nur horizontal
534 if (nNewStartX
== nOldStartX
)
536 rX1
= Min( nNewEndX
, nOldEndX
) + 1;
537 rX2
= Max( nNewEndX
, nOldEndX
);
539 else if (nNewEndX
== nOldEndX
)
541 rX1
= Min( nNewStartX
, nOldStartX
);
542 rX2
= Max( nNewStartX
, nOldStartX
) - 1;
546 rX1
= Min( nNewStartX
, nOldStartX
);
547 rX2
= Max( nNewStartX
, nOldStartX
) - 1;
549 nContX1
= Min( nNewEndX
, nOldEndX
) + 1;
550 nContX2
= Max( nNewEndX
, nOldEndX
);
555 else if (nNewEndX
== nOldEndX
&& nNewEndY
== nOldEndY
) // links oben
557 if ((nNewStartX
<nOldStartX
) == (nNewStartY
<nOldStartY
))
558 rX1
= Min( nNewStartX
, nOldStartX
);
560 rX1
= Max( nNewStartX
, nOldStartX
); // Ecke weglassen
562 rY1
= Min( nNewStartY
, nOldStartY
); // oben
563 rY2
= Max( nNewStartY
, nOldStartY
) - 1;
567 nContX1
= Min( nNewStartX
, nOldStartX
); // links
568 nContX2
= Max( nNewStartX
, nOldStartX
) - 1;
570 else if (nNewStartX
== nOldStartX
&& nNewEndY
== nOldEndY
) // rechts oben
572 if ((nNewEndX
<nOldEndX
) != (nNewStartY
<nOldStartY
))
573 rX2
= Max( nNewEndX
, nOldEndX
);
575 rX2
= Min( nNewEndX
, nOldEndX
); // Ecke weglassen
577 rY1
= Min( nNewStartY
, nOldStartY
); // oben
578 rY2
= Max( nNewStartY
, nOldStartY
) - 1;
582 nContX1
= Min( nNewEndX
, nOldEndX
) + 1; // rechts
583 nContX2
= Max( nNewEndX
, nOldEndX
);
585 else if (nNewEndX
== nOldEndX
&& nNewStartY
== nOldStartY
) // links unten
587 if ((nNewStartX
<nOldStartX
) != (nNewEndY
<nOldEndY
))
588 rX1
= Min( nNewStartX
, nOldStartX
);
590 rX1
= Max( nNewStartX
, nOldStartX
); // Ecke weglassen
592 rY1
= Min( nNewEndY
, nOldEndY
) + 1; // unten
593 rY2
= Max( nNewEndY
, nOldEndY
);
595 nContY1
= nOldStartY
;
597 nContX1
= Min( nNewStartX
, nOldStartX
); // links
598 nContX2
= Max( nNewStartX
, nOldStartX
) - 1;
600 else if (nNewStartX
== nOldStartX
&& nNewStartY
== nOldStartY
) // rechts unten
602 if ((nNewEndX
<nOldEndX
) == (nNewEndY
<nOldEndY
))
603 rX2
= Max( nNewEndX
, nOldEndX
);
605 rX2
= Min( nNewEndX
, nOldEndX
); // Ecke weglassen
607 rY1
= Min( nNewEndY
, nOldEndY
) + 1; // unten
608 rY2
= Max( nNewEndY
, nOldEndY
);
610 nContY1
= nOldStartY
;
612 nContX1
= Min( nNewEndX
, nOldEndX
) + 1; // rechts
613 nContX2
= Max( nNewEndX
, nOldEndX
);
622 nContX1
= nNewStartX
;
623 nContY1
= nNewStartY
;
631 void ScUpdateRect::GetContDiff( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)