1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <svl/hint.hxx>
21 #include <comphelper/lok.hxx>
22 #include <svx/numfmtsh.hxx>
23 #include <svx/numinf.hxx>
24 #include <svx/svxids.hrc>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/objsh.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <osl/diagnose.h>
30 #include <tabvwsh.hxx>
33 #include <document.hxx>
34 #include <formulacell.hxx>
36 #include <uiitems.hxx>
38 #include <cellvalue.hxx>
39 #include <svl/numformat.hxx>
40 #include <svl/sharedstring.hxx>
42 void ScTabViewShell::Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
44 if (rHint
.GetId() == SfxHintId::ScPaint
) // draw new
46 const ScPaintHint
* pPaintHint
= static_cast<const ScPaintHint
*>(&rHint
);
47 PaintPartFlags nParts
= pPaintHint
->GetParts();
48 SCTAB nTab
= GetViewData().GetTabNo();
49 if (pPaintHint
->GetStartTab() <= nTab
&& pPaintHint
->GetEndTab() >= nTab
)
51 if (nParts
& PaintPartFlags::Extras
) // first if table vanished !!!
53 nParts
= PaintPartFlags::All
;
55 // if the current sheet has pending row height updates (sheet links refreshed),
56 // execute them before invalidating the window
57 GetViewData().GetDocShell()->UpdatePendingRowHeights( GetViewData().GetTabNo() );
59 if (nParts
& PaintPartFlags::Size
)
60 RepeatResize(); //! InvalidateBorder ???
61 const tools::Long nWidthAffectedHint
= pPaintHint
->GetMaxWidthAffectedHint();
62 if (nParts
& PaintPartFlags::Grid
)
63 PaintArea( pPaintHint
->GetStartCol(), pPaintHint
->GetStartRow(),
64 pPaintHint
->GetEndCol(), pPaintHint
->GetEndRow(),
65 ScUpdateMode::All
, nWidthAffectedHint
);
66 if (nParts
& PaintPartFlags::Marks
)
67 PaintArea( pPaintHint
->GetStartCol(), pPaintHint
->GetStartRow(),
68 pPaintHint
->GetEndCol(), pPaintHint
->GetEndRow(),
69 ScUpdateMode::Marks
, nWidthAffectedHint
);
70 if (nParts
& PaintPartFlags::Left
)
71 PaintLeftArea( pPaintHint
->GetStartRow(), pPaintHint
->GetEndRow() );
72 if (nParts
& PaintPartFlags::Top
)
73 PaintTopArea( pPaintHint
->GetStartCol(), pPaintHint
->GetEndCol() );
75 // #i84689# call UpdateAllOverlays here instead of in ScTabView::PaintArea
76 if (nParts
& ( PaintPartFlags::Left
| PaintPartFlags::Top
)) // only if widths or heights changed
82 else if (rHint
.GetId() == SfxHintId::ScEditView
) // create Edit-View
84 // ScEditViewHint is only received at active view
85 auto pEditViewHint
= static_cast<const ScEditViewHint
*>(&rHint
);
87 SCTAB nTab
= GetViewData().GetTabNo();
88 if ( pEditViewHint
->GetTab() == nTab
)
90 SCCOL nCol
= pEditViewHint
->GetCol();
91 SCROW nRow
= pEditViewHint
->GetRow();
95 MakeEditView( pEditViewHint
->GetEngine(), nCol
, nRow
);
97 StopEditShell(); // shouldn't be set
99 ScSplitPos eActive
= GetViewData().GetActivePart();
100 if ( GetViewData().HasEditView(eActive
) )
102 // MakeEditView will fail, if the cursor is outside the screen.
103 // Then GetEditView will return a none-active view, therefore
104 // calling HasEditView.
106 EditView
* pView
= GetViewData().GetEditView(eActive
); // isn't zero
108 SetEditShell(pView
, true);
113 else if (rHint
.GetId() == SfxHintId::ScTables
) // table insert / deleted
115 auto pTablesHint
= static_cast<const ScTablesHint
*>(&rHint
);
116 // first fetch current table (can be changed during DeleteTab on ViewData)
117 SCTAB nActiveTab
= GetViewData().GetTabNo();
119 SCTAB nTab1
= pTablesHint
->GetTab1();
120 SCTAB nTab2
= pTablesHint
->GetTab2();
121 sal_uInt16 nId
= pTablesHint
->GetTablesHintId();
124 case SC_TAB_INSERTED
:
125 GetViewData().InsertTab( nTab1
);
128 GetViewData().DeleteTab( nTab1
);
131 GetViewData().MoveTab( nTab1
, nTab2
);
134 GetViewData().CopyTab( nTab1
, nTab2
);
138 case SC_TABS_INSERTED
:
139 GetViewData().InsertTabs( nTab1
, nTab2
);
141 case SC_TABS_DELETED
:
142 GetViewData().DeleteTabs( nTab1
, nTab2
);
145 OSL_FAIL("unknown ScTablesHint");
148 // No calling of IsActive() here, because the actions can be coming from Basic
149 // and then also the active view has to be switched.
151 SCTAB nNewTab
= nActiveTab
;
152 bool bStayOnActiveTab
= true;
155 case SC_TAB_INSERTED
:
156 if ( nTab1
<= nNewTab
) // insert before
160 if ( nTab1
< nNewTab
) // deleted before
162 else if ( nTab1
== nNewTab
) // deleted current
163 bStayOnActiveTab
= false;
166 if ( nNewTab
== nTab1
) // moved table
168 else if ( nTab1
< nTab2
) // moved back
170 if ( nNewTab
> nTab1
&& nNewTab
<= nTab2
) // succeeding area
173 else // move in front
175 if ( nNewTab
>= nTab2
&& nNewTab
< nTab1
) // succeeding area
180 if ( nNewTab
>= nTab2
) // insert before
184 if ( nTab1
== nNewTab
) // current is hidden
185 bStayOnActiveTab
= false;
187 case SC_TABS_INSERTED
:
188 if ( nTab1
<= nNewTab
)
191 case SC_TABS_DELETED
:
192 if ( nTab1
< nNewTab
)
197 ScDocument
& rDoc
= GetViewData().GetDocument();
198 if ( nNewTab
>= rDoc
.GetTableCount() )
199 nNewTab
= rDoc
.GetTableCount() - 1;
201 bool bForce
= !bStayOnActiveTab
;
202 SetTabNo( nNewTab
, bForce
, false, bStayOnActiveTab
);
204 else if (const ScIndexHint
* pIndexHint
= dynamic_cast<const ScIndexHint
*>(&rHint
))
206 SfxHintId nId
= pIndexHint
->GetId();
207 sal_uInt16 nIndex
= pIndexHint
->GetIndex();
210 case SfxHintId::ScShowRangeFinder
:
211 PaintRangeFinder( nIndex
);
216 else // without parameter
218 const SfxHintId nSlot
= rHint
.GetId();
221 case SfxHintId::ScDataChanged
:
225 case SfxHintId::ScRefModeChanged
:
227 bool bRefMode
= ScModule::get()->IsFormulaMode();
231 GetSelEngine()->Reset();
235 case SfxHintId::ScKillEditView
:
236 case SfxHintId::ScKillEditViewNoPaint
:
237 if (!comphelper::LibreOfficeKit::isActive()
238 || this == SfxViewShell::Current()
243 KillEditView( nSlot
== SfxHintId::ScKillEditViewNoPaint
);
247 case SfxHintId::DocChanged
:
249 ScDocument
& rDoc
= GetViewData().GetDocument();
250 if (!rDoc
.HasTable( GetViewData().GetTabNo() ))
257 case SfxHintId::ScDrawLayerNew
:
258 MakeDrawView(TRISTATE_INDET
);
261 case SfxHintId::ScDocSaved
:
263 // "Save as" can make a write-protected document writable,
264 // therefore the Layer-Locks anew (#39884#)
265 // (Invalidate etc. is happening already from Sfx)
266 // by SID_EDITDOC no SfxHintId::TitleChanged will occur, that
267 // is why the own hint from DoSaveCompleted
268 //! what is with SfxHintId::SAVECOMPLETED ?
272 // Would be too much to change Design-Mode with every save
273 // (when saving under the name, it should remain unchanged)
274 // Therefore only by SfxHintId::ModeChanged (from ViewFrame)
278 case SfxHintId::ModeChanged
:
279 // Since you can no longer rely on it where this hint was coming
280 // from, always switch the design mode when the ReadOnly state
281 // really was changed:
283 if ( GetViewData().GetSfxDocShell()->IsReadOnly() != bReadOnly
)
285 bReadOnly
= GetViewData().GetSfxDocShell()->IsReadOnly();
287 SfxBoolItem
aItem( SID_FM_DESIGN_MODE
, !bReadOnly
);
288 GetViewData().GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE
,
289 SfxCallMode::ASYNCHRON
, { &aItem
});
291 UpdateInputContext();
295 case SfxHintId::ScShowRangeFinder
:
296 PaintRangeFinder(-1);
299 case SfxHintId::ScForceSetTab
:
300 SetTabNo( GetViewData().GetTabNo(), true );
303 case SfxHintId::LanguageChanged
:
305 GetViewFrame().GetBindings().Invalidate(SID_LANGUAGE_STATUS
);
306 if ( ScGridWindow
* pWin
= GetViewData().GetActiveWin() )
307 pWin
->ResetAutoSpell();
316 SfxViewShell::Notify( rBC
, rHint
);
319 std::unique_ptr
<SvxNumberInfoItem
> ScTabViewShell::MakeNumberInfoItem( ScDocument
& rDoc
, const ScViewData
& rViewData
)
322 // construct NumberInfo item
324 SvxNumberValueType eValType
= SvxNumberValueType::Undefined
;
325 double nCellValue
= 0;
326 OUString aCellString
;
328 ScRefCellValue
aCell(rDoc
, rViewData
.GetCurPos());
330 switch (aCell
.getType())
334 nCellValue
= aCell
.getDouble();
335 eValType
= SvxNumberValueType::Number
;
339 case CELLTYPE_STRING
:
341 aCellString
= aCell
.getSharedString()->getString();
342 eValType
= SvxNumberValueType::String
;
346 case CELLTYPE_FORMULA
:
348 if (aCell
.getFormula()->IsValue())
350 nCellValue
= aCell
.getFormula()->GetValue();
351 eValType
= SvxNumberValueType::Number
;
356 eValType
= SvxNumberValueType::Undefined
;
363 eValType
= SvxNumberValueType::Undefined
;
368 case SvxNumberValueType::String
:
369 return std::make_unique
<SvxNumberInfoItem
>(
370 rDoc
.GetFormatTable(),
372 SID_ATTR_NUMBERFORMAT_INFO
);
374 case SvxNumberValueType::Number
:
375 return std::make_unique
<SvxNumberInfoItem
>(
376 rDoc
.GetFormatTable(),
378 SID_ATTR_NUMBERFORMAT_INFO
);
380 case SvxNumberValueType::Undefined
:
385 return std::make_unique
<SvxNumberInfoItem
>(
386 rDoc
.GetFormatTable(), SID_ATTR_NUMBERFORMAT_INFO
);
389 void ScTabViewShell::UpdateNumberFormatter(
390 const SvxNumberInfoItem
& rInfoItem
)
392 for ( sal_uInt32 key
: rInfoItem
.GetDelFormats() )
393 rInfoItem
.GetNumberFormatter()->DeleteEntry( key
);
396 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */