Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / navipi / navipi.cxx
blob8ed6c4815c0860837289590d779f8d08eb6bb7d6
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 .
20 #include <rangelst.hxx>
21 #include <sfx2/app.hxx>
22 #include <sfx2/bindings.hxx>
23 #include <sfx2/dispatch.hxx>
24 #include <sfx2/event.hxx>
25 #include <sfx2/imgmgr.hxx>
26 #include <sfx2/navigat.hxx>
27 #include <svl/stritem.hxx>
28 #include <svl/urlbmk.hxx>
29 #include <vcl/settings.hxx>
30 #include <unotools/charclass.hxx>
31 #include <stdlib.h>
33 #include "viewdata.hxx"
34 #include "tabvwsh.hxx"
35 #include "docsh.hxx"
36 #include "document.hxx"
37 #include "dbdata.hxx"
38 #include "rangenam.hxx"
39 #include "rangeutl.hxx"
40 #include "popmenu.hxx"
41 #include "scresid.hxx"
42 #include "scmod.hxx"
43 #include "navicfg.hxx"
44 #include "navcitem.hxx"
45 #include "navipi.hrc"
46 #include "navipi.hxx"
47 #include "navsett.hxx"
48 #include "markdata.hxx"
50 #include <algorithm>
52 // tolerance, how much spac above the folded size is still small
53 #define SCNAV_MINTOL 5
55 // maximum values for UI
56 #define SCNAV_MAXCOL (MAXCOLCOUNT)
57 // macro is sufficient since only used in ctor
58 #define SCNAV_COLDIGITS (static_cast<sal_Int32>( floor( log10( static_cast<double>(SCNAV_MAXCOL)))) + 1) // 1...256...18278
59 // precomputed constant because it is used in every change of spin button field
60 static const sal_Int32 SCNAV_COLLETTERS = ::ScColToAlpha(SCNAV_MAXCOL).getLength(); // A...IV...ZZZ
62 #define SCNAV_MAXROW (MAXROWCOUNT)
64 void ScNavigatorDlg::ReleaseFocus()
66 SfxViewShell* pCurSh = SfxViewShell::Current();
68 if ( pCurSh )
70 vcl::Window* pShellWnd = pCurSh->GetWindow();
71 if ( pShellWnd )
72 pShellWnd->GrabFocus();
76 // class ColumnEdit
78 ColumnEdit::ColumnEdit( ScNavigatorDlg* pParent, const ResId& rResId )
79 : SpinField ( pParent, rResId ),
80 rDlg ( *pParent ),
81 nCol ( 0 ),
82 nKeyGroup ( KEYGROUP_ALPHA )
84 SetMaxTextLen( SCNAV_COLDIGITS ); // 1...256...18278 or A...IV...ZZZ
87 ColumnEdit::~ColumnEdit()
91 bool ColumnEdit::Notify( NotifyEvent& rNEvt )
93 bool bHandled = SpinField::Notify( rNEvt );
95 MouseNotifyEvent nType = rNEvt.GetType();
96 if ( nType == MouseNotifyEvent::KEYINPUT )
98 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
99 vcl::KeyCode aCode = pKEvt->GetKeyCode();
101 if ( !aCode.IsMod1() && !aCode.IsMod2() )
103 //! Input Validation (only alphanumerics, max 2-3 digits)
104 //! was before VCL not forwarded keyinput
105 //! rethink this!!!
107 if ( aCode.GetCode() == KEY_RETURN )
109 ScNavigatorDlg::ReleaseFocus();
110 ExecuteCol();
111 bHandled = true;
115 else if ( nType == MouseNotifyEvent::LOSEFOCUS ) // LoseFocus not called at VCL
116 EvalText(); // nCol set
118 return bHandled;
121 void ColumnEdit::LoseFocus()
123 EvalText();
126 void ColumnEdit::Up()
128 nCol++;
130 if ( nCol <= SCNAV_MAXCOL )
131 SetCol( nCol );
132 else
133 nCol--;
136 void ColumnEdit::Down()
138 if ( nCol>1 )
139 SetCol( nCol-1 );
142 void ColumnEdit::First()
144 nCol = 1;
145 SetText(OUString('A'));
148 void ColumnEdit::Last()
150 OUString aStr;
151 nCol = NumToAlpha( SCNAV_MAXCOL, aStr );
152 SetText( aStr );
155 void ColumnEdit::EvalText()
157 OUString aStrCol = GetText();
159 if (!aStrCol.isEmpty())
161 // nKeyGroup is no longer set at VCL, in cause of lack of keyinput
163 if ( CharClass::isAsciiNumeric(aStrCol) )
164 nCol = NumStrToAlpha( aStrCol );
165 else
166 nCol = AlphaToNum( aStrCol );
168 else
169 nCol = 0;
171 SetText( aStrCol );
172 nKeyGroup = KEYGROUP_ALPHA;
175 void ColumnEdit::ExecuteCol()
177 SCROW nRow = rDlg.aEdRow->GetRow();
179 EvalText(); // setzt nCol
181 if ( (nCol > 0) && (nRow > 0) )
182 rDlg.SetCurrentCell( nCol-1, nRow-1 );
185 void ColumnEdit::SetCol( SCCOL nColNo )
187 OUString aStr;
189 if ( nColNo == 0 )
191 nCol = 0;
192 SetText( aStr );
194 else
196 nColNo = NumToAlpha( nColNo, aStr );
197 nCol = nColNo;
198 SetText( aStr );
202 SCCOL ColumnEdit::AlphaToNum( OUString& rStr )
204 SCCOL nColumn = 0;
206 if ( CharClass::isAsciiAlpha( rStr) )
208 rStr = rStr.toAsciiUpperCase();
210 if (::AlphaToCol( nColumn, rStr))
211 ++nColumn;
213 if ( (rStr.getLength() > SCNAV_COLLETTERS) || (nColumn > SCNAV_MAXCOL) )
215 nColumn = SCNAV_MAXCOL;
216 NumToAlpha( nColumn, rStr );
219 else
220 rStr.clear();
222 return nColumn;
225 SCCOL ColumnEdit::NumStrToAlpha( OUString& rStr )
227 SCCOL nColumn = 0;
229 if ( CharClass::isAsciiNumeric(rStr) )
230 nColumn = NumToAlpha( (SCCOL)rStr.toInt32(), rStr );
231 else
232 rStr.clear();
234 return nColumn;
237 SCCOL ColumnEdit::NumToAlpha( SCCOL nColNo, OUString& rStr )
239 if ( nColNo > SCNAV_MAXCOL )
240 nColNo = SCNAV_MAXCOL;
241 else if ( nColNo < 1 )
242 nColNo = 1;
244 ::ScColToAlpha( rStr, nColNo - 1);
246 return nColNo;
249 // class RowEdit
251 RowEdit::RowEdit( ScNavigatorDlg* pParent, const ResId& rResId )
252 : NumericField( pParent, rResId ),
253 rDlg ( *pParent )
255 SetMax( SCNAV_MAXROW);
256 SetLast( SCNAV_MAXROW);
259 RowEdit::~RowEdit()
263 bool RowEdit::Notify( NotifyEvent& rNEvt )
265 bool bHandled = NumericField::Notify( rNEvt );
267 if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
269 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
270 vcl::KeyCode aCode = pKEvt->GetKeyCode();
271 if ( aCode.GetCode() == KEY_RETURN && !aCode.IsMod1() && !aCode.IsMod2() )
273 ScNavigatorDlg::ReleaseFocus();
274 ExecuteRow();
275 bHandled = true;
279 return bHandled;
282 void RowEdit::LoseFocus()
286 void RowEdit::ExecuteRow()
288 SCCOL nCol = rDlg.aEdCol->GetCol();
289 SCROW nRow = (SCROW)GetValue();
291 if ( (nCol > 0) && (nRow > 0) )
292 rDlg.SetCurrentCell( nCol-1, nRow-1 );
295 // class ScDocListBox
297 ScDocListBox::ScDocListBox( ScNavigatorDlg* pParent, const ResId& rResId )
298 : ListBox ( pParent, rResId ),
299 rDlg ( *pParent )
303 ScDocListBox::~ScDocListBox()
307 void ScDocListBox::Select()
309 ScNavigatorDlg::ReleaseFocus();
311 OUString aDocName = GetSelectEntry();
312 rDlg.aLbEntries->SelectDoc( aDocName );
315 // class CommandToolBox
317 CommandToolBox::CommandToolBox( ScNavigatorDlg* pParent, const ResId& rResId )
318 : ToolBox ( pParent, rResId ),
319 rDlg ( *pParent )
321 InitImageList(); // ImageList members of ScNavigatorDlg must be initialized before!
323 SetSizePixel( CalcWindowSizePixel() );
324 SetDropdownClickHdl( LINK(this, CommandToolBox, ToolBoxDropdownClickHdl) );
325 SetItemBits( IID_DROPMODE, GetItemBits( IID_DROPMODE ) | ToolBoxItemBits::DROPDOWNONLY );
328 CommandToolBox::~CommandToolBox()
332 void CommandToolBox::Select( sal_uInt16 nSelId )
334 // Modus umschalten ?
336 if ( nSelId == IID_ZOOMOUT || nSelId == IID_SCENARIOS )
338 NavListMode eOldMode = rDlg.eListMode;
339 NavListMode eNewMode;
341 if ( nSelId == IID_SCENARIOS )
343 if ( eOldMode == NAV_LMODE_SCENARIOS )
344 eNewMode = NAV_LMODE_AREAS;
345 else
346 eNewMode = NAV_LMODE_SCENARIOS;
348 else // on/off
350 if ( eOldMode == NAV_LMODE_NONE )
351 eNewMode = NAV_LMODE_AREAS;
352 else
353 eNewMode = NAV_LMODE_NONE;
355 rDlg.SetListMode( eNewMode );
356 UpdateButtons();
358 else
359 switch ( nSelId )
361 case IID_DATA:
362 rDlg.MarkDataArea();
363 break;
364 case IID_UP:
365 rDlg.StartOfDataArea();
366 break;
367 case IID_DOWN:
368 rDlg.EndOfDataArea();
369 break;
370 case IID_CHANGEROOT:
371 rDlg.aLbEntries->ToggleRoot();
372 UpdateButtons();
373 break;
377 void CommandToolBox::Select()
379 Select( GetCurItemId() );
382 void CommandToolBox::Click()
386 IMPL_LINK_NOARG_TYPED(CommandToolBox, ToolBoxDropdownClickHdl, ToolBox *, void)
388 // the popup menue of the drop modus has to be called in the
389 // click (button down) and not in the select (button up)
391 if ( GetCurItemId() == IID_DROPMODE )
393 ScPopupMenu aPop( ScResId( RID_POPUP_DROPMODE ) );
394 aPop.CheckItem( RID_DROPMODE_URL + rDlg.GetDropMode() );
395 aPop.Execute( this, GetItemRect(IID_DROPMODE), PopupMenuFlags::ExecuteDown );
396 sal_uInt16 nId = aPop.GetSelected();
398 EndSelection(); // bevore SetDropMode (SetDropMode calls SetItemImage)
400 if ( nId >= RID_DROPMODE_URL && nId <= RID_DROPMODE_COPY )
401 rDlg.SetDropMode( nId - RID_DROPMODE_URL );
403 // reset the highlighted button
404 Point aPoint;
405 MouseEvent aLeave( aPoint, 0, MouseEventModifiers::LEAVEWINDOW | MouseEventModifiers::SYNTHETIC );
406 MouseMove( aLeave );
410 void CommandToolBox::UpdateButtons()
412 NavListMode eMode = rDlg.eListMode;
413 CheckItem( IID_SCENARIOS, eMode == NAV_LMODE_SCENARIOS );
414 CheckItem( IID_ZOOMOUT, eMode != NAV_LMODE_NONE );
416 // Umschalten-Button:
417 if ( eMode == NAV_LMODE_SCENARIOS || eMode == NAV_LMODE_NONE )
419 EnableItem( IID_CHANGEROOT, false );
420 CheckItem( IID_CHANGEROOT, false );
422 else
424 EnableItem( IID_CHANGEROOT );
425 bool bRootSet = rDlg.aLbEntries->GetRootType() != ScContentId::ROOT;
426 CheckItem( IID_CHANGEROOT, bRootSet );
429 sal_uInt16 nImageId = 0;
430 switch ( rDlg.nDropMode )
432 case SC_DROPMODE_URL: nImageId = RID_IMG_DROP_URL; break;
433 case SC_DROPMODE_LINK: nImageId = RID_IMG_DROP_LINK; break;
434 case SC_DROPMODE_COPY: nImageId = RID_IMG_DROP_COPY; break;
436 SetItemImage( IID_DROPMODE, Image(ScResId(nImageId)) );
439 void CommandToolBox::InitImageList()
441 ImageList& rImgLst = rDlg.aCmdImageList;
443 sal_uInt16 nCount = GetItemCount();
444 for (sal_uInt16 i = 0; i < nCount; i++)
446 sal_uInt16 nId = GetItemId(i);
447 SetItemImage( nId, rImgLst.GetImage( nId ) );
451 void CommandToolBox::DataChanged( const DataChangedEvent& rDCEvt )
453 if ( rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
455 // update item images
457 InitImageList();
458 UpdateButtons(); // drop mode
461 ToolBox::DataChanged( rDCEvt );
464 // class ScNavigatorSettings
466 ScNavigatorSettings::ScNavigatorSettings() :
467 mnRootSelected( ScContentId::ROOT ),
468 mnChildSelected( SC_CONTENT_NOCHILD )
472 // class ScNavigatorDlgWrapper
474 SFX_IMPL_CHILDWINDOWCONTEXT( ScNavigatorDialogWrapper, SID_NAVIGATOR )
476 ScNavigatorDialogWrapper::ScNavigatorDialogWrapper(
477 vcl::Window* pParent,
478 sal_uInt16 nId,
479 SfxBindings* pBind,
480 SfxChildWinInfo* /* pInfo */ ) :
481 SfxChildWindowContext( nId )
483 pNavigator = VclPtr<ScNavigatorDlg>::Create( pBind, this, pParent, true );
484 SetWindow( pNavigator );
486 // handle configurations elsewhere,
487 // only size of pInfo matters now
489 Size aInfoSize = pParent->GetOutputSizePixel(); // outside defined size
490 Size aNavSize = pNavigator->GetOutputSizePixel(); // Default-Size
492 aNavSize.Width() = std::max( aInfoSize.Width(), aNavSize.Width() );
493 aNavSize.Height() = std::max( aInfoSize.Height(), aNavSize.Height() );
494 pNavigator->nListModeHeight = std::max( aNavSize.Height(), pNavigator->nListModeHeight );
496 // The size could be changed in another module,
497 // therefore we have to or have not to display the content
498 // in dependence of the current size
500 bool bSmall = ( aInfoSize.Height() <= pNavigator->aInitSize.Height() + SCNAV_MINTOL );
501 NavListMode eNavMode = NAV_LMODE_NONE;
502 if (!bSmall)
504 // if scenario was active, switch on
506 ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
507 NavListMode eLastMode = (NavListMode) rCfg.GetListMode();
508 if ( eLastMode == NAV_LMODE_SCENARIOS )
509 eNavMode = NAV_LMODE_SCENARIOS;
510 else
511 eNavMode = NAV_LMODE_AREAS;
514 // Do not set the size of the float again (sal_False at SetListMode), so that the
515 // navigator is not expanded, if it was minimized (#38872#).
517 pNavigator->SetListMode( eNavMode, false ); // FALSE: do not set the Float size
519 sal_uInt16 nCmdId;
520 switch (eNavMode)
522 case NAV_LMODE_SCENARIOS: nCmdId = IID_SCENARIOS; break;
523 case NAV_LMODE_AREAS: nCmdId = IID_AREAS; break;
524 // The following case can never be reach due to how eNavMode is set-up
525 // case NAV_LMODE_DOCS: nCmdId = IID_DOCS; break;
526 // case NAV_LMODE_DBAREAS: nCmdId = IID_DBAREAS; break;
527 default: nCmdId = 0;
529 if (nCmdId)
531 pNavigator->aTbxCmd->CheckItem( nCmdId );
532 pNavigator->DoResize();
535 pNavigator->bFirstBig = ( nCmdId == 0 ); // later
538 void ScNavigatorDialogWrapper::Resizing( Size& rSize )
540 static_cast<ScNavigatorDlg*>(GetWindow())->Resizing(rSize);
543 // class ScNavigatorPI
545 #define CTRL_ITEMS 4
547 #define REGISTER_SLOT(i,id) \
548 ppBoundItems[i]=new ScNavigatorControllerItem(id,*this,rBindings);
550 ScNavigatorDlg::ScNavigatorDlg( SfxBindings* pB, SfxChildWindowContext* pCW, vcl::Window* pParent,
551 const bool bUseStyleSettingsBackground) :
552 Window( pParent, ScResId(RID_SCDLG_NAVIGATOR) ),
553 rBindings ( *pB ), // is used in CommandToolBox ctor
554 aCmdImageList( ScResId( IL_CMD ) ),
555 aFtCol ( VclPtr<FixedInfo>::Create( this, ScResId( FT_COL ) ) ),
556 aEdCol ( VclPtr<ColumnEdit>::Create( this, ScResId( ED_COL ) ) ),
557 aFtRow ( VclPtr<FixedInfo>::Create( this, ScResId( FT_ROW ) ) ),
558 aEdRow ( VclPtr<RowEdit>::Create( this, ScResId( ED_ROW ) ) ),
559 aTbxCmd ( VclPtr<CommandToolBox>::Create( this, ScResId( TBX_CMD ) ) ),
560 aLbEntries ( VclPtr<ScContentTree>::Create( this, ScResId( LB_ENTRIES ) ) ),
561 aWndScenarios( VclPtr<ScScenarioWindow>::Create( this,ScResId( STR_QHLP_SCEN_LISTBOX), ScResId(STR_QHLP_SCEN_COMMENT)) ),
562 aLbDocuments( VclPtr<ScDocListBox>::Create( this, ScResId( LB_DOCUMENTS ) ) ),
563 aStrDragMode ( ScResId( STR_DRAGMODE ) ),
564 aStrDisplay ( ScResId( STR_DISPLAY ) ),
565 aStrActiveWin( ScResId( STR_ACTIVEWIN ) ),
566 pContextWin ( pCW ),
567 pMarkArea ( nullptr ),
568 pViewData ( nullptr ),
569 nListModeHeight( 0 ),
570 nInitListHeight( 0 ),
571 eListMode ( NAV_LMODE_NONE ),
572 nDropMode ( SC_DROPMODE_URL ),
573 nCurCol ( 0 ),
574 nCurRow ( 0 ),
575 nCurTab ( 0 ),
576 bFirstBig ( false ),
577 mbUseStyleSettingsBackground(bUseStyleSettingsBackground)
579 ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
580 nDropMode = rCfg.GetDragMode();
581 // eListMode is set from outside, Root further below
583 aLbDocuments->SetDropDownLineCount(9);
584 OUString aOpen(" (");
585 aStrActive = aOpen;
586 aStrActive += OUString( ScResId( STR_ACTIVE ) );
587 aStrActive += ")"; // " (active)"
588 aStrNotActive = aOpen;
589 aStrNotActive += OUString( ScResId( STR_NOTACTIVE ) );
590 aStrNotActive += ")"; // " (not active)"
591 aStrHidden = aOpen;
592 aStrHidden += OUString( ScResId( STR_HIDDEN ) );
593 aStrHidden += ")"; // " (hidden)"
595 aTitleBase = GetText();
597 const long nListboxYPos =
598 ::std::max(
599 (aTbxCmd->GetPosPixel().Y() + aTbxCmd->GetSizePixel().Height()),
600 (aEdRow->GetPosPixel().Y() + aEdRow->GetSizePixel().Height()) )
601 + 4;
602 aLbEntries->setPosSizePixel( 0, nListboxYPos, 0, 0, PosSizeFlags::Y);
604 nBorderOffset = aLbEntries->GetPosPixel().X();
606 aInitSize.Width() = aTbxCmd->GetPosPixel().X()
607 + aTbxCmd->GetSizePixel().Width()
608 + nBorderOffset;
609 aInitSize.Height() = aLbEntries->GetPosPixel().Y();
611 nInitListHeight = aLbEntries->GetSizePixel().Height();
612 nListModeHeight = aInitSize.Height()
613 + nInitListHeight;
615 ppBoundItems = new ScNavigatorControllerItem* [CTRL_ITEMS];
617 rBindings.ENTERREGISTRATIONS();
619 REGISTER_SLOT( 0, SID_CURRENTCELL );
620 REGISTER_SLOT( 1, SID_CURRENTTAB );
621 REGISTER_SLOT( 2, SID_CURRENTDOC );
622 REGISTER_SLOT( 3, SID_SELECT_SCENARIO );
624 rBindings.LEAVEREGISTRATIONS();
626 StartListening( *(SfxGetpApp()) );
627 StartListening( rBindings );
629 aLbDocuments->Hide(); // does not exist at NAV_LMODE_NONE
631 aLbEntries->InitWindowBits(true);
633 aLbEntries->SetSpaceBetweenEntries(0);
634 aLbEntries->SetSelectionMode( SINGLE_SELECTION );
635 aLbEntries->SetDragDropMode( DragDropMode::CTRL_MOVE |
636 DragDropMode::CTRL_COPY |
637 DragDropMode::ENABLE_TOP );
639 // was a category chosen as root?
640 ScContentId nLastRoot = rCfg.GetRootType();
641 if ( nLastRoot != ScContentId::ROOT )
642 aLbEntries->SetRootType( nLastRoot );
644 aLbEntries->Refresh();
645 GetDocNames();
647 aTbxCmd->UpdateButtons();
649 UpdateColumn();
650 UpdateRow();
651 UpdateTable();
652 aLbEntries->Hide();
653 aWndScenarios->Hide();
654 aWndScenarios->SetPosPixel( aLbEntries->GetPosPixel() );
656 aContentIdle.SetIdleHdl( LINK( this, ScNavigatorDlg, TimeHdl ) );
657 aContentIdle.SetPriority( SchedulerPriority::LOWEST );
659 FreeResource();
661 aLbEntries->SetAccessibleRelationLabeledBy(aLbEntries.get());
662 aTbxCmd->SetAccessibleRelationLabeledBy(aTbxCmd.get());
663 aLbDocuments->SetAccessibleName(aStrActiveWin);
665 if (pContextWin == nullptr)
667 // When the context window is missing then the navigator is
668 // displayed in the sidebar and has the whole deck to fill.
669 // Therefore hide the button that hides all controls below the
670 // top two rows of buttons.
671 aTbxCmd->Select(IID_ZOOMOUT);
672 aTbxCmd->RemoveItem(aTbxCmd->GetItemPos(IID_ZOOMOUT));
674 aLbEntries->SetNavigatorDlgFlag(true);
677 ScNavigatorDlg::~ScNavigatorDlg()
679 disposeOnce();
682 void ScNavigatorDlg::dispose()
684 aContentIdle.Stop();
686 sal_uInt16 i;
687 for ( i=0; i<CTRL_ITEMS; i++ )
688 delete ppBoundItems[i];
690 delete [] ppBoundItems;
691 delete pMarkArea;
693 EndListening( *(SfxGetpApp()) );
694 EndListening( rBindings );
696 aFtCol.disposeAndClear();
697 aEdCol.disposeAndClear();
698 aFtRow.disposeAndClear();
699 aEdRow.disposeAndClear();
700 aTbxCmd.disposeAndClear();
701 aLbEntries.disposeAndClear();
702 aWndScenarios.disposeAndClear();
703 aLbDocuments.disposeAndClear();
704 vcl::Window::dispose();
707 void ScNavigatorDlg::Resizing( Size& rNewSize ) // Size = Outputsize?
709 FloatingWindow* pFloat = pContextWin!=nullptr ? pContextWin->GetFloatingWindow() : nullptr;
710 if ( pFloat )
712 Size aMinOut = pFloat->GetMinOutputSizePixel();
714 if ( rNewSize.Width() < aMinOut.Width() )
715 rNewSize.Width() = aMinOut.Width();
717 if ( eListMode == NAV_LMODE_NONE )
718 rNewSize.Height() = aInitSize.Height();
719 else
721 if ( rNewSize.Height() < aMinOut.Height() )
722 rNewSize.Height() = aMinOut.Height();
727 void ScNavigatorDlg::Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect )
729 if (mbUseStyleSettingsBackground)
731 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
732 Color aBgColor = rStyleSettings.GetFaceColor();
733 Wallpaper aBack( aBgColor );
735 SetBackground( aBack );
736 aFtCol->SetBackground( aBack );
737 aFtRow->SetBackground( aBack );
739 else
741 aFtCol->SetBackground(Wallpaper());
742 aFtRow->SetBackground(Wallpaper());
745 Window::Paint(rRenderContext, rRect);
748 void ScNavigatorDlg::DataChanged( const DataChangedEvent& rDCEvt )
750 if ( rDCEvt.GetType() == DataChangedEventType::SETTINGS && (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
752 // toolbox images are exchanged in CommandToolBox::DataChanged
753 Invalidate();
756 Window::DataChanged( rDCEvt );
759 void ScNavigatorDlg::Resize()
761 DoResize();
764 void ScNavigatorDlg::DoResize()
766 Size aNewSize = GetOutputSizePixel();
767 long nTotalHeight = aNewSize.Height();
769 // if the navigator is docked, the window is probably at first small generated,
770 // then there is a resize to the actual size -> switch on content
772 bool bSmall = ( nTotalHeight <= aInitSize.Height() + SCNAV_MINTOL );
773 if ( !bSmall && bFirstBig )
775 // Switch on content again as described in the config
777 bFirstBig = false;
778 NavListMode eNavMode = NAV_LMODE_AREAS;
779 ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
780 NavListMode eLastMode = (NavListMode) rCfg.GetListMode();
781 if ( eLastMode == NAV_LMODE_SCENARIOS )
782 eNavMode = NAV_LMODE_SCENARIOS;
783 SetListMode( eNavMode, false ); // FALSE: do not set the Float size
786 // even if the content is not visible, adapt the size,
787 // so the width fit
789 Point aEntryPos = aLbEntries->GetPosPixel();
790 Point aListPos = aLbDocuments->GetPosPixel();
791 aNewSize.Width() -= 2*nBorderOffset;
792 Size aDocSize = aLbDocuments->GetSizePixel();
793 aDocSize.Width() = aNewSize.Width();
795 if(!bSmall)
798 long nListHeight = aLbDocuments->GetSizePixel().Height();
799 aNewSize.Height() -= ( aEntryPos.Y() + nListHeight + 2*nBorderOffset );
800 if(aNewSize.Height()<0) aNewSize.Height()=0;
802 aListPos.Y() = aEntryPos.Y() + aNewSize.Height() + nBorderOffset;
804 if(aListPos.Y() > aLbEntries->GetPosPixel().Y())
805 aLbDocuments->SetPosPixel( aListPos );
808 aLbEntries->SetSizePixel( aNewSize );
809 aWndScenarios->SetSizePixel( aNewSize );
810 aLbDocuments->SetSizePixel( aDocSize );
812 bool bListMode = (eListMode != NAV_LMODE_NONE);
813 if (pContextWin != nullptr)
815 FloatingWindow* pFloat = pContextWin->GetFloatingWindow();
816 if ( pFloat && bListMode )
817 nListModeHeight = nTotalHeight;
821 void ScNavigatorDlg::Notify( SfxBroadcaster&, const SfxHint& rHint )
823 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>( &rHint );
824 if ( pSimpleHint )
826 const sal_uInt32 nHintId = pSimpleHint->GetId();
828 if ( nHintId == SC_HINT_DOCNAME_CHANGED )
830 aLbEntries->ActiveDocChanged();
832 else if ( NAV_LMODE_NONE == eListMode )
834 // Table not any more
836 else
838 switch ( nHintId )
840 case SC_HINT_TABLES_CHANGED:
841 aLbEntries->Refresh( ScContentId::TABLE );
842 break;
844 case SC_HINT_DBAREAS_CHANGED:
845 aLbEntries->Refresh( ScContentId::DBAREA );
846 break;
848 case SC_HINT_AREAS_CHANGED:
849 aLbEntries->Refresh( ScContentId::RANGENAME );
850 break;
852 case SC_HINT_DRAW_CHANGED:
853 aLbEntries->Refresh( ScContentId::GRAPHIC );
854 aLbEntries->Refresh( ScContentId::OLEOBJECT );
855 aLbEntries->Refresh( ScContentId::DRAWING );
856 break;
858 case SC_HINT_AREALINKS_CHANGED:
859 aLbEntries->Refresh( ScContentId::AREALINK );
860 break;
862 // SFX_HINT_DOCCHANGED not only at document change
864 case SC_HINT_NAVIGATOR_UPDATEALL:
865 UpdateAll();
866 break;
868 case FID_DATACHANGED:
869 case FID_ANYDATACHANGED:
870 aContentIdle.Start(); // Do not search notes immediately
871 break;
872 case FID_KILLEDITVIEW:
873 aLbEntries->ObjectFresh( ScContentId::OLEOBJECT );
874 aLbEntries->ObjectFresh( ScContentId::DRAWING );
875 aLbEntries->ObjectFresh( ScContentId::GRAPHIC );
876 break;
877 default:
878 break;
882 else if ( dynamic_cast<const SfxEventHint*>(&rHint) )
884 sal_uLong nEventId = static_cast<const SfxEventHint&>(rHint).GetEventId();
885 if ( nEventId == SFX_EVENT_ACTIVATEDOC )
887 aLbEntries->ActiveDocChanged();
888 UpdateAll();
893 IMPL_LINK_TYPED( ScNavigatorDlg, TimeHdl, Idle*, pIdle, void )
895 if ( pIdle != &aContentIdle )
896 return;
898 aLbEntries->Refresh( ScContentId::NOTE );
901 void ScNavigatorDlg::SetDropMode(sal_uInt16 nNew)
903 nDropMode = nNew;
904 aTbxCmd->UpdateButtons();
906 ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
907 rCfg.SetDragMode(nDropMode);
910 void ScNavigatorDlg::SetCurrentCell( SCCOL nColNo, SCROW nRowNo )
912 if ( (nColNo+1 != nCurCol) || (nRowNo+1 != nCurRow) )
914 // SID_CURRENTCELL == Item #0 clear cache, so it's possible
915 // setting the current cell even in combined areas
916 ppBoundItems[0]->ClearCache();
918 ScAddress aScAddress( nColNo, nRowNo, 0 );
919 OUString aAddr(aScAddress.Format(ScRefFlags::ADDR_ABS));
921 bool bUnmark = false;
922 if ( GetViewData() )
923 bUnmark = !pViewData->GetMarkData().IsCellMarked( nColNo, nRowNo );
925 SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
926 SfxBoolItem aUnmarkItem( FN_PARAM_1, bUnmark ); // cancel selektion
928 rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL,
929 SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
930 { &aPosItem, &aUnmarkItem });
934 void ScNavigatorDlg::SetCurrentCellStr( const OUString& rName )
936 ppBoundItems[0]->ClearCache();
937 SfxStringItem aNameItem( SID_CURRENTCELL, rName );
939 rBindings.GetDispatcher()->ExecuteList(SID_CURRENTCELL,
940 SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
941 { &aNameItem });
944 void ScNavigatorDlg::SetCurrentTable( SCTAB nTabNo )
946 if ( nTabNo != nCurTab )
948 // Table for basic is base-1
949 SfxUInt16Item aTabItem( SID_CURRENTTAB, static_cast<sal_uInt16>(nTabNo) + 1 );
950 rBindings.GetDispatcher()->ExecuteList(SID_CURRENTTAB,
951 SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
952 { &aTabItem });
956 void ScNavigatorDlg::SetCurrentTableStr( const OUString& rName )
958 if (!GetViewData()) return;
960 ScDocument* pDoc = pViewData->GetDocument();
961 SCTAB nCount = pDoc->GetTableCount();
962 OUString aTabName;
963 SCTAB nLastSheet = 0;
965 for (SCTAB i = 0; i<nCount; i++)
967 pDoc->GetName(i, aTabName);
968 if (aTabName.equals(rName))
970 // Check if this is a Scenario sheet and if so select the sheet
971 // where it belongs to, which is the previous non-Scenario sheet.
972 if (pDoc->IsScenario(i))
974 SetCurrentTable(nLastSheet);
975 return;
977 else
979 SetCurrentTable(i);
980 return;
983 else
985 if (!pDoc->IsScenario(i))
986 nLastSheet = i;
991 void ScNavigatorDlg::SetCurrentObject( const OUString& rName )
993 SfxStringItem aNameItem( SID_CURRENTOBJECT, rName );
994 rBindings.GetDispatcher()->ExecuteList( SID_CURRENTOBJECT,
995 SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
996 { &aNameItem });
999 void ScNavigatorDlg::SetCurrentDoc( const OUString& rDocName ) // activate
1001 SfxStringItem aDocItem( SID_CURRENTDOC, rDocName );
1002 rBindings.GetDispatcher()->ExecuteList( SID_CURRENTDOC,
1003 SfxCallMode::SYNCHRON | SfxCallMode::RECORD,
1004 { &aDocItem });
1007 ScTabViewShell* ScNavigatorDlg::GetTabViewShell()
1009 return dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
1012 ScNavigatorSettings* ScNavigatorDlg::GetNavigatorSettings()
1014 // Don't store the settings pointer here, because the settings belong to
1015 // the view, and the view may be closed while the navigator is open (reload).
1016 // If the pointer is cached here again later for performance reasons, it has to
1017 // be forgotten when the view is closed.
1019 ScTabViewShell* pViewSh = GetTabViewShell();
1020 return pViewSh ? pViewSh->GetNavigatorSettings() : nullptr;
1023 bool ScNavigatorDlg::GetViewData()
1025 ScTabViewShell* pViewSh = GetTabViewShell();
1026 pViewData = pViewSh ? &pViewSh->GetViewData() : nullptr;
1028 return ( pViewData != nullptr );
1031 void ScNavigatorDlg::UpdateColumn( const SCCOL* pCol )
1033 if ( pCol )
1034 nCurCol = *pCol;
1035 else if ( GetViewData() )
1036 nCurCol = pViewData->GetCurX() + 1;
1038 aEdCol->SetCol( nCurCol );
1039 CheckDataArea();
1042 void ScNavigatorDlg::UpdateRow( const SCROW* pRow )
1044 if ( pRow )
1045 nCurRow = *pRow;
1046 else if ( GetViewData() )
1047 nCurRow = pViewData->GetCurY() + 1;
1049 aEdRow->SetRow( nCurRow );
1050 CheckDataArea();
1053 void ScNavigatorDlg::UpdateTable( const SCTAB* pTab )
1055 if ( pTab )
1056 nCurTab = *pTab;
1057 else if ( GetViewData() )
1058 nCurTab = pViewData->GetTabNo();
1060 CheckDataArea();
1063 void ScNavigatorDlg::UpdateAll()
1065 switch ( eListMode )
1067 case NAV_LMODE_DOCS:
1068 case NAV_LMODE_DBAREAS:
1069 case NAV_LMODE_AREAS:
1070 aLbEntries->Refresh();
1071 break;
1073 case NAV_LMODE_NONE:
1074 //! ???
1075 break;
1077 default:
1078 break;
1081 aContentIdle.Stop(); // not again
1084 void ScNavigatorDlg::SetListMode( NavListMode eMode, bool bSetSize )
1086 if ( eMode != eListMode )
1088 if ( eMode != NAV_LMODE_NONE )
1089 bFirstBig = false; // do not switch automatically any more
1091 eListMode = eMode;
1093 switch ( eMode )
1095 case NAV_LMODE_NONE:
1096 ShowList( false, bSetSize );
1097 break;
1099 case NAV_LMODE_AREAS:
1100 case NAV_LMODE_DBAREAS:
1101 case NAV_LMODE_DOCS:
1102 aLbEntries->Refresh();
1103 ShowList( true, bSetSize );
1104 break;
1106 case NAV_LMODE_SCENARIOS:
1107 ShowScenarios( bSetSize );
1108 break;
1111 aTbxCmd->UpdateButtons();
1113 if ( eMode != NAV_LMODE_NONE )
1115 ScNavipiCfg& rCfg = SC_MOD()->GetNavipiCfg();
1116 rCfg.SetListMode( (sal_uInt16) eMode );
1120 if ( pMarkArea )
1121 UnmarkDataArea();
1124 void ScNavigatorDlg::ShowList( bool bShow, bool bSetSize )
1126 FloatingWindow* pFloat = pContextWin!=nullptr ? pContextWin->GetFloatingWindow() : nullptr;
1127 Size aSize = GetParent()->GetOutputSizePixel();
1129 if ( bShow )
1131 Size aMinSize = aInitSize;
1133 aMinSize.Height() += nInitListHeight;
1134 if ( pFloat )
1135 pFloat->SetMinOutputSizePixel( aMinSize );
1136 aSize.Height() = nListModeHeight;
1137 aLbEntries->Show();
1138 aLbDocuments->Show();
1140 else
1142 if ( pFloat )
1144 pFloat->SetMinOutputSizePixel( aInitSize );
1145 nListModeHeight = aSize.Height();
1147 aSize.Height() = aInitSize.Height();
1148 aLbEntries->Hide();
1149 aLbDocuments->Hide();
1151 aWndScenarios->Hide();
1153 if ( pFloat )
1155 if ( bSetSize )
1156 pFloat->SetOutputSizePixel( aSize );
1158 else
1160 SfxNavigator* pNav = dynamic_cast<SfxNavigator*>(GetParent());
1161 if (pNav != nullptr)
1163 Size aFloating = pNav->GetFloatingSize();
1164 aFloating.Height() = aSize.Height();
1165 pNav->SetFloatingSize( aFloating );
1170 void ScNavigatorDlg::ShowScenarios( bool bSetSize )
1172 FloatingWindow* pFloat = pContextWin!=nullptr ? pContextWin->GetFloatingWindow() : nullptr;
1173 Size aSize = GetParent()->GetOutputSizePixel();
1175 Size aMinSize = aInitSize;
1176 aMinSize.Height() += nInitListHeight;
1177 if ( pFloat )
1178 pFloat->SetMinOutputSizePixel( aMinSize );
1179 aSize.Height() = nListModeHeight;
1181 rBindings.Invalidate( SID_SELECT_SCENARIO );
1182 rBindings.Update( SID_SELECT_SCENARIO );
1184 aWndScenarios->Show();
1185 aLbDocuments->Show();
1186 aLbEntries->Hide();
1188 if ( pFloat )
1190 if ( bSetSize )
1191 pFloat->SetOutputSizePixel( aSize );
1193 else
1195 SfxNavigator* pNav = static_cast<SfxNavigator*>(GetParent());
1196 Size aFloating = pNav->GetFloatingSize();
1197 aFloating.Height() = aSize.Height();
1198 pNav->SetFloatingSize( aFloating );
1202 // documents for Dropdown-Listbox
1204 void ScNavigatorDlg::GetDocNames( const OUString* pManualSel )
1206 aLbDocuments->Clear();
1207 aLbDocuments->SetUpdateMode( false );
1209 ScDocShell* pCurrentSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
1211 OUString aSelEntry;
1212 SfxObjectShell* pSh = SfxObjectShell::GetFirst();
1213 while ( pSh )
1215 if ( dynamic_cast<const ScDocShell*>( pSh) != nullptr )
1217 OUString aName = pSh->GetTitle();
1218 OUString aEntry = aName;
1219 if (pSh == pCurrentSh)
1220 aEntry += aStrActive;
1221 else
1222 aEntry += aStrNotActive;
1223 aLbDocuments->InsertEntry( aEntry );
1225 if ( pManualSel ? ( aName == *pManualSel )
1226 : ( pSh == pCurrentSh ) )
1227 aSelEntry = aEntry; // complete entry for selection
1230 pSh = SfxObjectShell::GetNext( *pSh );
1233 aLbDocuments->InsertEntry( aStrActiveWin );
1235 OUString aHidden = aLbEntries->GetHiddenTitle();
1236 if (!aHidden.isEmpty())
1238 OUString aEntry = aHidden;
1239 aEntry += aStrHidden;
1240 aLbDocuments->InsertEntry( aEntry );
1242 if ( pManualSel && aHidden == *pManualSel )
1243 aSelEntry = aEntry;
1246 aLbDocuments->SetUpdateMode( true );
1248 aLbDocuments->SelectEntry( aSelEntry );
1251 void ScNavigatorDlg::MarkDataArea()
1253 ScTabViewShell* pViewSh = GetTabViewShell();
1255 if ( pViewSh )
1257 if ( !pMarkArea )
1258 pMarkArea = new ScArea;
1260 pViewSh->MarkDataArea();
1261 ScRange aMarkRange;
1262 pViewSh->GetViewData().GetMarkData().GetMarkArea(aMarkRange);
1263 pMarkArea->nColStart = aMarkRange.aStart.Col();
1264 pMarkArea->nRowStart = aMarkRange.aStart.Row();
1265 pMarkArea->nColEnd = aMarkRange.aEnd.Col();
1266 pMarkArea->nRowEnd = aMarkRange.aEnd.Row();
1267 pMarkArea->nTab = aMarkRange.aStart.Tab();
1271 void ScNavigatorDlg::UnmarkDataArea()
1273 ScTabViewShell* pViewSh = GetTabViewShell();
1275 if ( pViewSh )
1277 pViewSh->Unmark();
1278 DELETEZ( pMarkArea );
1282 void ScNavigatorDlg::CheckDataArea()
1284 if ( aTbxCmd->IsItemChecked( IID_DATA ) && pMarkArea )
1286 if ( nCurTab != pMarkArea->nTab
1287 || nCurCol < pMarkArea->nColStart+1
1288 || nCurCol > pMarkArea->nColEnd+1
1289 || nCurRow < pMarkArea->nRowStart+1
1290 || nCurRow > pMarkArea->nRowEnd+1 )
1292 aTbxCmd->SetItemState( IID_DATA, TriState(TRISTATE_TRUE) );
1293 aTbxCmd->Select( IID_DATA );
1298 void ScNavigatorDlg::StartOfDataArea()
1300 // pMarkArea evaluate ???
1302 if ( GetViewData() )
1304 ScMarkData& rMark = pViewData->GetMarkData();
1305 ScRange aMarkRange;
1306 rMark.GetMarkArea( aMarkRange );
1308 SCCOL nCol = aMarkRange.aStart.Col();
1309 SCROW nRow = aMarkRange.aStart.Row();
1311 if ( (nCol+1 != aEdCol->GetCol()) || (nRow+1 != aEdRow->GetRow()) )
1312 SetCurrentCell( nCol, nRow );
1316 void ScNavigatorDlg::EndOfDataArea()
1318 // pMarkArea evaluate ???
1320 if ( GetViewData() )
1322 ScMarkData& rMark = pViewData->GetMarkData();
1323 ScRange aMarkRange;
1324 rMark.GetMarkArea( aMarkRange );
1326 SCCOL nCol = aMarkRange.aEnd.Col();
1327 SCROW nRow = aMarkRange.aEnd.Row();
1329 if ( (nCol+1 != aEdCol->GetCol()) || (nRow+1 != aEdRow->GetRow()) )
1330 SetCurrentCell( nCol, nRow );
1334 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */