LibreOffice Module sc (master)  1
navipi.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 <sfx2/app.hxx>
21 #include <sfx2/bindings.hxx>
22 #include <sfx2/dispatch.hxx>
23 #include <sfx2/event.hxx>
24 #include <sfx2/navigat.hxx>
25 #include <svl/stritem.hxx>
26 #include <unotools/charclass.hxx>
27 #include <uiobject.hxx>
28 
29 #include <viewdata.hxx>
30 #include <tabvwsh.hxx>
31 #include <docsh.hxx>
32 #include <document.hxx>
33 #include <rangeutl.hxx>
34 #include <sc.hrc>
35 #include <strings.hrc>
36 #include <bitmaps.hlst>
37 #include <scresid.hxx>
38 #include <scmod.hxx>
39 #include <navicfg.hxx>
40 #include <navcitem.hxx>
41 #include <navipi.hxx>
42 #include <navsett.hxx>
43 #include <markdata.hxx>
44 
45 #include <com/sun/star/uno/Reference.hxx>
46 
47 using namespace com::sun::star;
48 
49 // maximum values for UI
50 static SCCOL SCNAV_MAXCOL(const ScSheetLimits& rLimits) { return rLimits.GetMaxColCount(); }
51 static sal_Int32 SCNAV_COLDIGITS(const ScSheetLimits& rLimits)
52 {
53  return static_cast<sal_Int32>( floor( log10( static_cast<double>(SCNAV_MAXCOL(rLimits)))) ) + 1; // 1...256...18278
54 }
55 static sal_Int32 SCNAV_COLLETTERS(const ScSheetLimits& rLimits)
56 {
57  return ::ScColToAlpha(SCNAV_MAXCOL(rLimits)).getLength(); // A...IV...ZZZ
58 }
59 
60 static SCROW SCNAV_MAXROW(const ScSheetLimits& rSheetLimits)
61 {
62  return rSheetLimits.GetMaxRowCount();
63 }
64 
66 {
68 
69  if ( pCurSh )
70  {
71  vcl::Window* pShellWnd = pCurSh->GetWindow();
72  if ( pShellWnd )
73  pShellWnd->GrabFocus();
74  }
75 }
76 
77 namespace
78 {
79  SCCOL NumToAlpha(const ScSheetLimits& rSheetLimits, SCCOL nColNo, OUString& rStr)
80  {
81  if ( nColNo > SCNAV_MAXCOL(rSheetLimits) )
82  nColNo = SCNAV_MAXCOL(rSheetLimits);
83  else if ( nColNo < 1 )
84  nColNo = 1;
85 
86  ::ScColToAlpha( rStr, nColNo - 1);
87 
88  return nColNo;
89  }
90 
91  SCCOL AlphaToNum(const ScDocument& rDoc, OUString& rStr)
92  {
93  SCCOL nColumn = 0;
94 
95  if ( CharClass::isAsciiAlpha( rStr) )
96  {
97  rStr = rStr.toAsciiUpperCase();
98 
99  if (::AlphaToCol( rDoc, nColumn, rStr))
100  ++nColumn;
101 
102  if ( (rStr.getLength() > SCNAV_COLLETTERS(rDoc.GetSheetLimits())) ||
103  (nColumn > SCNAV_MAXCOL(rDoc.GetSheetLimits())) )
104  {
105  nColumn = SCNAV_MAXCOL(rDoc.GetSheetLimits());
106  NumToAlpha( rDoc.GetSheetLimits(), nColumn, rStr );
107  }
108  }
109  else
110  rStr.clear();
111 
112  return nColumn;
113  }
114 
115  SCCOL NumStrToAlpha(const ScSheetLimits& rSheetLimits, OUString& rStr)
116  {
117  SCCOL nColumn = 0;
118 
119  if ( CharClass::isAsciiNumeric(rStr) )
120  nColumn = NumToAlpha( rSheetLimits, static_cast<SCCOL>(rStr.toInt32()), rStr );
121  else
122  rStr.clear();
123 
124  return nColumn;
125  }
126 }
127 
128 IMPL_LINK(ScNavigatorDlg, ParseRowInputHdl, int*, result, bool)
129 {
130  SCCOL nCol;
131 
132  OUString aStrCol = m_xEdCol->get_text();
133 
134  if (!aStrCol.isEmpty())
135  {
136  // nKeyGroup is no longer set at VCL, in cause of lack of keyinput
137 
138  ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
139  auto& rDoc = pViewSh->GetViewData().GetDocument();
140  if ( CharClass::isAsciiNumeric(aStrCol) )
141  nCol = NumStrToAlpha( rDoc.GetSheetLimits(), aStrCol );
142  else
143  nCol = AlphaToNum( rDoc, aStrCol );
144  }
145  else
146  nCol = 0;
147 
148  *result = nCol;
149  return true;
150 }
151 
153 {
154  ReleaseFocus();
155 
156  SCROW nRow = m_xEdRow->get_value();
157  SCCOL nCol = m_xEdCol->get_value();
158 
159  if ( (nCol > 0) && (nRow > 0) )
160  SetCurrentCell(nCol - 1, nRow - 1);
161 
162  return true;
163 }
164 
165 IMPL_LINK_NOARG(ScNavigatorDlg, FormatRowOutputHdl, weld::SpinButton&, void)
166 {
167  OUString aStr;
168  ::ScColToAlpha(aStr, m_xEdCol->get_value() - 1);
169  m_xEdCol->set_text(aStr);
170 }
171 
173 {
174  ReleaseFocus();
175 
176  SCCOL nCol = m_xEdCol->get_value();
177  SCROW nRow = m_xEdRow->get_value();
178 
179  if ( (nCol > 0) && (nRow > 0) )
180  SetCurrentCell(nCol - 1, nRow - 1);
181 
182  return true;
183 }
184 
185 IMPL_LINK(ScNavigatorDlg, DocumentSelectHdl, weld::ComboBox&, rListBox, void)
186 {
188 
189  OUString aDocName = rListBox.get_active_text();
190  m_xLbEntries->SelectDoc(aDocName);
191 }
192 
193 IMPL_LINK(ScNavigatorDlg, ToolBoxSelectHdl, const OString&, rSelId, void)
194 {
195  // Switch the mode?
196  if (rSelId == "contents" || rSelId == "scenarios")
197  {
198  NavListMode eOldMode = eListMode;
199  NavListMode eNewMode;
200 
201  if (rSelId == "scenarios")
202  {
203  if (eOldMode == NAV_LMODE_SCENARIOS)
204  eNewMode = NAV_LMODE_AREAS;
205  else
206  eNewMode = NAV_LMODE_SCENARIOS;
207  }
208  else // on/off
209  {
210  if (eOldMode == NAV_LMODE_NONE)
211  eNewMode = NAV_LMODE_AREAS;
212  else
213  eNewMode = NAV_LMODE_NONE;
214  }
215  SetListMode(eNewMode);
216  UpdateButtons();
217  }
218  else if (rSelId == "dragmode")
219  m_xTbxCmd2->set_menu_item_active("dragmode", !m_xTbxCmd2->get_menu_item_active("dragmode"));
220  else
221  {
222  if (rSelId == "datarange")
223  MarkDataArea();
224  else if (rSelId == "start")
225  StartOfDataArea();
226  else if (rSelId == "end")
227  EndOfDataArea();
228  else if (rSelId == "toggle")
229  {
230  m_xLbEntries->ToggleRoot();
231  UpdateButtons();
232  }
233  }
234 }
235 
236 IMPL_LINK(ScNavigatorDlg, ToolBoxDropdownClickHdl, const OString&, rCommand, void)
237 {
238  if (!m_xTbxCmd2->get_menu_item_active(rCommand))
239  return;
240 
241  // the popup menu of the drop mode has to be called in the
242  // click (button down) and not in the select (button up)
243  if (rCommand != "dragmode")
244  return;
245 
246  switch (GetDropMode())
247  {
248  case 0:
249  m_xDragModeMenu->set_active("hyperlink", true);
250  break;
251  case 1:
252  m_xDragModeMenu->set_active("link", true);
253  break;
254  case 2:
255  m_xDragModeMenu->set_active("copy", true);
256  break;
257  }
258 }
259 
260 IMPL_LINK(ScNavigatorDlg, MenuSelectHdl, const OString&, rIdent, void)
261 {
262  if (rIdent == "hyperlink")
263  SetDropMode(0);
264  else if (rIdent == "link")
265  SetDropMode(1);
266  else if (rIdent == "copy")
267  SetDropMode(2);
268 }
269 
271 {
272  NavListMode eMode = eListMode;
273  m_xTbxCmd2->set_item_active("scenarios", eMode == NAV_LMODE_SCENARIOS);
274  m_xTbxCmd1->set_item_active("contents", eMode != NAV_LMODE_NONE);
275 
276  // the toggle button:
277  if (eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE)
278  {
279  m_xTbxCmd2->set_item_sensitive("toggle", false);
280  m_xTbxCmd2->set_item_active("toggle", false);
281  }
282  else
283  {
284  m_xTbxCmd2->set_item_sensitive("toggle", true);
285  bool bRootSet = m_xLbEntries->GetRootType() != ScContentId::ROOT;
286  m_xTbxCmd2->set_item_active("toggle", bRootSet);
287  }
288 
289  OUString sImageId;
290  switch (nDropMode)
291  {
292  case SC_DROPMODE_URL:
293  sImageId = RID_BMP_DROP_URL;
294  break;
295  case SC_DROPMODE_LINK:
296  sImageId = RID_BMP_DROP_LINK;
297  break;
298  case SC_DROPMODE_COPY:
299  sImageId = RID_BMP_DROP_COPY;
300  break;
301  }
302  m_xTbxCmd2->set_item_icon_name("dragmode", sImageId);
303 }
304 
306  : mnRootSelected(ScContentId::ROOT)
307  , mnChildSelected(SC_CONTENT_NOCHILD)
308 {
309  maExpandedVec.fill(false);
310 }
311 
313 {
314 private:
315  std::unique_ptr<ScNavigatorDlg> m_xNavigator;
316 public:
318  vcl::Window* pParent, SfxChildWinInfo* pInfo);
319  virtual void StateChanged(StateChangedType nStateChange) override;
320  virtual void dispose() override
321  {
322  m_xNavigator.reset();
324  }
325  virtual ~ScNavigatorWin() override
326  {
327  disposeOnce();
328  }
329 };
330 
332  vcl::Window* _pParent, SfxChildWinInfo* pInfo)
333  : SfxNavigator(_pBindings, _pMgr, _pParent, pInfo)
334 {
335  m_xNavigator = std::make_unique<ScNavigatorDlg>(_pBindings, m_xContainer.get(), this);
336  SetMinOutputSizePixel(GetOptimalSize());
337 }
338 
340  : PanelLayout(pParent, "NavigatorPanel", "modules/scalc/ui/navigatorpanel.ui")
341  , rBindings(*pB)
342  , m_xEdCol(m_xBuilder->weld_spin_button("column"))
343  , m_xEdRow(m_xBuilder->weld_spin_button("row"))
344  , m_xTbxCmd1(m_xBuilder->weld_toolbar("toolbox1"))
345  , m_xTbxCmd2(m_xBuilder->weld_toolbar("toolbox2"))
346  , m_xLbEntries(new ScContentTree(m_xBuilder->weld_tree_view("contentbox"), this))
347  , m_xScenarioBox(m_xBuilder->weld_widget("scenariobox"))
348  , m_xWndScenarios(new ScScenarioWindow(*m_xBuilder,
349  ScResId(SCSTR_QHLP_SCEN_LISTBOX), ScResId(SCSTR_QHLP_SCEN_COMMENT)))
350  , m_xLbDocuments(m_xBuilder->weld_combo_box("documents"))
351  , m_xDragModeMenu(m_xBuilder->weld_menu("dragmodemenu"))
352  , m_xNavigatorDlg(pNavigatorDlg)
353  , aStrActiveWin(ScResId(SCSTR_ACTIVEWIN))
354  , pViewData(nullptr )
355  , eListMode(NAV_LMODE_NONE)
356  , nDropMode(SC_DROPMODE_URL)
357  , nCurCol(0)
358  , nCurRow(0)
359  , nCurTab(0)
360 {
361  UpdateInitShow();
362 
364  m_xEdRow->set_width_chars(5);
365  //max rows is 1,000,000, which is too long for typical use
366  m_xEdRow->connect_activate(LINK(this, ScNavigatorDlg, ExecuteRowHdl));
367 
368  m_xEdCol->connect_activate(LINK(this, ScNavigatorDlg, ExecuteColHdl));
369  m_xEdCol->connect_output(LINK(this, ScNavigatorDlg, FormatRowOutputHdl));
370  m_xEdCol->connect_input(LINK(this, ScNavigatorDlg, ParseRowInputHdl));
371 
372  m_xTbxCmd1->connect_clicked(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl));
373  m_xTbxCmd2->connect_clicked(LINK(this, ScNavigatorDlg, ToolBoxSelectHdl));
374 
375  m_xTbxCmd2->set_item_menu("dragmode", m_xDragModeMenu.get());
376  m_xDragModeMenu->connect_activate(LINK(this, ScNavigatorDlg, MenuSelectHdl));
377  m_xTbxCmd2->connect_menu_toggled(LINK(this, ScNavigatorDlg, ToolBoxDropdownClickHdl));
378 
379  ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
380  nDropMode = rCfg.GetDragMode();
381 
382  m_xLbDocuments->set_size_request(42, -1); // set a nominal width so it takes width of surroundings
383  m_xLbDocuments->connect_changed(LINK(this, ScNavigatorDlg, DocumentSelectHdl));
384  aStrActive = " (" + ScResId(SCSTR_ACTIVE) + ")"; // " (active)"
385  aStrNotActive = " (" + ScResId(SCSTR_NOTACTIVE) + ")"; // " (not active)"
386  aStrHidden = " (" + ScResId(SCSTR_HIDDEN) + ")"; // " (hidden)"
387 
388  rBindings.ENTERREGISTRATIONS();
389 
390  mvBoundItems[0].reset(new ScNavigatorControllerItem(SID_CURRENTCELL,*this,rBindings));
391  mvBoundItems[1].reset(new ScNavigatorControllerItem(SID_CURRENTTAB,*this,rBindings));
392  mvBoundItems[2].reset(new ScNavigatorControllerItem(SID_CURRENTDOC,*this,rBindings));
393  mvBoundItems[3].reset(new ScNavigatorControllerItem(SID_SELECT_SCENARIO,*this,rBindings));
394 
395  rBindings.LEAVEREGISTRATIONS();
396 
397  StartListening( *(SfxGetpApp()) );
399 
400  // was a category chosen as root?
401  ScContentId nLastRoot = rCfg.GetRootType();
402  if ( nLastRoot != ScContentId::ROOT )
403  m_xLbEntries->SetRootType( nLastRoot );
404 
405  GetDocNames(nullptr);
406 
407  UpdateButtons();
408 
409  UpdateColumn();
410  UpdateRow();
411  UpdateTable(nullptr);
412  m_xLbEntries->hide();
413  m_xScenarioBox->hide();
414 
415  aContentIdle.SetInvokeHandler( LINK( this, ScNavigatorDlg, TimeHdl ) );
416  aContentIdle.SetPriority( TaskPriority::LOWEST );
417 
418  m_xLbEntries->SetNavigatorDlgFlag(true);
419 
420  // if scenario was active, switch on
421  NavListMode eNavMode = static_cast<NavListMode>(rCfg.GetListMode());
422  if (eNavMode == NAV_LMODE_SCENARIOS)
423  m_xTbxCmd2->set_item_active("scenarios", true);
424  else
425  eNavMode = NAV_LMODE_AREAS;
426  SetListMode(eNavMode);
427 }
428 
430 {
431  if (m_xNavigatorDlg)
432  return m_xNavigatorDlg->GetFrameWeld();
433  return PanelLayout::GetFrameWeld();
434 }
435 
437 {
438  if (ScViewData* pData = GetViewData())
439  {
440  ScDocument& rDoc = pData->GetDocument();
441  m_xEdRow->set_range(1, SCNAV_MAXROW(rDoc.GetSheetLimits()));
442  m_xEdCol->set_range(1, SCNAV_MAXCOL(rDoc.GetSheetLimits()));
443  m_xEdCol->set_width_chars(SCNAV_COLDIGITS(rDoc.GetSheetLimits())); // 1...256...18278 or A...IV...ZZZ
444  }
445 }
446 
448 {
449  // When the navigator is displayed in the sidebar, or is otherwise
450  // docked, it has the whole deck to fill. Therefore hide the button that
451  // hides all controls below the top two rows of buttons.
452  m_xTbxCmd1->set_item_visible("contents", ParentIsFloatingWindow(m_xNavigatorDlg));
453 }
454 
456 {
457  SfxNavigator::StateChanged(nStateChange);
458  if (nStateChange == StateChangedType::InitShow)
459  m_xNavigator->UpdateInitShow();
460 }
461 
463 {
464  aContentIdle.Stop();
465 
466  for (auto & p : mvBoundItems)
467  p.reset();
468  pMarkArea.reset();
469 
470  EndListening( *(SfxGetpApp()) );
472 
473  m_xEdCol.reset();
474  m_xEdRow.reset();
475  m_xTbxCmd1.reset();
476  m_xTbxCmd2.reset();
477  m_xDragModeMenu.reset();
478  m_xLbEntries.reset();
479  m_xWndScenarios.reset();
480  m_xScenarioBox.reset();
481  m_xLbDocuments.reset();
482 }
483 
485 {
486  if (const SfxEventHint* pHint = dynamic_cast<const SfxEventHint*>(&rHint))
487  {
488  if (pHint->GetEventId() == SfxEventHintId::ActivateDoc)
489  {
491  bool bRefreshed = m_xLbEntries->ActiveDocChanged();
492  // UpdateAll just possibly calls Refresh (and always
493  // ContentUpdated) so if ActiveDocChanged already called Refresh
494  // skip re-calling it
495  if (bRefreshed)
496  ContentUpdated();
497  else
498  UpdateAll();
499  }
500  }
501  else
502  {
503  const SfxHintId nHintId = rHint.GetId();
504 
505  if (nHintId == SfxHintId::ScDocNameChanged)
506  {
507  m_xLbEntries->ActiveDocChanged();
508  }
509  else if (NAV_LMODE_NONE == eListMode)
510  {
511  // Table not any more
512  }
513  else
514  {
515  switch ( nHintId )
516  {
517  case SfxHintId::ScTablesChanged:
518  m_xLbEntries->Refresh( ScContentId::TABLE );
519  break;
520 
521  case SfxHintId::ScDbAreasChanged:
522  m_xLbEntries->Refresh( ScContentId::DBAREA );
523  break;
524 
525  case SfxHintId::ScAreasChanged:
527  break;
528 
529  case SfxHintId::ScDrawChanged:
533  break;
534 
535  case SfxHintId::ScAreaLinksChanged:
537  break;
538 
539  // SfxHintId::DocChanged not only at document change
540 
541  case SfxHintId::ScNavigatorUpdateAll:
542  UpdateAll();
543  break;
544 
545  case SfxHintId::ScDataChanged:
546  case SfxHintId::ScAnyDataChanged:
547  aContentIdle.Start(); // Do not search notes immediately
548  break;
549  case SfxHintId::ScSelectionChanged:
550  UpdateSelection();
551  break;
552  default:
553  break;
554  }
555  }
556  }
557 }
558 
559 IMPL_LINK( ScNavigatorDlg, TimeHdl, Timer*, pIdle, void )
560 {
561  if ( pIdle != &aContentIdle )
562  return;
563 
564  m_xLbEntries->Refresh( ScContentId::NOTE );
565 }
566 
567 void ScNavigatorDlg::SetDropMode(sal_uInt16 nNew)
568 {
569  nDropMode = nNew;
570  UpdateButtons();
571  ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
572  rCfg.SetDragMode(nDropMode);
573 }
574 
576 {
577  if ((nColNo+1 == nCurCol) && (nRowNo+1 == nCurRow))
578  return;
579 
580  // SID_CURRENTCELL == Item #0 clear cache, so it's possible
581  // setting the current cell even in combined areas
582  mvBoundItems[0]->ClearCache();
583 
584  ScAddress aScAddress( nColNo, nRowNo, 0 );
585  OUString aAddr(aScAddress.Format(ScRefFlags::ADDR_ABS));
586 
587  bool bUnmark = false;
588  if ( GetViewData() )
589  bUnmark = !pViewData->GetMarkData().IsCellMarked( nColNo, nRowNo );
590 
591  SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
592  SfxBoolItem aUnmarkItem( FN_PARAM_1, bUnmark ); // cancel selection
593 
594  rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL,
595  SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
596  { &aPosItem, &aUnmarkItem });
597 }
598 
599 void ScNavigatorDlg::SetCurrentCellStr( const OUString& rName )
600 {
601  mvBoundItems[0]->ClearCache();
602  SfxStringItem aNameItem( SID_CURRENTCELL, rName );
603 
604  rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL,
605  SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
606  { &aNameItem });
607 }
608 
610 {
611  if ( nTabNo != nCurTab )
612  {
613  // Table for basic is base-1
614  SfxUInt16Item aTabItem( SID_CURRENTTAB, static_cast<sal_uInt16>(nTabNo) + 1 );
615  rBindings.GetDispatcher()->ExecuteList(SID_CURRENTTAB,
616  SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
617  { &aTabItem });
618  }
619 }
620 
621 void ScNavigatorDlg::SetCurrentTableStr( std::u16string_view rName )
622 {
623  if (!GetViewData()) return;
624 
625  ScDocument& rDoc = pViewData->GetDocument();
626  SCTAB nCount = rDoc.GetTableCount();
627  OUString aTabName;
628  SCTAB nLastSheet = 0;
629 
630  for (SCTAB i = 0; i<nCount; i++)
631  {
632  rDoc.GetName(i, aTabName);
633  if (aTabName == rName)
634  {
635  // Check if this is a Scenario sheet and if so select the sheet
636  // where it belongs to, which is the previous non-Scenario sheet.
637  if (rDoc.IsScenario(i))
638  {
639  SetCurrentTable(nLastSheet);
640  return;
641  }
642  else
643  {
645  return;
646  }
647  }
648  else
649  {
650  if (!rDoc.IsScenario(i))
651  nLastSheet = i;
652  }
653  }
654 }
655 
656 void ScNavigatorDlg::SetCurrentObject( const OUString& rName )
657 {
658  SfxStringItem aNameItem( SID_CURRENTOBJECT, rName );
659  rBindings.GetDispatcher()->ExecuteList( SID_CURRENTOBJECT,
660  SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
661  { &aNameItem });
662 }
663 
664 void ScNavigatorDlg::SetCurrentDoc( const OUString& rDocName ) // activate
665 {
666  SfxStringItem aDocItem( SID_CURRENTDOC, rDocName );
667  rBindings.GetDispatcher()->ExecuteList( SID_CURRENTDOC,
668  SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
669  { &aDocItem });
670 }
671 
673 {
674  ScTabViewShell* pViewSh = GetTabViewShell();
675  if( !pViewSh )
676  return;
677 
678  uno::Reference< drawing::XShapes > xShapes = pViewSh->getSelectedXShapes();
679  if( !xShapes )
680  return;
681 
682  uno::Reference< container::XIndexAccess > xIndexAccess(
683  xShapes, uno::UNO_QUERY_THROW );
684  if( xIndexAccess->getCount() > 1 )
685  return;
686  uno::Reference< drawing::XShape > xShape;
687  if( xIndexAccess->getByIndex(0) >>= xShape )
688  {
689  uno::Reference< container::XNamed > xNamed( xShape, uno::UNO_QUERY_THROW );
690  OUString sName = xNamed->getName();
691  if (!sName.isEmpty())
692  {
693  m_xLbEntries->SelectEntryByName( ScContentId::DRAWING, sName );
694  }
695  }
696 }
697 
699 {
700  return dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
701 }
702 
704 {
705  // Don't store the settings pointer here, because the settings belong to
706  // the view, and the view may be closed while the navigator is open (reload).
707  // If the pointer is cached here again later for performance reasons, it has to
708  // be forgotten when the view is closed.
709 
710  ScTabViewShell* pViewSh = GetTabViewShell();
711  return pViewSh ? pViewSh->GetNavigatorSettings() : nullptr;
712 }
713 
715 {
716  ScTabViewShell* pViewSh = GetTabViewShell();
717  pViewData = pViewSh ? &pViewSh->GetViewData() : nullptr;
718  return pViewData;
719 }
720 
722 {
723  if ( pCol )
724  nCurCol = *pCol;
725  else if ( GetViewData() )
726  nCurCol = pViewData->GetCurX() + 1;
727 
728  m_xEdCol->set_value(nCurCol);
729 }
730 
731 void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
732 {
733  if ( pRow )
734  nCurRow = *pRow;
735  else if ( GetViewData() )
736  nCurRow = pViewData->GetCurY() + 1;
737 
738  m_xEdRow->set_value(nCurRow);
739 }
740 
742 {
743  if ( pTab )
744  nCurTab = *pTab;
745  else if ( GetViewData() )
747 }
748 
750 {
751  switch (eListMode)
752  {
753  case NAV_LMODE_AREAS:
754  m_xLbEntries->Refresh();
755  break;
756  case NAV_LMODE_NONE:
758  break;
759  default:
760  break;
761  }
762  ContentUpdated(); // not again
763 }
764 
766 {
767  aContentIdle.Stop();
768 }
769 
771 {
772  if (eMode != eListMode)
773  {
774  bool bForceParentResize = ParentIsFloatingWindow(m_xNavigatorDlg) &&
775  (eMode == NAV_LMODE_NONE || eListMode == NAV_LMODE_NONE);
776  SfxNavigator* pNav = bForceParentResize ? m_xNavigatorDlg.get() : nullptr;
777  if (pNav && eMode == NAV_LMODE_NONE) //save last normal size on minimizing
778  aExpandedSize = pNav->GetSizePixel();
779 
780  eListMode = eMode;
781 
782  switch (eMode)
783  {
784  case NAV_LMODE_NONE:
785  ShowList(false);
786  break;
787  case NAV_LMODE_AREAS:
788  m_xLbEntries->Refresh();
789  ShowList(true);
790  break;
791  case NAV_LMODE_SCENARIOS:
792  ShowScenarios();
793  break;
794  }
795 
796  UpdateButtons();
797 
798  if (eMode != NAV_LMODE_NONE)
799  {
800  ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
801  rCfg.SetListMode( static_cast<sal_uInt16>(eMode) );
802  }
803 
804  if (pNav)
805  {
806  pNav->InvalidateChildSizeCache();
807  Size aOptimalSize(pNav->GetOptimalSize());
808  Size aNewSize(pNav->GetOutputSizePixel());
809  aNewSize.setHeight( eMode == NAV_LMODE_NONE ? aOptimalSize.Height() : aExpandedSize.Height() );
810  pNav->SetMinOutputSizePixel(aOptimalSize);
811  pNav->SetOutputSizePixel(aNewSize);
812  }
813  }
814 
815  if (pMarkArea)
816  UnmarkDataArea();
817 }
818 
819 void ScNavigatorDlg::ShowList(bool bShow)
820 {
821  if (bShow)
822  {
823  m_xLbEntries->show();
824  m_xLbDocuments->show();
825  }
826  else
827  {
828  m_xLbEntries->hide();
829  m_xLbDocuments->hide();
830  }
831  m_xScenarioBox->hide();
832 }
833 
835 {
836  rBindings.Invalidate( SID_SELECT_SCENARIO );
837  rBindings.Update( SID_SELECT_SCENARIO );
838 
839  m_xScenarioBox->show();
840  m_xLbDocuments->show();
841  m_xLbEntries->hide();
842 }
843 
844 // documents for Dropdown-Listbox
845 void ScNavigatorDlg::GetDocNames( const OUString* pManualSel )
846 {
847  m_xLbDocuments->clear();
848  m_xLbDocuments->freeze();
849 
850  ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
851 
852  OUString aSelEntry;
854  while ( pSh )
855  {
856  if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
857  {
858  OUString aName = pSh->GetTitle();
859  OUString aEntry = aName;
860  if (pSh == pCurrentSh)
861  aEntry += aStrActive;
862  else
863  aEntry += aStrNotActive;
864  m_xLbDocuments->append_text(aEntry);
865 
866  if ( pManualSel ? ( aName == *pManualSel )
867  : ( pSh == pCurrentSh ) )
868  aSelEntry = aEntry; // complete entry for selection
869  }
870 
871  pSh = SfxObjectShell::GetNext( *pSh );
872  }
873 
874  m_xLbDocuments->append_text(aStrActiveWin);
875 
876  OUString aHidden = m_xLbEntries->GetHiddenTitle();
877  if (!aHidden.isEmpty())
878  {
879  OUString aEntry = aHidden + aStrHidden;
880  m_xLbDocuments->append_text(aEntry);
881 
882  if ( pManualSel && aHidden == *pManualSel )
883  aSelEntry = aEntry;
884  }
885 
886  m_xLbDocuments->thaw();
887 
888  m_xLbDocuments->set_active_text(aSelEntry);
889 }
890 
892 {
893  ScTabViewShell* pViewSh = GetTabViewShell();
894 
895  if ( !pViewSh )
896  return;
897 
898  if ( !pMarkArea )
899  pMarkArea.reset( new ScArea );
900 
901  pViewSh->MarkDataArea();
902  ScRange aMarkRange;
903  pViewSh->GetViewData().GetMarkData().GetMarkArea(aMarkRange);
904  pMarkArea->nColStart = aMarkRange.aStart.Col();
905  pMarkArea->nRowStart = aMarkRange.aStart.Row();
906  pMarkArea->nColEnd = aMarkRange.aEnd.Col();
907  pMarkArea->nRowEnd = aMarkRange.aEnd.Row();
908  pMarkArea->nTab = aMarkRange.aStart.Tab();
909 }
910 
912 {
913  ScTabViewShell* pViewSh = GetTabViewShell();
914 
915  if ( pViewSh )
916  {
917  pViewSh->Unmark();
918  pMarkArea.reset();
919  }
920 }
921 
923 {
924  // pMarkArea evaluate ???
925 
926  if ( GetViewData() )
927  {
928  ScMarkData& rMark = pViewData->GetMarkData();
929  ScRange aMarkRange;
930  rMark.GetMarkArea( aMarkRange );
931 
932  SCCOL nCol = aMarkRange.aStart.Col();
933  SCROW nRow = aMarkRange.aStart.Row();
934 
935  if ( (nCol+1 != m_xEdCol->get_value()) || (nRow+1 != m_xEdRow->get_value()) )
936  SetCurrentCell( nCol, nRow );
937  }
938 }
939 
941 {
942  // pMarkArea evaluate ???
943 
944  if ( GetViewData() )
945  {
946  ScMarkData& rMark = pViewData->GetMarkData();
947  ScRange aMarkRange;
948  rMark.GetMarkArea( aMarkRange );
949 
950  SCCOL nCol = aMarkRange.aEnd.Col();
951  SCROW nRow = aMarkRange.aEnd.Row();
952 
953  if ( (nCol+1 != m_xEdCol->get_value()) || (nRow+1 != m_xEdRow->get_value()) )
954  SetCurrentCell( nCol, nRow );
955  }
956 }
957 
959 
961  SfxBindings* pBindings, SfxChildWinInfo* pInfo)
962  : SfxNavigatorWrapper(_pParent, nId)
963 {
964  SetWindow(VclPtr<ScNavigatorWin>::Create(pBindings, this, _pParent, pInfo));
965  Initialize();
966 }
967 
968 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3108
std::unique_ptr< weld::ComboBox > m_xLbDocuments
Definition: navipi.hxx:104
sal_uInt16 GetDragMode() const
Definition: navicfg.hxx:41
SC_DLLPUBLIC void Format(OStringBuffer &r, ScRefFlags nFlags, const ScDocument *pDocument=nullptr, const Details &rDetails=detailsOOOa1) const
Definition: address.cxx:2116
void UpdateInitShow()
Definition: navipi.cxx:447
void MarkDataArea(bool bIncludeCursor=true)
Definition: tabview3.cxx:1656
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
virtual ~ScNavigatorWin() override
Definition: navipi.cxx:325
ScAddress aStart
Definition: address.hxx:499
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:42
void SetMinOutputSizePixel(const Size &rSize)
OUString ScResId(TranslateId aId)
Definition: scdll.cxx:89
SCROW Row() const
Definition: address.hxx:261
void SetCurrentTable(SCTAB nTab)
Definition: navipi.cxx:609
OUString GetTitle(sal_uInt16 nMaxLen=0) const
ScViewData * pViewData
Definition: navipi.hxx:118
std::unique_ptr< ContentProperties > pData
ScNavigatorWin(SfxBindings *_pBindings, SfxChildWindow *pMgr, vcl::Window *pParent, SfxChildWinInfo *pInfo)
Definition: navipi.cxx:331
void UpdateSheetLimits()
Definition: navipi.cxx:436
SCROW nCurRow
Definition: navipi.hxx:123
SCCOL GetMaxColCount() const
Definition: sheetlimits.hxx:63
SCROW GetCurY() const
Definition: viewdata.hxx:401
void EndOfDataArea()
Definition: navipi.cxx:940
void UpdateTable(const SCTAB *pTab)
Definition: navipi.cxx:741
void ScColToAlpha(OUStringBuffer &rBuf, SCCOL nCol)
append alpha representation of column to buffer
Definition: address.cxx:1926
SCTAB GetTabNo() const
Definition: viewdata.hxx:394
OUString aStrNotActive
Definition: navipi.hxx:113
Contains settings of the navigator listbox.
Definition: navsett.hxx:29
void SetWindow(const VclPtr< vcl::Window > &p)
void Unmark()
Definition: tabview3.cxx:1723
ScAddress aEnd
Definition: address.hxx:500
ScDocument & GetDocument() const
Definition: viewdata.hxx:379
static SfxObjectShell * Current()
std::unique_ptr< weld::SpinButton > m_xEdCol
Definition: navipi.hxx:97
void Invalidate(sal_uInt16 nId)
SCROW GetMaxRowCount() const
Definition: sheetlimits.hxx:61
virtual weld::Window * GetFrameWeld() const override
Definition: navipi.cxx:429
SfxHintId GetId() const
virtual void StateChanged(StateChangedType nStateChange) override
Definition: navipi.cxx:455
void GetDocNames(const OUString *pSelEntry)
Definition: navipi.cxx:845
void fill(V val)
bool IsCellMarked(SCCOL nCol, SCROW nRow, bool bNoSimple=false) const
Definition: markdata.cxx:284
SfxApplication * SfxGetpApp()
css::uno::Reference< css::drawing::XShapes > getSelectedXShapes()
Definition: viewuno.cxx:821
void GetMarkArea(ScRange &rRange) const
Definition: markdata.cxx:111
void UpdateAll()
Definition: navipi.cxx:749
StateChangedType
void StartOfDataArea()
Definition: navipi.cxx:922
o3tl::enumarray< ScContentId, bool > maExpandedVec
Definition: navsett.hxx:32
SCCOL nCurCol
Definition: navipi.hxx:122
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:314
int nCount
static SfxViewShell * Current()
Mode eMode
SCTAB Tab() const
Definition: address.hxx:270
void SetCurrentObject(const OUString &rName)
Definition: navipi.cxx:656
const char * sName
ScViewData & GetViewData()
Definition: tabview.hxx:333
std::unique_ptr< ScNavigatorDlg > m_xNavigator
Definition: navipi.cxx:315
void ShowScenarios()
Definition: navipi.cxx:834
std::unique_ptr< ScScenarioWindow > m_xWndScenarios
Definition: navipi.hxx:103
std::unique_ptr< ScArea > pMarkArea
Definition: navipi.hxx:117
OUString aStrActiveWin
Definition: navipi.hxx:115
std::unique_ptr< weld::Toolbar > m_xTbxCmd2
Definition: navipi.hxx:100
ScContentId GetRootType() const
Definition: navicfg.hxx:43
int i
std::unique_ptr< weld::Box > m_xContainer
NavListMode eListMode
Definition: navipi.hxx:120
sal_Int16 SCCOL
Definition: types.hxx:21
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: navipi.cxx:484
#define SC_MOD()
Definition: scmod.hxx:250
Idle aContentIdle
Definition: navipi.hxx:110
void SetCurrentTableStr(std::u16string_view rName)
Definition: navipi.cxx:621
void UpdateButtons()
Definition: navipi.cxx:270
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:873
ScNavigatorSettings * GetNavigatorSettings()
Definition: tabvwsh4.cxx:1851
static ScTabViewShell * GetTabViewShell()
Definition: navipi.cxx:698
void ShowList(bool bShow)
Definition: navipi.cxx:819
void SetDragMode(sal_uInt16 nNew)
Definition: navicfg.cxx:42
void SetCurrentDoc(const OUString &rDocName)
Definition: navipi.cxx:664
void UpdateRow(const SCROW *pRow=nullptr)
Definition: navipi.cxx:731
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
ScContentId
Definition: content.hxx:34
void GrabFocus()
std::array< std::unique_ptr< ScNavigatorControllerItem >, CTRL_ITEMS > mvBoundItems
Definition: navipi.hxx:126
bool ParentIsFloatingWindow(const vcl::Window *pParent)
SCCOL Col() const
Definition: address.hxx:266
virtual void StateChanged(StateChangedType nStateChange) override
void SetCurrentCellStr(const OUString &rName)
Definition: navipi.cxx:599
void UnmarkDataArea()
Definition: navipi.cxx:911
friend class ScNavigatorControllerItem
Definition: navipi.hxx:89
void Update(sal_uInt16 nId)
bool AlphaToCol(const ScDocument &rDoc, SCCOL &rCol, const OUString &rStr)
get column number of A..IV... string
Definition: address.cxx:2541
sal_Int32 SCROW
Definition: types.hxx:17
std::unique_ptr< weld::Widget > m_xScenarioBox
Definition: navipi.hxx:102
ScNavigatorWrapper(vcl::Window *pParent, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo *pInfo)
Definition: navipi.cxx:960
static ScNavigatorSettings * GetNavigatorSettings()
Definition: navipi.cxx:703
void Stop()
SC_DLLPUBLIC bool IsScenario(SCTAB nTab) const
Definition: documen3.cxx:432
void UpdateSelection()
Definition: navipi.cxx:672
OUString aStrHidden
Definition: navipi.hxx:114
constexpr tools::Long Height() const
static SfxObjectShell * GetFirst(const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
void ContentUpdated()
Definition: navipi.cxx:765
std::unique_ptr< weld::Menu > m_xDragModeMenu
Definition: navipi.hxx:105
ScNavigatorSettings()
Index of selected child entry.
Definition: navipi.cxx:305
OUString aName
std::unique_ptr< ScContentTree > m_xLbEntries
Definition: navipi.hxx:101
SfxBindings & rBindings
Definition: navipi.hxx:95
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
void SetCurrentCell(SCCOL nCol, SCROW Row)
Definition: navipi.cxx:575
sal_uInt16 GetListMode() const
Definition: navicfg.hxx:39
ScNavigatorDlg(SfxBindings *pB, weld::Widget *pParent, SfxNavigator *pNavigatorDlg)
Definition: navipi.cxx:339
void * p
void SetInvokeHandler(const Link< Timer *, void > &rLink)
vcl::Window * GetWindow() const
static bool isAsciiNumeric(const OUString &rStr)
ROOT
void setHeight(tools::Long nHeight)
virtual void Start(bool bStartTimer=true) override
void SetDropMode(sal_uInt16 nNew)
Definition: navipi.cxx:567
SfxDispatcher * GetDispatcher() const
virtual weld::Window * GetFrameWeld() const
reference_type * get() const
Any result
static SfxObjectShell * GetNext(const SfxObjectShell &rPrev, const std::function< bool(const SfxObjectShell *)> &isObjectShell=nullptr, bool bOnlyVisible=true)
void SetPriority(TaskPriority ePriority)
static void ReleaseFocus()
Definition: navipi.cxx:65
std::unique_ptr< weld::SpinButton > m_xEdRow
Definition: navipi.hxx:98
void SetListMode(NavListMode eMode)
Definition: navipi.cxx:770
ScViewData * GetViewData()
Definition: navipi.cxx:714
void UpdateColumn(const SCCOL *pCol=nullptr)
Definition: navipi.cxx:721
virtual ~ScNavigatorDlg() override
Definition: navipi.cxx:462
virtual void dispose() override
static bool isAsciiAlpha(const OUString &rStr)
VclPtr< SfxNavigator > m_xNavigatorDlg
Definition: navipi.hxx:107
SfxChildWindow * pMgr
OUString aStrActive
Definition: navipi.hxx:112
aStr
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:213
Size aExpandedSize
Definition: navipi.hxx:109
void MarkDataArea()
Definition: navipi.cxx:891
sal_uInt16 nDropMode
Definition: navipi.hxx:121
SCTAB nCurTab
Definition: navipi.hxx:124
sal_Int16 SCTAB
Definition: types.hxx:22
void SetListMode(sal_uInt16 nNew)
Definition: navicfg.cxx:33
virtual void dispose() override
Definition: navipi.cxx:320
SCCOL GetCurX() const
Definition: viewdata.hxx:400
const sal_uLong SC_CONTENT_NOCHILD
Definition: content.hxx:40
std::unique_ptr< weld::Toolbar > m_xTbxCmd1
Definition: navipi.hxx:99