LibreOffice Module sc (master)  1
tabvwsh5.cxx
Go to the documentation of this file.
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 <svl/hint.hxx>
21 #include <comphelper/lok.hxx>
22 #include <svl/zforlist.hxx>
23 #include <svx/numfmtsh.hxx>
24 #include <svx/numinf.hxx>
25 #include <svx/svxids.hrc>
26 #include <sfx2/dispatch.hxx>
27 #include <sfx2/objsh.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <osl/diagnose.h>
30 
31 #include <tabvwsh.hxx>
32 #include <global.hxx>
33 #include <docsh.hxx>
34 #include <document.hxx>
35 #include <formulacell.hxx>
36 #include <scmod.hxx>
37 #include <uiitems.hxx>
38 #include <hints.hxx>
39 #include <cellvalue.hxx>
40 #include <svl/numformat.hxx>
41 #include <svl/sharedstring.hxx>
42 
43 void ScTabViewShell::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
44 {
45  if (const ScPaintHint* pPaintHint = dynamic_cast<const ScPaintHint*>(&rHint)) // draw new
46  {
47  PaintPartFlags nParts = pPaintHint->GetParts();
48  SCTAB nTab = GetViewData().GetTabNo();
49  if (pPaintHint->GetStartTab() <= nTab && pPaintHint->GetEndTab() >= nTab)
50  {
51  if (nParts & PaintPartFlags::Extras) // first if table vanished !!!
52  if (PaintExtras())
53  nParts = PaintPartFlags::All;
54 
55  // if the current sheet has pending row height updates (sheet links refreshed),
56  // execute them before invalidating the window
58 
59  if (nParts & PaintPartFlags::Size)
60  RepeatResize();
61  if (nParts & PaintPartFlags::Grid)
62  PaintArea( pPaintHint->GetStartCol(), pPaintHint->GetStartRow(),
63  pPaintHint->GetEndCol(), pPaintHint->GetEndRow() );
64  if (nParts & PaintPartFlags::Marks)
65  PaintArea( pPaintHint->GetStartCol(), pPaintHint->GetStartRow(),
66  pPaintHint->GetEndCol(), pPaintHint->GetEndRow(), ScUpdateMode::Marks );
67  if (nParts & PaintPartFlags::Left)
68  PaintLeftArea( pPaintHint->GetStartRow(), pPaintHint->GetEndRow() );
69  if (nParts & PaintPartFlags::Top)
70  PaintTopArea( pPaintHint->GetStartCol(), pPaintHint->GetEndCol() );
71 
72  // #i84689# call UpdateAllOverlays here instead of in ScTabView::PaintArea
73  if (nParts & ( PaintPartFlags::Left | PaintPartFlags::Top )) // only if widths or heights changed
75 
77  }
78  }
79  else if (auto pEditViewHint = dynamic_cast<const ScEditViewHint*>(&rHint)) // create Edit-View
80  {
81  // ScEditViewHint is only received at active view
82 
83  SCTAB nTab = GetViewData().GetTabNo();
84  if ( pEditViewHint->GetTab() == nTab )
85  {
86  SCCOL nCol = pEditViewHint->GetCol();
87  SCROW nRow = pEditViewHint->GetRow();
88  {
90 
91  MakeEditView( pEditViewHint->GetEngine(), nCol, nRow );
92 
93  StopEditShell(); // shouldn't be set
94 
95  ScSplitPos eActive = GetViewData().GetActivePart();
96  if ( GetViewData().HasEditView(eActive) )
97  {
98  // MakeEditView will fail, if the cursor is outside the screen.
99  // Then GetEditView will return a none-active view, therefore
100  // calling HasEditView.
101 
102  EditView* pView = GetViewData().GetEditView(eActive); // isn't zero
103 
104  SetEditShell(pView, true);
105  }
106  }
107  }
108  }
109  else if (auto pTablesHint = dynamic_cast<const ScTablesHint*>(&rHint)) // table insert / deleted
110  {
111  // first fetch current table (can be changed during DeleteTab on ViewData)
112  SCTAB nActiveTab = GetViewData().GetTabNo();
113 
114  SCTAB nTab1 = pTablesHint->GetTab1();
115  SCTAB nTab2 = pTablesHint->GetTab2();
116  sal_uInt16 nId = pTablesHint->GetTablesHintId();
117  switch (nId)
118  {
119  case SC_TAB_INSERTED:
120  GetViewData().InsertTab( nTab1 );
121  break;
122  case SC_TAB_DELETED:
123  GetViewData().DeleteTab( nTab1 );
124  break;
125  case SC_TAB_MOVED:
126  GetViewData().MoveTab( nTab1, nTab2 );
127  break;
128  case SC_TAB_COPIED:
129  GetViewData().CopyTab( nTab1, nTab2 );
130  break;
131  case SC_TAB_HIDDEN:
132  break;
133  case SC_TABS_INSERTED:
134  GetViewData().InsertTabs( nTab1, nTab2 );
135  break;
136  case SC_TABS_DELETED:
137  GetViewData().DeleteTabs( nTab1, nTab2 );
138  break;
139  default:
140  OSL_FAIL("unknown ScTablesHint");
141  }
142 
143  // No calling of IsActive() here, because the actions can be coming from Basic
144  // and then also the active view has to be switched.
145 
146  SCTAB nNewTab = nActiveTab;
147  bool bStayOnActiveTab = true;
148  switch (nId)
149  {
150  case SC_TAB_INSERTED:
151  if ( nTab1 <= nNewTab ) // insert before
152  ++nNewTab;
153  break;
154  case SC_TAB_DELETED:
155  if ( nTab1 < nNewTab ) // deleted before
156  --nNewTab;
157  else if ( nTab1 == nNewTab ) // deleted current
158  bStayOnActiveTab = false;
159  break;
160  case SC_TAB_MOVED:
161  if ( nNewTab == nTab1 ) // moved table
162  nNewTab = nTab2;
163  else if ( nTab1 < nTab2 ) // moved back
164  {
165  if ( nNewTab > nTab1 && nNewTab <= nTab2 ) // succeeding area
166  --nNewTab;
167  }
168  else // move in front
169  {
170  if ( nNewTab >= nTab2 && nNewTab < nTab1 ) // succeeding area
171  ++nNewTab;
172  }
173  break;
174  case SC_TAB_COPIED:
175  if ( nNewTab >= nTab2 ) // insert before
176  ++nNewTab;
177  break;
178  case SC_TAB_HIDDEN:
179  if ( nTab1 == nNewTab ) // current is hidden
180  bStayOnActiveTab = false;
181  break;
182  case SC_TABS_INSERTED:
183  if ( nTab1 <= nNewTab )
184  nNewTab += nTab2;
185  break;
186  case SC_TABS_DELETED:
187  if ( nTab1 < nNewTab )
188  nNewTab -= nTab2;
189  break;
190  }
191 
192  ScDocument& rDoc = GetViewData().GetDocument();
193  if ( nNewTab >= rDoc.GetTableCount() )
194  nNewTab = rDoc.GetTableCount() - 1;
195 
196  bool bForce = !bStayOnActiveTab;
197  SetTabNo( nNewTab, bForce, false, bStayOnActiveTab );
198  }
199  else if (const ScIndexHint* pIndexHint = dynamic_cast<const ScIndexHint*>(&rHint))
200  {
201  SfxHintId nId = pIndexHint->GetId();
202  sal_uInt16 nIndex = pIndexHint->GetIndex();
203  switch (nId)
204  {
205  case SfxHintId::ScShowRangeFinder:
206  PaintRangeFinder( nIndex );
207  break;
208  default: break;
209  }
210  }
211  else // without parameter
212  {
213  const SfxHintId nSlot = rHint.GetId();
214  switch ( nSlot )
215  {
216  case SfxHintId::ScDataChanged:
217  UpdateFormulas();
218  break;
219 
220  case SfxHintId::ScRefModeChanged:
221  {
222  bool bRefMode = SC_MOD()->IsFormulaMode();
223  if (!bRefMode)
224  StopRefMode();
225  else
226  GetSelEngine()->Reset();
227  }
228  break;
229 
230  case SfxHintId::ScKillEditView:
231  case SfxHintId::ScKillEditViewNoPaint:
233  || this == SfxViewShell::Current()
234  || bInPrepareClose
235  || bInDispose)
236  {
237  StopEditShell();
238  KillEditView( nSlot == SfxHintId::ScKillEditViewNoPaint );
239  }
240  break;
241 
242  case SfxHintId::DocChanged:
243  {
244  ScDocument& rDoc = GetViewData().GetDocument();
245  if (!rDoc.HasTable( GetViewData().GetTabNo() ))
246  {
247  SetTabNo(0);
248  }
249  }
250  break;
251 
252  case SfxHintId::ScDrawLayerNew:
254  break;
255 
256  case SfxHintId::ScDocSaved:
257  {
258  // "Save as" can make a write-protected document writable,
259  // therefore the Layer-Locks anew (#39884#)
260  // (Invalidate etc. is happening already from Sfx)
261  // by SID_EDITDOC no SfxHintId::TitleChanged will occur, that
262  // is why the own hint from DoSaveCompleted
264 
266 
267  // Would be too much to change Design-Mode with every save
268  // (when saving under the name, it should remain unchanged)
269  // Therefore only by SfxHintId::ModeChanged (from ViewFrame)
270  }
271  break;
272 
273  case SfxHintId::ModeChanged:
274  // Since you can no longer rely on it where this hint was coming
275  // from, always switch the design mode when the ReadOnly state
276  // really was changed:
277 
278  if ( GetViewData().GetSfxDocShell()->IsReadOnly() != bReadOnly )
279  {
281 
282  SfxBoolItem aItem( SID_FM_DESIGN_MODE, !bReadOnly);
283  GetViewData().GetDispatcher().ExecuteList(SID_FM_DESIGN_MODE,
284  SfxCallMode::ASYNCHRON, { &aItem });
285 
287  }
288  break;
289 
290  case SfxHintId::ScShowRangeFinder:
291  PaintRangeFinder(-1);
292  break;
293 
294  case SfxHintId::ScForceSetTab:
295  SetTabNo( GetViewData().GetTabNo(), true );
296  break;
297 
298  case SfxHintId::LanguageChanged:
299  {
300  GetViewFrame()->GetBindings().Invalidate(SID_LANGUAGE_STATUS);
301  if ( ScGridWindow* pWin = GetViewData().GetActiveWin() )
302  pWin->ResetAutoSpell();
303  }
304  break;
305 
306  default:
307  break;
308  }
309  }
310 
311  SfxViewShell::Notify( rBC, rHint );
312 }
313 
314 std::unique_ptr<SvxNumberInfoItem> ScTabViewShell::MakeNumberInfoItem( ScDocument& rDoc, const ScViewData& rViewData )
315 {
316 
317  // construct NumberInfo item
318 
319  SvxNumberValueType eValType = SvxNumberValueType::Undefined;
320  double nCellValue = 0;
321  OUString aCellString;
322 
323  ScRefCellValue aCell(rDoc, rViewData.GetCurPos());
324 
325  switch (aCell.meType)
326  {
327  case CELLTYPE_VALUE:
328  {
329  nCellValue = aCell.mfValue;
330  eValType = SvxNumberValueType::Number;
331  }
332  break;
333 
334  case CELLTYPE_STRING:
335  {
336  aCellString = aCell.mpString->getString();
337  eValType = SvxNumberValueType::String;
338  }
339  break;
340 
341  case CELLTYPE_FORMULA:
342  {
343  if (aCell.mpFormula->IsValue())
344  {
345  nCellValue = aCell.mpFormula->GetValue();
346  eValType = SvxNumberValueType::Number;
347  }
348  else
349  {
350  nCellValue = 0;
351  eValType = SvxNumberValueType::Undefined;
352  }
353  }
354  break;
355 
356  default:
357  nCellValue = 0;
358  eValType = SvxNumberValueType::Undefined;
359  }
360 
361  switch ( eValType )
362  {
363  case SvxNumberValueType::String:
364  return std::make_unique<SvxNumberInfoItem>(
365  rDoc.GetFormatTable(),
366  aCellString,
367  SID_ATTR_NUMBERFORMAT_INFO );
368 
369  case SvxNumberValueType::Number:
370  return std::make_unique<SvxNumberInfoItem>(
371  rDoc.GetFormatTable(),
372  nCellValue,
373  SID_ATTR_NUMBERFORMAT_INFO );
374 
375  case SvxNumberValueType::Undefined:
376  default:
377  ;
378  }
379 
380  return std::make_unique<SvxNumberInfoItem>(
381  rDoc.GetFormatTable(), static_cast<sal_uInt16>(SID_ATTR_NUMBERFORMAT_INFO));
382 }
383 
385  const SvxNumberInfoItem& rInfoItem )
386 {
387  for ( sal_uInt32 key : rInfoItem.GetDelFormats() )
388  rInfoItem.GetNumberFormatter()->DeleteEntry( key );
389 }
390 
391 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxViewFrame * GetViewFrame() const
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
SfxHintId
sal_Int32 nIndex
static void UpdateNumberFormatter(const SvxNumberInfoItem &rInfoItem)
Definition: tabvwsh5.cxx:384
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:353
void UpdatePendingRowHeights(SCTAB nUpdateTab, bool bBefore=false)
Definition: docsh5.cxx:432
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
#define SC_TAB_MOVED
Definition: uiitems.hxx:77
void UpdateInputContext()
Definition: tabview3.cxx:2977
bool PaintExtras()
Definition: tabview3.cxx:2759
void InsertTabs(SCTAB nTab, SCTAB nNewSheets)
Definition: viewdata.cxx:893
void RepeatResize(bool bUpdateFix=true)
Definition: tabview.cxx:771
void HideNoteMarker()
Definition: tabview2.cxx:1387
bool bInPrepareClose
Definition: tabvwsh.hxx:152
sal_Int16 nId
SCTAB GetTabNo() const
Definition: viewdata.hxx:394
SvxNumberValueType
ScSplitPos GetActivePart() const
Definition: viewdata.hxx:397
ScDocument & GetDocument() const
Definition: viewdata.hxx:379
void UpdateAllOverlays()
Definition: tabview2.cxx:1000
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:103
#define SC_TAB_INSERTED
Definition: uiitems.hxx:75
void Invalidate(sal_uInt16 nId)
const std::vector< sal_uInt32 > & GetDelFormats() const
static std::unique_ptr< SvxNumberInfoItem > MakeNumberInfoItem(ScDocument &rDoc, const ScViewData &rViewData)
Definition: tabvwsh5.cxx:314
SfxHintId GetId() const
ScSplitPos
Definition: viewdata.hxx:44
void KillEditView(bool bNoPaint)
Definition: tabview3.cxx:2171
void PaintLeftArea(SCROW nStartRow, SCROW nEndRow)
Definition: tabview3.cxx:2717
constexpr OUStringLiteral IsReadOnly(u"IsReadOnly")
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:314
void PaintRangeFinder(tools::Long nNumber)
Definition: tabview3.cxx:2495
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: tabvwsh5.cxx:43
static SfxViewShell * Current()
void UpdateFormulas(SCCOL nStartCol=-1, SCROW nStartRow=-1, SCCOL nEndCol=-1, SCROW nEndRow=-1)
Definition: tabview3.cxx:2283
SC_DLLPUBLIC bool HasTable(SCTAB nTab) const
Definition: document.cxx:191
#define SC_TAB_DELETED
Definition: uiitems.hxx:76
TRISTATE_INDET
ScViewData & GetViewData()
Definition: tabview.hxx:333
ScGridWindow * GetActiveWin()
Definition: tabview.cxx:886
void PaintArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScUpdateMode eMode=ScUpdateMode::All)
Definition: tabview3.cxx:2306
void InsertTab(SCTAB nTab)
Definition: viewdata.cxx:879
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:441
void DeleteTab(SCTAB nTab)
Definition: viewdata.cxx:912
sal_Int16 SCCOL
Definition: types.hxx:21
#define SC_TAB_HIDDEN
Definition: uiitems.hxx:79
#define SC_MOD()
Definition: scmod.hxx:250
SfxBindings & GetBindings()
SC_DLLPUBLIC void SetTabNo(SCTAB nTab, bool bNew=false, bool bExtendSelection=false, bool bSameTabButMoved=false)
Definition: tabview3.cxx:1798
void StopEditShell()
Definition: tabvwsh4.cxx:1068
void DeleteTabs(SCTAB nTab, SCTAB nSheets)
Definition: viewdata.cxx:926
void DeleteEntry(sal_uInt32 nKey)
void MakeEditView(ScEditEngineDefaulter *pEngine, SCCOL nCol, SCROW nRow)
Definition: tabview3.cxx:2091
void MoveTab(SCTAB nSrcTab, SCTAB nDestTab)
Definition: viewdata.cxx:966
bool IsReadOnly() const
void StopRefMode()
Definition: tabview4.cxx:113
ScAddress GetCurPos() const
Definition: viewdata.cxx:4076
SvNumberFormatter * GetNumberFormatter() const
#define SC_TABS_DELETED
Definition: uiitems.hxx:81
sal_Int32 SCROW
Definition: types.hxx:17
#define SC_TABS_INSERTED
Definition: uiitems.hxx:80
SfxDispatcher & GetDispatcher()
Definition: viewdata.cxx:3102
ScViewSelectionEngine * GetSelEngine()
Definition: tabview.hxx:337
SfxObjectShell * GetSfxDocShell() const
Definition: viewdata.hxx:357
#define SC_TAB_COPIED
Definition: uiitems.hxx:78
void PaintTopArea(SCCOL nStartCol, SCCOL nEndCol)
Definition: tabview3.cxx:2659
void CopyTab(SCTAB nSrcTab, SCTAB nDestTab)
Definition: viewdata.cxx:941
PaintPartFlags
Definition: global.hxx:119
void UpdateLayerLocks()
Definition: tabview5.cxx:357
void SetEditShell(EditView *pView, bool bActive)
Definition: tabvwsh4.cxx:750
void GetEditView(ScSplitPos eWhich, EditView *&rViewPtr, SCCOL &rCol, SCROW &rRow)
Definition: viewdata.cxx:2279
sal_Int16 SCTAB
Definition: types.hxx:22
void MakeDrawView(TriState nForceDesignMode)
Definition: tabview5.cxx:229