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 <config_features.h>
24 #include <sfx2/request.hxx>
25 #include <sfx2/bindings.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <basic/sbstar.hxx>
28 #include <basic/sberrors.hxx>
29 #include <svl/ctloptions.hxx>
30 #include <svl/stritem.hxx>
31 #include <svl/whiter.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/weld.hxx>
34 #include <sfx2/objface.hxx>
35 #include <svx/svxdlg.hxx>
36 #include <editeng/colritem.hxx>
38 #include <tabvwsh.hxx>
42 #include <document.hxx>
43 #include <scresid.hxx>
44 #include <globstr.hrc>
45 #include <strings.hrc>
46 #include <docfunc.hxx>
47 #include <eventuno.hxx>
48 #include <dpobject.hxx>
49 #include <dpshttab.hxx>
51 #include <scabstdlg.hxx>
53 #include <tabbgcolor.hxx>
54 #include <markdata.hxx>
58 using std::unique_ptr
;
59 using namespace com::sun::star
;
61 void ScTabViewShell::ExecuteTable( SfxRequest
& rReq
)
63 ScViewData
& rViewData
= GetViewData();
64 ScDocument
& rDoc
= rViewData
.GetDocument();
66 SCTAB nCurrentTab
= rViewData
.GetTabNo();
67 SCTAB nTabCount
= rDoc
.GetTableCount();
68 sal_uInt16 nSlot
= rReq
.GetSlot();
69 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
71 HideListBox(); // Autofilter-DropDown-Listbox
75 case FID_TABLE_VISIBLE
:
78 rDoc
.GetName( nCurrentTab
, aName
);
81 if( pReqArgs
!= nullptr )
83 const SfxPoolItem
* pItem
;
84 if( pReqArgs
->HasItem( FID_TABLE_VISIBLE
, &pItem
) )
85 bVisible
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
88 if( ! bVisible
) // fade out
90 if ( rDoc
.IsDocEditable() )
92 ScMarkData
& rMark
= rViewData
.GetMarkData();
98 std::vector
<OUString
> rNames
{ aName
};
106 if ( rDoc
.IsDocEditable() )
108 ScMarkData
& rMark
= rViewData
.GetMarkData();
109 SCTAB nActiveTab
= -1;
110 // For the cases when user right clicks on a non-active tab and hides it. This case is possible for Online.
113 const SfxPoolItem
*pItem
;
114 if( pReqArgs
->HasItem( FID_TABLE_HIDE
, &pItem
) )
116 SCTAB nTabNumber
= static_cast<const SfxInt16Item
*>(pItem
)->GetValue();
117 // Does selected sheets (tabs) list include the sheet to be hidden?
118 std::set
<SCTAB
>::iterator it
= rMark
.GetSelectedTabs().find(nTabNumber
);
119 if (it
== rMark
.GetSelectedTabs().end())
121 // No it doesn't, so we won't shift the selected tab. Let's remember its position.
122 nActiveTab
= GetViewData().GetTabNo();
124 rMark
.SelectOneTable(nTabNumber
);
127 HideTable( rMark
, nActiveTab
);
134 std::vector
<OUString
> rNames
;
137 const SfxPoolItem
* pItem
;
138 if( pReqArgs
->HasItem( FID_TABLE_SHOW
, &pItem
) )
140 OUString aName
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
141 rNames
.push_back(aName
);
150 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
152 VclPtr
<AbstractScShowTabDlg
> pDlg(pFact
->CreateScShowTabDlg(GetFrameWeld()));
156 for ( SCTAB i
=0; i
!= nTabCount
; i
++ )
158 if (!rDoc
.IsVisible(i
))
160 rDoc
.GetName( i
, aTabName
);
161 pDlg
->Insert( aTabName
, bFirst
);
166 std::shared_ptr
<SfxRequest
> xReq
= std::make_shared
<SfxRequest
>(rReq
);
167 pDlg
->StartExecuteAsync([this, pDlg
, xReq
= std::move(xReq
)](sal_Int32 nResult
){
168 std::vector
<OUString
> sTables
;
169 if (RET_OK
== nResult
)
171 std::vector
<sal_Int32
> aSelectedRows
= pDlg
->GetSelectedRows();
172 for (auto a
: aSelectedRows
)
174 OUString sTable
= pDlg
->GetEntry(a
);
175 xReq
->AppendItem( SfxStringItem( FID_TABLE_SHOW
, sTable
) );
176 sTables
.push_back(sTable
);
178 ShowTable( sTables
);
189 case FID_INS_TABLE_EXT
:
190 ExecuteInsertTable(rReq
);
195 case FID_TAB_MENU_RENAME
:
197 // FID_TAB_MENU_RENAME - "rename" in menu
198 // FID_TAB_RENAME - "name"-property for basic
199 // equal execute, but MENU_RENAME may be disabled inside GetState
201 ExecuteAppendOrRenameTable(rReq
);
207 ExecuteMoveTable(rReq
);
211 case FID_TAB_DUPLICATE
:
213 // Get info about current document and selected tab
214 SCTAB nTab
= rViewData
.GetTabNo();
215 OUString aDocName
= GetViewData().GetDocShell()->GetTitle(SFX_TITLE_FULLNAME
);
219 SfxObjectShell
* pSh
= SfxObjectShell::GetFirst();
220 ScDocShell
* pScSh
= nullptr;
223 // Determine the index of the current document
226 pScSh
= dynamic_cast<ScDocShell
*>( pSh
);
230 if (aDocName
== pScSh
->GetTitle(SFX_TITLE_FULLNAME
))
235 // Only count ScDocShell
238 pSh
= SfxObjectShell::GetNext( *pSh
);
241 MoveTable( nDoc
, nTab
+ 1, bCpy
);
245 case FID_DELETE_TABLE
:
247 bool bHasIndex
= (pReqArgs
!= nullptr);
249 // allow removing via the Index/FID_DELETE_TABLE parameter
250 SCTAB nTabNr
= nCurrentTab
;
253 const SfxPoolItem
* pItem
;
254 if (pReqArgs
->HasItem(FID_DELETE_TABLE
, &pItem
))
256 nTabNr
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
258 // inserting is 1-based, let's be consistent
264 bool bDoIt
= bHasIndex
;
267 bool bTabWithPivotTable
= false;
268 if (rDoc
.HasPivotTable())
270 const ScDPCollection
* pDPs
= rDoc
.GetDPCollection();
273 const ScMarkData::MarkedTabsType
& rSelectedTabs
= rViewData
.GetMarkData().GetSelectedTabs();
274 const size_t nCount
= pDPs
->GetCount();
275 for (size_t i
= 0; i
< nCount
; ++i
)
277 const ScDPObject
& rDPObj
= (*pDPs
)[i
];
278 const ScSheetSourceDesc
* pSheetSourceDesc
= rDPObj
.GetSheetDesc();
279 if (pSheetSourceDesc
)
281 SCTAB nTabOut
= rDPObj
.GetOutRange().aStart
.Tab();
282 SCTAB nTabSource
= pSheetSourceDesc
->GetSourceRange().aStart
.Tab();
283 bool bTabOutSel
= false;
284 for (const SCTAB nSelTab
: rSelectedTabs
)
286 if (nSelTab
== nTabSource
)
287 bTabWithPivotTable
= true;
288 if (nSelTab
== nTabOut
)
290 if (bTabWithPivotTable
&& bTabOutSel
)
293 // if both pivot table and data are selected
294 // no need to warn for source data losing
295 if (bTabWithPivotTable
&& bTabOutSel
)
296 bTabWithPivotTable
= false;
297 if (bTabWithPivotTable
)
304 SCTAB nTabSelCnt
= rViewData
.GetMarkData().GetSelectCount();
305 OUString aTabSelCnt
= Application::GetSettings().GetUILocaleDataWrapper().getNum( nTabSelCnt
, 0 );
306 OUString aQueryDeleteTab
= ScResId( STR_QUERY_DELTAB
, nTabSelCnt
)
307 .replaceAll( "%d", aTabSelCnt
);
308 if (bTabWithPivotTable
)
310 OUString aStr
= ScResId( STR_QUERY_PIVOTTABLE_DELTAB
, nTabSelCnt
)
311 .replaceAll( "%d", aTabSelCnt
)
312 + " " + aQueryDeleteTab
;
314 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
315 VclMessageType::Question
, VclButtonsType::YesNo
,
317 xQueryBox
->set_default_response(RET_NO
);
319 // Hard warning as there is potential of data loss on deletion
320 bDoIt
= (RET_YES
== xQueryBox
->run());
324 bool bHasData
= false;
325 ScMarkData
& rMark
= rViewData
.GetMarkData();
326 for ( SCTAB i
= 0; i
< nTabCount
&& !bHasData
; i
++ )
328 if ( rMark
.GetTableSelect(i
) && !rDoc
.IsTabProtected(i
) )
332 bHasData
= rDoc
.GetDataStart( i
, nStartCol
, nStartRow
);
335 // Do not ask for confirmation if all selected tabs are empty
338 std::unique_ptr
<weld::MessageDialog
> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
339 VclMessageType::Question
, VclButtonsType::YesNo
,
341 xQueryBox
->set_default_response(RET_YES
);
343 // no parameter given, ask for confirmation
344 bDoIt
= (RET_YES
== xQueryBox
->run());
353 SCTAB nNewTab
= nCurrentTab
;
354 std::vector
<SCTAB
> TheTabs
;
358 // sheet no. provided by the parameter
359 TheTabs
.push_back(nTabNr
);
360 if (nNewTab
> nTabNr
&& nNewTab
> 0)
366 bool bTabFlag
= false;
367 ScMarkData
& rMark
= rViewData
.GetMarkData();
368 for (SCTAB i
= 0; i
< nTabCount
; i
++)
370 if (rMark
.GetTableSelect(i
) && !rDoc
.IsTabProtected(i
))
372 TheTabs
.push_back(i
);
374 if (nNewTab
== i
&& i
+1 < nTabCount
)
380 if (nNewTab
>= nTabCount
- static_cast<SCTAB
>(TheTabs
.size()))
384 rViewData
.SetTabNo(nNewTab
);
385 DeleteTables(TheTabs
);
394 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
395 ScDocFunc
&rFunc
= pDocSh
->GetDocFunc();
396 bool bSet
= !rDoc
.IsLayoutRTL( nCurrentTab
);
398 const ScMarkData
& rMark
= rViewData
.GetMarkData();
399 if ( rMark
.GetSelectCount() != 0 )
401 // handle several sheets
403 SfxUndoManager
* pUndoManager
= pDocSh
->GetUndoManager();
404 OUString aUndo
= ScResId( STR_UNDO_TAB_RTL
);
405 pUndoManager
->EnterListAction( aUndo
, aUndo
, 0, rViewData
.GetViewShell()->GetViewShellId() );
407 for (const auto& rTab
: rMark
)
408 rFunc
.SetLayoutRTL( rTab
, bSet
);
410 pUndoManager
->LeaveListAction();
413 rFunc
.SetLayoutRTL( nCurrentTab
, bSet
);
417 case FID_TAB_TOGGLE_GRID
:
419 bool bShowGrid
= rViewData
.GetShowGrid();
420 rViewData
.SetShowGrid(!bShowGrid
);
421 SfxBindings
& rBindings
= GetViewFrame().GetBindings();
422 rBindings
.Invalidate( FID_TAB_TOGGLE_GRID
);
423 ScDocShellModificator
aModificator(*rViewData
.GetDocShell());
424 aModificator
.SetDocumentModified();
430 case FID_TAB_SET_TAB_BG_COLOR
:
431 case FID_TAB_MENU_SET_TAB_BG_COLOR
:
432 ExecuteSetTableBackgroundCol(rReq
);
437 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
438 uno::Reference
<container::XNameReplace
> xEvents( new ScSheetEventsObj( pDocSh
, nCurrentTab
) );
439 uno::Reference
<frame::XFrame
> xFrame
= GetViewFrame().GetFrame().GetFrameInterface();
440 SvxAbstractDialogFactory
* pDlgFactory
= SvxAbstractDialogFactory::Create();
441 VclPtr
<VclAbstractDialog
> pDialog( pDlgFactory
->CreateSvxMacroAssignDlg(
442 GetFrameWeld(), xFrame
, false, xEvents
, 0 ) );
443 // the dialog modifies the settings directly
444 pDialog
->StartExecuteAsync(
445 [pDialog
] (sal_Int32
/*nResult*/)->void
447 pDialog
->disposeOnce();
452 case FID_TOGGLEHIDDENCOLROW
:
454 svtools::EditableColorConfig aEditableConfig
;
455 svtools::ColorConfigValue aValue
= aEditableConfig
.GetColorValue(svtools::CALCHIDDENROWCOL
);
456 aValue
.bIsVisible
= !aValue
.bIsVisible
;
457 aEditableConfig
.SetColorValue(svtools::CALCHIDDENROWCOL
, aValue
);
461 OSL_FAIL("unknown message for ViewShell");
466 void ScTabViewShell::GetStateTable( SfxItemSet
& rSet
)
468 ScViewData
& rViewData
= GetViewData();
469 ScDocument
& rDoc
= rViewData
.GetDocument();
470 ScDocShell
* pDocShell
= rViewData
.GetDocShell();
471 ScMarkData
& rMark
= GetViewData().GetMarkData();
472 SCTAB nTab
= rViewData
.GetTabNo();
474 SCTAB nTabCount
= rDoc
.GetTableCount();
475 SCTAB nTabSelCount
= rMark
.GetSelectCount();
477 SfxWhichIter
aIter(rSet
);
478 sal_uInt16 nWhich
= aIter
.FirstWhich();
485 case FID_TABLE_VISIBLE
:
486 rSet
.Put( SfxBoolItem( nWhich
, rDoc
.IsVisible(nTab
) ));
492 // enable menu : check to make sure we won't hide all sheets. we need at least one visible at all times.
493 for ( SCTAB i
=0; i
< nTabCount
&& nVis
<nTabSelCount
+ 1; i
++ )
494 if (rDoc
.IsVisible(i
))
496 if ( nVis
<=nTabSelCount
|| !rDoc
.IsDocEditable() )
497 rSet
.DisableItem( nWhich
);
503 bool bHasHidden
= false;
504 for ( SCTAB i
=0; i
< nTabCount
&& !bHasHidden
; i
++ )
505 if (!rDoc
.IsVisible(i
))
507 if ( !bHasHidden
|| rDoc
.IsDocProtected() || nTabSelCount
> 1 )
508 rSet
.DisableItem( nWhich
);
512 case FID_DELETE_TABLE
:
514 if ( rDoc
.GetChangeTrack() )
515 rSet
.DisableItem( nWhich
);
519 for ( SCTAB i
=0; i
< nTabCount
&& nVis
<2; i
++ )
520 if (rDoc
.IsVisible(i
))
522 if ( rDoc
.IsTabProtected(nTab
)
523 || !rDoc
.IsDocEditable()
525 || nTabSelCount
== nTabCount
)
526 rSet
.DisableItem( nWhich
);
532 case FID_INS_TABLE_EXT
:
534 if ( !rDoc
.IsDocEditable() ||
535 nTabCount
> MAXTAB
||
536 ( nWhich
== FID_INS_TABLE_EXT
&& pDocShell
&& pDocShell
->IsDocShared() ) )
537 rSet
.DisableItem( nWhich
);
541 case FID_TAB_DUPLICATE
:
542 if ( !rDoc
.IsDocEditable()
543 || rDoc
.GetChangeTrack() != nullptr
544 || nTabCount
> MAXTAB
)
545 rSet
.DisableItem( nWhich
);
548 // FID_TAB_MENU_RENAME - "rename" from Menu
549 // FID_TAB_RENAME - "name"-property for Basic
551 case FID_TAB_MENU_RENAME
:
552 if ( !rDoc
.IsDocEditable() ||
553 rDoc
.IsTabProtected(nTab
) ||nTabSelCount
> 1 ||
554 ( pDocShell
&& pDocShell
->IsDocShared() ) )
555 rSet
.DisableItem( nWhich
);
561 rDoc
.GetName( nTab
, aTabName
);
563 rSet
.Put( SfxStringItem( nWhich
, aTabName
));
570 if ( !SvtCTLOptions::IsCTLFontEnabled() )
571 rSet
.DisableItem( nWhich
);
573 rSet
.Put( SfxBoolItem( nWhich
, rDoc
.IsLayoutRTL( nTab
) ) );
577 case FID_TAB_MENU_SET_TAB_BG_COLOR
:
579 if ( !rDoc
.IsDocEditable()
580 || ( pDocShell
&& pDocShell
->IsDocShared() )
581 || rDoc
.IsTabProtected(nTab
) )
582 rSet
.DisableItem( nWhich
);
586 case FID_TAB_SET_TAB_BG_COLOR
:
588 Color aColor
= rDoc
.GetTabBgColor( nTab
);
589 rSet
.Put( SvxColorItem( aColor
, nWhich
) );
593 case FID_TAB_TOGGLE_GRID
:
594 rSet
.Put( SfxBoolItem(nWhich
, rViewData
.GetShowGrid()) );
597 nWhich
= aIter
.NextWhich();
601 void ScTabViewShell::ExecuteMoveTable( SfxRequest
& rReq
)
603 ScViewData
& rViewData
= GetViewData();
604 ScDocument
& rDoc
= rViewData
.GetDocument();
605 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
607 if ( rDoc
.GetChangeTrack() != nullptr )
608 return; // if ChangeTracking is active, then no TabMove
612 SCTAB nTab
= rViewData
.GetTabNo();
613 SCTAB nContextMenuTab
= -1;
614 bool bFromContextMenu
= false;
615 bool bFromMoveOrCopySheetDialog
= false; // FN_PARAM_6
616 bool bCpy
= false, bUseCurrentDocument
= false;
620 // if FID_TAB_MOVE has parameters
621 if( pReqArgs
!= nullptr )
623 SCTAB nTableCount
= rDoc
.GetTableCount();
624 const SfxPoolItem
* pItem
;
626 // if UseCurrentDocument(FN_PARAM_3) is true ignore the document name provided and use current document
627 if( pReqArgs
->HasItem( FN_PARAM_3
, &pItem
) )
628 bUseCurrentDocument
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
630 if (bUseCurrentDocument
)
631 aDocName
= GetViewData().GetDocShell()->GetTitle();
632 else if(pReqArgs
->HasItem( FID_TAB_MOVE
, &pItem
))
633 aDocName
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
635 if( pReqArgs
->HasItem( FN_PARAM_1
, &pItem
) )
637 // nTab is the target tab.
638 // source tab is either the active tab or the tab that context menu opened on.
640 nTab
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue() - 1;
641 if ( nTab
>= nTableCount
)
642 nTab
= SC_TAB_APPEND
;
644 if( pReqArgs
->HasItem( FN_PARAM_2
, &pItem
) )
645 bCpy
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
647 if (pReqArgs
->HasItem(FN_PARAM_4
, &pItem
))
649 bFromContextMenu
= static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
651 if (bFromContextMenu
)
653 // source tab: the tab that context menu opened on
654 if (pReqArgs
->HasItem(FN_PARAM_5
, &pItem
))
656 = static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
658 if (pReqArgs
->HasItem(FN_PARAM_6
, &pItem
))
659 bFromMoveOrCopySheetDialog
660 = static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
664 if (bFromMoveOrCopySheetDialog
)
666 OUString aDefaultName
;
667 rDoc
.GetName(nContextMenuTab
, aDefaultName
);
669 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
671 VclPtr
<AbstractScMoveTableDlg
> pDlg(
672 pFact
->CreateScMoveTableDlg(GetFrameWeld(), aDefaultName
));
674 ScMarkData
& rMark
= GetViewData().GetMarkData();
675 SCTAB nTabSelCount
= rMark
.GetSelectCount();
677 if (nTableCount
== nTabSelCount
)
679 pDlg
->SetForceCopyTable();
682 // We support direct renaming of sheet only when one sheet
684 pDlg
->EnableRenameTable(nTabSelCount
== 1);
686 std::shared_ptr
<SfxRequest
> xReq
= std::make_shared
<SfxRequest
>(rReq
);
687 pDlg
->StartExecuteAsync([this, pDlg
, xReq
=std::move(xReq
),
688 nContextMenuTab
](sal_Int32 nResult
) {
691 sal_uInt16 nDocument
= 0;
692 SCTAB nTargetIndex
= -1;
694 bool bDoItAsync
= false;
696 if (RET_OK
== nResult
)
698 nDocument
= pDlg
->GetSelectedDocument();
699 nTargetIndex
= pDlg
->GetSelectedTable();
700 bCopy
= pDlg
->GetCopyTable();
701 bool bRna
= pDlg
->GetRenameTable();
702 // Leave aTabName string empty, when Rename is FALSE.
704 pDlg
->GetTabNameString(aTableName
);
708 OUString aFoundDocName
;
709 if (nDocument
!= SC_DOC_NEW
)
711 ScDocShell
* pSh
= ScDocShell::GetShellByNum(nDocument
);
714 aFoundDocName
= pSh
->GetTitle();
715 if (!pSh
->GetDocument().IsDocEditable())
717 ErrorMessage(STR_READONLYERR
);
722 xReq
->AppendItem(SfxStringItem(FID_TAB_MOVE
, aFoundDocName
));
723 // 1-based table, if not APPEND
724 SCTAB nBasicTab
= (nContextMenuTab
<= MAXTAB
)
725 ? (nContextMenuTab
+ 1)
728 SfxUInt16Item(FN_PARAM_1
, static_cast<sal_uInt16
>(nBasicTab
)));
729 xReq
->AppendItem(SfxBoolItem(FN_PARAM_2
, bCopy
));
735 // send move or copy request
736 MoveTable(nDocument
, nTargetIndex
, bCopy
, &aTableName
, true,
746 if (!aDocName
.isEmpty())
748 SfxObjectShell
* pSh
= SfxObjectShell::GetFirst();
749 ScDocShell
* pScSh
= nullptr;
754 pScSh
= dynamic_cast<ScDocShell
*>( pSh
);
758 if (aDocName
== pScSh
->GetTitle())
761 ScDocument
& rDestDoc
= pScSh
->GetDocument();
762 nTableCount
= rDestDoc
.GetTableCount();
763 bDoIt
= rDestDoc
.IsDocEditable();
767 i
++; // only count ScDocShell
769 pSh
= SfxObjectShell::GetNext( *pSh
);
772 else // no doc-name -> new doc
778 if ( bDoIt
&& nTab
>= nTableCount
) // if necessary append
779 nTab
= SC_TAB_APPEND
;
784 OUString aDefaultName
;
785 rDoc
.GetName( rViewData
.GetTabNo(), aDefaultName
);
787 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
789 VclPtr
<AbstractScMoveTableDlg
> pDlg(pFact
->CreateScMoveTableDlg(GetFrameWeld(),
792 SCTAB nTableCount
= rDoc
.GetTableCount();
793 ScMarkData
& rMark
= GetViewData().GetMarkData();
794 SCTAB nTabSelCount
= rMark
.GetSelectCount();
796 if(nTableCount
==nTabSelCount
)
798 pDlg
->SetForceCopyTable();
801 // We support direct renaming of sheet only when one sheet
803 pDlg
->EnableRenameTable(nTabSelCount
== 1);
805 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
806 rReq
.Ignore(); // the 'old' request is not relevant any more
807 pDlg
->StartExecuteAsync(
808 [this, pDlg
, xRequest
=std::move(xRequest
)] (sal_Int32 nResult
)->void
810 if (nResult
== RET_OK
)
812 DoMoveTableFromDialog(*xRequest
, pDlg
);
821 rReq
.Done(); // record, while doc is active
823 if (bFromContextMenu
)
824 MoveTable(nDoc
, nTab
, bCpy
, &aTabName
, true,
827 MoveTable( nDoc
, nTab
, bCpy
, &aTabName
);
831 void ScTabViewShell::ExecuteInsertTable(SfxRequest
& rReq
)
833 ScViewData
& rViewData
= GetViewData();
834 ScDocument
& rDoc
= rViewData
.GetDocument();
835 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
836 sal_uInt16 nSlot
= rReq
.GetSlot();
837 SCTAB nCurrentTab
= rViewData
.GetTabNo();
838 SCTAB nTabCount
= rDoc
.GetTableCount();
839 ScMarkData
& rMark
= rViewData
.GetMarkData();
840 SCTAB nTabSelCount
= rMark
.GetSelectCount();
841 SCTAB nTabNr
= nCurrentTab
;
843 if ( !rDoc
.IsDocEditable() )
846 if ( pReqArgs
!= nullptr ) // from basic
849 const SfxPoolItem
* pTabItem
;
850 const SfxPoolItem
* pNameItem
;
852 if ( pReqArgs
->HasItem( FN_PARAM_1
, &pTabItem
) &&
853 pReqArgs
->HasItem( nSlot
, &pNameItem
) )
855 OUString aName
= static_cast<const SfxStringItem
*>(pNameItem
)->GetValue();
856 rDoc
.CreateValidTabName(aName
);
858 // sheet number from basic: 1-based
859 // 0 is special, means adding at the end
860 nTabNr
= static_cast<const SfxUInt16Item
*>(pTabItem
)->GetValue();
866 if (nTabNr
> nTabCount
)
869 bOk
= InsertTable(aName
, nTabNr
);
874 rViewData
.GetViewShell()->SetActive();
875 rReq
.Done( *pReqArgs
);
881 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
882 rReq
.Ignore(); // the 'old' request is not relevant any more
883 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
884 VclPtr
<AbstractScInsertTableDlg
> pDlg(pFact
->CreateScInsertTableDlg(GetFrameWeld(), rViewData
,
885 nTabSelCount
, nSlot
== FID_INS_TABLE_EXT
));
886 pDlg
->StartExecuteAsync(
887 [this, pDlg
, xRequest
=std::move(xRequest
)] (sal_Int32 nResult
)->void
889 if (nResult
== RET_OK
)
890 DoInsertTableFromDialog(*xRequest
, pDlg
);
897 void ScTabViewShell::DoInsertTableFromDialog(SfxRequest
& rReq
, const VclPtr
<AbstractScInsertTableDlg
>& pDlg
)
899 ScViewData
& rViewData
= GetViewData();
900 ScDocument
& rDoc
= rViewData
.GetDocument();
901 SCTAB nCurrentTab
= rViewData
.GetTabNo();
902 SCTAB nTabNr
= nCurrentTab
;
903 SCTAB nTabCount
= rDoc
.GetTableCount();
904 ScMarkData
& rMark
= rViewData
.GetMarkData();
906 if (pDlg
->GetTablesFromFile())
908 std::vector
<SCTAB
> nTabs
;
910 const OUString
* pStr
= pDlg
->GetFirstTable( &n
);
913 nTabs
.push_back( static_cast<SCTAB
>(n
) );
914 pStr
= pDlg
->GetNextTable( &n
);
916 bool bLink
= pDlg
->GetTablesAsLink();
919 if(pDlg
->IsTableBefore())
921 ImportTables( pDlg
->GetDocShellTables(), nTabs
.size(), nTabs
.data(),
926 SCTAB nTabAfter
= nTabNr
+1;
928 for(SCTAB j
=nCurrentTab
+1;j
<nTabCount
;j
++)
930 if(!rDoc
.IsScenario(j
))
937 ImportTables( pDlg
->GetDocShellTables(), nTabs
.size(), nTabs
.data(),
944 SCTAB nCount
=pDlg
->GetTableCount();
945 if(pDlg
->IsTableBefore())
947 if(nCount
==1 && !pDlg
->GetFirstTable()->isEmpty())
949 rReq
.AppendItem( SfxStringItem( FID_INS_TABLE
, *pDlg
->GetFirstTable() ) );
950 rReq
.AppendItem( SfxUInt16Item( FN_PARAM_1
, static_cast<sal_uInt16
>(nTabNr
) + 1 ) ); // 1-based
953 InsertTable( *pDlg
->GetFirstTable(), nTabNr
);
957 std::vector
<OUString
> aNames(0);
958 InsertTables( aNames
, nTabNr
,nCount
);
963 SCTAB nTabAfter
= nTabNr
+1;
964 SCTAB nSelHigh
= rMark
.GetLastSelected();
966 for(SCTAB j
=nSelHigh
+1;j
<nTabCount
;j
++)
968 if(!rDoc
.IsScenario(j
))
973 else // #101672#; increase nTabAfter, because it is possible that the scenario tables are the last
977 if(nCount
==1 && !pDlg
->GetFirstTable()->isEmpty())
979 rReq
.AppendItem( SfxStringItem( FID_INS_TABLE
, *pDlg
->GetFirstTable() ) );
980 rReq
.AppendItem( SfxUInt16Item( FN_PARAM_1
, static_cast<sal_uInt16
>(nTabAfter
) + 1 ) ); // 1-based
983 InsertTable( *pDlg
->GetFirstTable(), nTabAfter
);
987 std::vector
<OUString
> aNames(0);
988 InsertTables( aNames
, nTabAfter
,nCount
);
992 rViewData
.GetViewShell()->SetActive();
995 void ScTabViewShell::DoMoveTableFromDialog( SfxRequest
& rReq
, const VclPtr
<AbstractScMoveTableDlg
>& pDlg
)
997 sal_uInt16 nDoc
= pDlg
->GetSelectedDocument();
998 SCTAB nTab
= pDlg
->GetSelectedTable();
999 bool bCpy
= pDlg
->GetCopyTable();
1000 bool bRna
= pDlg
->GetRenameTable();
1002 // Leave aTabName string empty, when Rename is FALSE.
1005 pDlg
->GetTabNameString( aTabName
);
1009 OUString aFoundDocName
;
1010 if ( nDoc
!= SC_DOC_NEW
)
1012 ScDocShell
* pSh
= ScDocShell::GetShellByNum( nDoc
);
1015 aFoundDocName
= pSh
->GetTitle();
1016 if ( !pSh
->GetDocument().IsDocEditable() )
1018 ErrorMessage(STR_READONLYERR
);
1023 rReq
.AppendItem( SfxStringItem( FID_TAB_MOVE
, aFoundDocName
) );
1024 // 1-based table, if not APPEND
1025 SCTAB nBasicTab
= ( nTab
<= MAXTAB
) ? (nTab
+1) : nTab
;
1026 rReq
.AppendItem( SfxUInt16Item( FN_PARAM_1
, static_cast<sal_uInt16
>(nBasicTab
) ) );
1027 rReq
.AppendItem( SfxBoolItem( FN_PARAM_2
, bCpy
) );
1030 rReq
.Done(); // record, while doc is active
1031 MoveTable( nDoc
, nTab
, bCpy
, &aTabName
);
1035 void ScTabViewShell::ExecuteAppendOrRenameTable(SfxRequest
& rReq
)
1037 ScViewData
& rViewData
= GetViewData();
1038 ScDocument
& rDoc
= rViewData
.GetDocument();
1039 sal_uInt16 nSlot
= rReq
.GetSlot();
1040 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
1042 if ( nSlot
== FID_TAB_MENU_RENAME
)
1043 nSlot
= FID_TAB_RENAME
; // equal execute
1045 SCTAB nTabNr
= rViewData
.GetTabNo();
1046 ScMarkData
& rMark
= rViewData
.GetMarkData();
1047 SCTAB nTabSelCount
= rMark
.GetSelectCount();
1049 if ( !rDoc
.IsDocEditable() )
1050 return; // everything locked
1052 if ( nSlot
!= FID_TAB_APPEND
&&
1053 ( rDoc
.IsTabProtected( nTabNr
) || nTabSelCount
> 1 ) )
1054 return; // no rename
1056 if( pReqArgs
!= nullptr )
1059 const SfxPoolItem
* pItem
;
1062 if( pReqArgs
->HasItem( FN_PARAM_1
, &pItem
) )
1064 nTabNr
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue();
1066 // inserting is 1-based, let's be consistent
1071 if( pReqArgs
->HasItem( nSlot
, &pItem
) )
1072 aName
= static_cast<const SfxStringItem
*>(pItem
)->GetValue();
1076 case FID_TAB_APPEND
:
1077 bDone
= AppendTable( aName
);
1079 case FID_TAB_RENAME
:
1080 bDone
= RenameTable( aName
, nTabNr
);
1086 rReq
.Done( *pReqArgs
);
1097 case FID_TAB_APPEND
:
1098 aDlgTitle
= ScResId(SCSTR_APDTABLE
);
1099 rDoc
.CreateValidTabName( aName
);
1100 sHelpId
= HID_SC_APPEND_NAME
;
1103 case FID_TAB_RENAME
:
1104 aDlgTitle
= ScResId(SCSTR_RENAMETAB
);
1105 rDoc
.GetName( rViewData
.GetTabNo(), aName
);
1106 sHelpId
= HID_SC_RENAME_NAME
;
1110 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
1112 VclPtr
<AbstractScStringInputDlg
> pDlg(pFact
->CreateScStringInputDlg(
1113 GetFrameWeld(), aDlgTitle
, ScResId(SCSTR_NAME
),
1114 aName
, GetStaticInterface()->GetSlot(nSlot
)->GetCommand(),
1117 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
1118 rReq
.Ignore(); // the 'old' request is not relevant any more
1119 ExecuteAppendOrRenameTableDialog(pDlg
, xRequest
, nSlot
);
1123 void ScTabViewShell::ExecuteAppendOrRenameTableDialog(const VclPtr
<AbstractScStringInputDlg
>& pDlg
,
1124 const std::shared_ptr
<SfxRequest
>& xReq
,
1127 pDlg
->StartExecuteAsync(
1128 [this, pDlg
, xReq
, nSlot
] (sal_Int32 nResult
)->void
1130 if (DoAppendOrRenameTableDialog(nResult
, pDlg
, xReq
, nSlot
))
1131 ExecuteAppendOrRenameTableDialog(pDlg
, xReq
, nSlot
);
1133 pDlg
->disposeOnce();
1138 bool ScTabViewShell::DoAppendOrRenameTableDialog(sal_Int32 nResult
, const VclPtr
<AbstractScStringInputDlg
>& pDlg
,
1139 const std::shared_ptr
<SfxRequest
>& xReq
,
1142 if (nResult
!= RET_OK
)
1145 ScViewData
& rViewData
= GetViewData();
1146 SCTAB nTabNr
= rViewData
.GetTabNo();
1149 OUString aName
= pDlg
->GetInputString();
1153 case FID_TAB_APPEND
:
1154 bDone
= AppendTable( aName
);
1156 case FID_TAB_RENAME
:
1157 bDone
= RenameTable( aName
, nTabNr
);
1163 if (nSlot
== FID_TAB_APPEND
)
1164 rViewData
.GetViewShell()->SetActive();
1165 xReq
->AppendItem( SfxStringItem( nSlot
, aName
) );
1172 #if HAVE_FEATURE_SCRIPTING
1173 StarBASIC::Error( ERRCODE_BASIC_SETPROP_FAILED
); // XXX error handling???
1178 OUString
aErrMsg ( ScResId( STR_INVALIDTABNAME
) );
1179 std::unique_ptr
<weld::MessageDialog
> xBox(Application::CreateMessageDialog(GetFrameWeld(),
1180 VclMessageType::Warning
, VclButtonsType::Ok
, aErrMsg
));
1188 void ScTabViewShell::ExecuteSetTableBackgroundCol(SfxRequest
& rReq
)
1190 ScViewData
& rViewData
= GetViewData();
1191 ScDocument
& rDoc
= rViewData
.GetDocument();
1192 sal_uInt16 nSlot
= rReq
.GetSlot();
1193 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
1194 if ( nSlot
== FID_TAB_MENU_SET_TAB_BG_COLOR
)
1195 nSlot
= FID_TAB_SET_TAB_BG_COLOR
;
1196 SCTAB nTabNr
= rViewData
.GetTabNo();
1197 ScMarkData
& rMark
= rViewData
.GetMarkData();
1198 SCTAB nTabSelCount
= rMark
.GetSelectCount();
1199 SCTAB nCurrentTab
= rViewData
.GetTabNo();
1201 if ( !rDoc
.IsDocEditable() )
1204 if ( rDoc
.IsTabProtected( nTabNr
) ) // ||nTabSelCount > 1
1207 if( pReqArgs
!= nullptr )
1210 const SfxPoolItem
* pItem
;
1213 if( pReqArgs
->HasItem( nSlot
, &pItem
) )
1214 aColor
= static_cast<const SvxColorItem
*>(pItem
)->GetValue();
1216 if ( nTabSelCount
> 1 )
1218 std::unique_ptr
<ScUndoTabColorInfo::List
>
1219 pTabColorList(new ScUndoTabColorInfo::List
);
1220 for (const auto& rTab
: rMark
)
1222 if ( !rDoc
.IsTabProtected(rTab
) )
1224 ScUndoTabColorInfo
aTabColorInfo(rTab
);
1225 aTabColorInfo
.maNewTabBgColor
= aColor
;
1226 pTabColorList
->push_back(aTabColorInfo
);
1229 bDone
= SetTabBgColor( *pTabColorList
);
1233 bDone
= SetTabBgColor( aColor
, nCurrentTab
); //ScViewFunc.SetTabBgColor
1237 rReq
.Done( *pReqArgs
);
1242 Color aTabBgColor
= rDoc
.GetTabBgColor( nCurrentTab
);
1243 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
1244 VclPtr
<AbstractScTabBgColorDlg
> pDlg(pFact
->CreateScTabBgColorDlg(
1246 ScResId(SCSTR_SET_TAB_BG_COLOR
),
1247 ScResId(SCSTR_NO_TAB_BG_COLOR
),
1250 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
1251 rReq
.Ignore(); // the 'old' request is not relevant any more
1252 ExecuteTableBackgroundDialog(pDlg
, xRequest
, aTabBgColor
, nSlot
);
1256 void ScTabViewShell::ExecuteTableBackgroundDialog(const VclPtr
<AbstractScTabBgColorDlg
>& pDlg
,
1257 const std::shared_ptr
<SfxRequest
>& xReq
,
1258 Color aOldTabBgColor
, sal_uInt16 nSlot
)
1260 pDlg
->StartExecuteAsync(
1261 [this, pDlg
, xReq
, aOldTabBgColor
, nSlot
] (sal_Int32 nResult
)->void
1263 if (DoTableBackgroundDialog(nResult
, pDlg
, xReq
, aOldTabBgColor
, nSlot
))
1264 ExecuteTableBackgroundDialog(pDlg
, xReq
, aOldTabBgColor
, nSlot
);
1266 pDlg
->disposeOnce();
1271 bool ScTabViewShell::DoTableBackgroundDialog(sal_Int32 nResult
, const VclPtr
<AbstractScTabBgColorDlg
>& pDlg
,
1272 const std::shared_ptr
<SfxRequest
>& xReq
,
1273 Color aOldTabBgColor
, sal_uInt16 nSlot
)
1275 if (nResult
!= RET_OK
)
1278 ScViewData
& rViewData
= GetViewData();
1279 ScDocument
& rDoc
= rViewData
.GetDocument();
1280 ScMarkData
& rMark
= rViewData
.GetMarkData();
1281 SCTAB nCurrentTab
= rViewData
.GetTabNo();
1282 SCTAB nTabSelCount
= rMark
.GetSelectCount();
1283 bool bDone
= false; /// temp
1284 Color aSelectedColor
;
1285 pDlg
->GetSelectedColor(aSelectedColor
);
1286 std::unique_ptr
<ScUndoTabColorInfo::List
>
1287 pTabColorList(new ScUndoTabColorInfo::List
);
1288 if ( nTabSelCount
> 1 )
1290 for (const auto& rTab
: rMark
)
1292 if ( !rDoc
.IsTabProtected(rTab
) )
1294 ScUndoTabColorInfo
aTabColorInfo(rTab
);
1295 aTabColorInfo
.maNewTabBgColor
= aSelectedColor
;
1296 pTabColorList
->push_back(aTabColorInfo
);
1299 bDone
= SetTabBgColor( *pTabColorList
);
1303 bDone
= SetTabBgColor( aSelectedColor
, nCurrentTab
); //ScViewFunc.SetTabBgColor
1308 xReq
->AppendItem( SvxColorItem( aOldTabBgColor
, nSlot
) );
1315 #if HAVE_FEATURE_SCRIPTING
1316 StarBASIC::Error( ERRCODE_BASIC_SETPROP_FAILED
);
1324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */