tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / tabvwshf.cxx
blob70b9e424c32f91bcea38b8b858f1526e45f0e529
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 <config_features.h>
22 #include <memory>
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>
39 #include <sc.hrc>
40 #include <helpids.h>
41 #include <docsh.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>
56 #include <vector>
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
73 switch ( nSlot )
75 case FID_TABLE_VISIBLE:
77 OUString aName;
78 rDoc.GetName( nCurrentTab, aName );
80 bool bVisible=true;
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();
93 HideTable( rMark );
96 else // fade in
98 std::vector<OUString> rNames { aName };
99 ShowTable( rNames );
102 break;
104 case FID_TABLE_HIDE:
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.
111 if (pReqArgs)
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 );
130 break;
132 case FID_TABLE_SHOW:
134 std::vector<OUString> rNames;
135 if ( pReqArgs )
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);
142 ShowTable( rNames );
144 if( ! rReq.IsAPI() )
145 rReq.Done();
148 else
150 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
152 VclPtr<AbstractScShowTabDlg> pDlg(pFact->CreateScShowTabDlg(GetFrameWeld()));
154 OUString aTabName;
155 bool bFirst = true;
156 for ( SCTAB i=0; i != nTabCount; i++ )
158 if (!rDoc.IsVisible(i))
160 rDoc.GetName( i, aTabName );
161 pDlg->Insert( aTabName, bFirst );
162 bFirst = false;
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 );
179 xReq->Done();
181 pDlg->disposeOnce();
183 rReq.Ignore();
186 break;
188 case FID_INS_TABLE:
189 case FID_INS_TABLE_EXT:
190 ExecuteInsertTable(rReq);
191 break;
193 case FID_TAB_APPEND:
194 case FID_TAB_RENAME:
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);
203 break;
205 case FID_TAB_MOVE:
207 ExecuteMoveTable(rReq);
209 break;
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);
216 sal_uInt16 nDoc = 0;
217 bool bCpy = true;
219 SfxObjectShell* pSh = SfxObjectShell::GetFirst();
220 ScDocShell* pScSh = nullptr;
221 sal_uInt16 i = 0;
223 // Determine the index of the current document
224 while ( pSh )
226 pScSh = dynamic_cast<ScDocShell*>( pSh );
228 if( pScSh )
230 if (aDocName == pScSh->GetTitle(SFX_TITLE_FULLNAME))
232 nDoc = i;
233 break;
235 // Only count ScDocShell
236 i++;
238 pSh = SfxObjectShell::GetNext( *pSh );
241 MoveTable( nDoc, nTab + 1, bCpy );
243 break;
245 case FID_DELETE_TABLE:
247 bool bHasIndex = (pReqArgs != nullptr);
249 // allow removing via the Index/FID_DELETE_TABLE parameter
250 SCTAB nTabNr = nCurrentTab;
251 if (bHasIndex)
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
259 if (nTabNr > 0)
260 --nTabNr;
264 bool bDoIt = bHasIndex;
265 if (!bDoIt)
267 bool bTabWithPivotTable = false;
268 if (rDoc.HasPivotTable())
270 const ScDPCollection* pDPs = rDoc.GetDPCollection();
271 if (pDPs)
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)
289 bTabOutSel = true;
290 if (bTabWithPivotTable && bTabOutSel)
291 break;
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)
298 break;
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,
316 aStr));
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());
322 else
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) )
330 SCCOL nStartCol;
331 SCROW nStartRow;
332 bHasData = rDoc.GetDataStart( i, nStartCol, nStartRow );
335 // Do not ask for confirmation if all selected tabs are empty
336 if (bHasData)
338 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
339 VclMessageType::Question, VclButtonsType::YesNo,
340 aQueryDeleteTab));
341 xQueryBox->set_default_response(RET_YES);
343 // no parameter given, ask for confirmation
344 bDoIt = (RET_YES == xQueryBox->run());
346 else
347 bDoIt = true;
351 if (bDoIt)
353 SCTAB nNewTab = nCurrentTab;
354 std::vector<SCTAB> TheTabs;
356 if (bHasIndex)
358 // sheet no. provided by the parameter
359 TheTabs.push_back(nTabNr);
360 if (nNewTab > nTabNr && nNewTab > 0)
361 --nNewTab;
363 else
365 SCTAB nFirstTab = 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);
373 bTabFlag = true;
374 if (nNewTab == i && i+1 < nTabCount)
375 nNewTab++;
377 if (!bTabFlag)
378 nFirstTab = i;
380 if (nNewTab >= nTabCount - static_cast<SCTAB>(TheTabs.size()))
381 nNewTab = nFirstTab;
384 rViewData.SetTabNo(nNewTab);
385 DeleteTables(TheTabs);
386 TheTabs.clear();
387 rReq.Done();
390 break;
392 case FID_TAB_RTL:
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();
412 else
413 rFunc.SetLayoutRTL( nCurrentTab, bSet );
415 break;
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();
425 PaintGrid();
426 rReq.Done();
428 break;
430 case FID_TAB_SET_TAB_BG_COLOR:
431 case FID_TAB_MENU_SET_TAB_BG_COLOR:
432 ExecuteSetTableBackgroundCol(rReq);
433 break;
435 case FID_TAB_EVENTS:
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();
451 break;
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);
459 break;
460 default:
461 OSL_FAIL("unknown message for ViewShell");
462 break;
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();
480 while ( nWhich )
482 switch ( nWhich )
485 case FID_TABLE_VISIBLE:
486 rSet.Put( SfxBoolItem( nWhich, rDoc.IsVisible(nTab) ));
487 break;
489 case FID_TABLE_HIDE:
491 sal_uInt16 nVis = 0;
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))
495 ++nVis;
496 if ( nVis<=nTabSelCount || !rDoc.IsDocEditable() )
497 rSet.DisableItem( nWhich );
499 break;
501 case FID_TABLE_SHOW:
503 bool bHasHidden = false;
504 for ( SCTAB i=0; i < nTabCount && !bHasHidden; i++ )
505 if (!rDoc.IsVisible(i))
506 bHasHidden = true;
507 if ( !bHasHidden || rDoc.IsDocProtected() || nTabSelCount > 1 )
508 rSet.DisableItem( nWhich );
510 break;
512 case FID_DELETE_TABLE:
514 if ( rDoc.GetChangeTrack() )
515 rSet.DisableItem( nWhich );
516 else
518 sal_uInt16 nVis = 0;
519 for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
520 if (rDoc.IsVisible(i))
521 ++nVis;
522 if ( rDoc.IsTabProtected(nTab)
523 || !rDoc.IsDocEditable()
524 || nVis < 2
525 || nTabSelCount == nTabCount)
526 rSet.DisableItem( nWhich );
529 break;
531 case FID_INS_TABLE:
532 case FID_INS_TABLE_EXT:
533 case FID_TAB_APPEND:
534 if ( !rDoc.IsDocEditable() ||
535 nTabCount > MAXTAB ||
536 ( nWhich == FID_INS_TABLE_EXT && pDocShell && pDocShell->IsDocShared() ) )
537 rSet.DisableItem( nWhich );
538 break;
540 case FID_TAB_MOVE:
541 case FID_TAB_DUPLICATE:
542 if ( !rDoc.IsDocEditable()
543 || rDoc.GetChangeTrack() != nullptr
544 || nTabCount > MAXTAB)
545 rSet.DisableItem( nWhich );
546 break;
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 );
556 break;
558 case FID_TAB_RENAME:
560 OUString aTabName;
561 rDoc.GetName( nTab, aTabName );
563 rSet.Put( SfxStringItem( nWhich, aTabName ));
566 break;
568 case FID_TAB_RTL:
570 if ( !SvtCTLOptions::IsCTLFontEnabled() )
571 rSet.DisableItem( nWhich );
572 else
573 rSet.Put( SfxBoolItem( nWhich, rDoc.IsLayoutRTL( nTab ) ) );
575 break;
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 );
584 break;
586 case FID_TAB_SET_TAB_BG_COLOR:
588 Color aColor = rDoc.GetTabBgColor( nTab );
589 rSet.Put( SvxColorItem( aColor, nWhich ) );
591 break;
593 case FID_TAB_TOGGLE_GRID:
594 rSet.Put( SfxBoolItem(nWhich, rViewData.GetShowGrid()) );
595 break;
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
610 bool bDoIt = false;
611 sal_uInt16 nDoc = 0;
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;
617 OUString aDocName;
618 OUString aTabName;
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.
639 // table is 1-based
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))
655 nContextMenuTab
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
683 // is selected.
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) {
690 OUString aTableName;
691 sal_uInt16 nDocument = 0;
692 SCTAB nTargetIndex = -1;
693 bool bCopy = false;
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.
703 if (bRna)
704 pDlg->GetTabNameString(aTableName);
706 bDoItAsync = true;
708 OUString aFoundDocName;
709 if (nDocument != SC_DOC_NEW)
711 ScDocShell* pSh = ScDocShell::GetShellByNum(nDocument);
712 if (pSh)
714 aFoundDocName = pSh->GetTitle();
715 if (!pSh->GetDocument().IsDocEditable())
717 ErrorMessage(STR_READONLYERR);
718 bDoItAsync = false;
722 xReq->AppendItem(SfxStringItem(FID_TAB_MOVE, aFoundDocName));
723 // 1-based table, if not APPEND
724 SCTAB nBasicTab = (nContextMenuTab <= MAXTAB)
725 ? (nContextMenuTab + 1)
726 : nContextMenuTab;
727 xReq->AppendItem(
728 SfxUInt16Item(FN_PARAM_1, static_cast<sal_uInt16>(nBasicTab)));
729 xReq->AppendItem(SfxBoolItem(FN_PARAM_2, bCopy));
731 if (bDoItAsync)
733 xReq->Done();
735 // send move or copy request
736 MoveTable(nDocument, nTargetIndex, bCopy, &aTableName, true,
737 nContextMenuTab);
740 pDlg->disposeOnce();
742 rReq.Ignore();
744 else
746 if (!aDocName.isEmpty())
748 SfxObjectShell* pSh = SfxObjectShell::GetFirst();
749 ScDocShell* pScSh = nullptr;
750 sal_uInt16 i=0;
752 while ( pSh )
754 pScSh = dynamic_cast<ScDocShell*>( pSh );
756 if( pScSh )
758 if (aDocName == pScSh->GetTitle())
760 nDoc = i;
761 ScDocument& rDestDoc = pScSh->GetDocument();
762 nTableCount = rDestDoc.GetTableCount();
763 bDoIt = rDestDoc.IsDocEditable();
764 break;
767 i++; // only count ScDocShell
769 pSh = SfxObjectShell::GetNext( *pSh );
772 else // no doc-name -> new doc
774 nDoc = SC_DOC_NEW;
775 bDoIt = true;
778 if ( bDoIt && nTab >= nTableCount ) // if necessary append
779 nTab = SC_TAB_APPEND;
782 else
784 OUString aDefaultName;
785 rDoc.GetName( rViewData.GetTabNo(), aDefaultName );
787 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
789 VclPtr<AbstractScMoveTableDlg> pDlg(pFact->CreateScMoveTableDlg(GetFrameWeld(),
790 aDefaultName));
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
802 // is selected.
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);
814 pDlg->disposeOnce();
819 if( bDoIt )
821 rReq.Done(); // record, while doc is active
823 if (bFromContextMenu)
824 MoveTable(nDoc, nTab, bCpy, &aTabName, true,
825 nContextMenuTab);
826 else
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() )
844 return; // locked
846 if ( pReqArgs != nullptr ) // from basic
848 bool bOk = false;
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();
861 if (nTabNr == 0)
862 nTabNr = nTabCount;
863 else
864 --nTabNr;
866 if (nTabNr > nTabCount)
867 nTabNr = nTabCount;
869 bOk = InsertTable(aName, nTabNr);
872 if (bOk)
874 rViewData.GetViewShell()->SetActive();
875 rReq.Done( *pReqArgs );
877 //! else set error
879 else // dialog
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);
891 pDlg->disposeOnce();
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;
909 sal_uInt16 n = 0;
910 const OUString* pStr = pDlg->GetFirstTable( &n );
911 while ( pStr )
913 nTabs.push_back( static_cast<SCTAB>(n) );
914 pStr = pDlg->GetNextTable( &n );
916 bool bLink = pDlg->GetTablesAsLink();
917 if (!nTabs.empty())
919 if(pDlg->IsTableBefore())
921 ImportTables( pDlg->GetDocShellTables(), nTabs.size(), nTabs.data(),
922 bLink,nTabNr );
924 else
926 SCTAB nTabAfter = nTabNr+1;
928 for(SCTAB j=nCurrentTab+1;j<nTabCount;j++)
930 if(!rDoc.IsScenario(j))
932 nTabAfter=j;
933 break;
937 ImportTables( pDlg->GetDocShellTables(), nTabs.size(), nTabs.data(),
938 bLink,nTabAfter );
942 else
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
951 rReq.Done();
953 InsertTable( *pDlg->GetFirstTable(), nTabNr );
955 else
957 std::vector<OUString> aNames(0);
958 InsertTables( aNames, nTabNr,nCount );
961 else
963 SCTAB nTabAfter = nTabNr+1;
964 SCTAB nSelHigh = rMark.GetLastSelected();
966 for(SCTAB j=nSelHigh+1;j<nTabCount;j++)
968 if(!rDoc.IsScenario(j))
970 nTabAfter=j;
971 break;
973 else // #101672#; increase nTabAfter, because it is possible that the scenario tables are the last
974 nTabAfter = j + 1;
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
981 rReq.Done();
983 InsertTable( *pDlg->GetFirstTable(), nTabAfter);
985 else
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();
1001 OUString aTabName;
1002 // Leave aTabName string empty, when Rename is FALSE.
1003 if( bRna )
1005 pDlg->GetTabNameString( aTabName );
1007 bool bDoIt = true;
1009 OUString aFoundDocName;
1010 if ( nDoc != SC_DOC_NEW )
1012 ScDocShell* pSh = ScDocShell::GetShellByNum( nDoc );
1013 if (pSh)
1015 aFoundDocName = pSh->GetTitle();
1016 if ( !pSh->GetDocument().IsDocEditable() )
1018 ErrorMessage(STR_READONLYERR);
1019 bDoIt = false;
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 ) );
1028 if( bDoIt )
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 )
1058 bool bDone = false;
1059 const SfxPoolItem* pItem;
1060 OUString aName;
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
1067 if (nTabNr > 0)
1068 --nTabNr;
1071 if( pReqArgs->HasItem( nSlot, &pItem ) )
1072 aName = static_cast<const SfxStringItem*>(pItem)->GetValue();
1074 switch ( nSlot )
1076 case FID_TAB_APPEND:
1077 bDone = AppendTable( aName );
1078 break;
1079 case FID_TAB_RENAME:
1080 bDone = RenameTable( aName, nTabNr );
1081 break;
1084 if( bDone )
1086 rReq.Done( *pReqArgs );
1089 else
1091 OUString aName;
1092 OUString aDlgTitle;
1093 OUString sHelpId;
1095 switch ( nSlot )
1097 case FID_TAB_APPEND:
1098 aDlgTitle = ScResId(SCSTR_APDTABLE);
1099 rDoc.CreateValidTabName( aName );
1100 sHelpId = HID_SC_APPEND_NAME;
1101 break;
1103 case FID_TAB_RENAME:
1104 aDlgTitle = ScResId(SCSTR_RENAMETAB);
1105 rDoc.GetName( rViewData.GetTabNo(), aName );
1106 sHelpId = HID_SC_RENAME_NAME;
1107 break;
1110 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
1112 VclPtr<AbstractScStringInputDlg> pDlg(pFact->CreateScStringInputDlg(
1113 GetFrameWeld(), aDlgTitle, ScResId(SCSTR_NAME),
1114 aName, GetStaticInterface()->GetSlot(nSlot)->GetCommand(),
1115 sHelpId));
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,
1125 sal_uInt16 nSlot)
1127 pDlg->StartExecuteAsync(
1128 [this, pDlg, xReq, nSlot] (sal_Int32 nResult)->void
1130 if (DoAppendOrRenameTableDialog(nResult, pDlg, xReq, nSlot))
1131 ExecuteAppendOrRenameTableDialog(pDlg, xReq, nSlot);
1132 else
1133 pDlg->disposeOnce();
1138 bool ScTabViewShell::DoAppendOrRenameTableDialog(sal_Int32 nResult, const VclPtr<AbstractScStringInputDlg>& pDlg,
1139 const std::shared_ptr<SfxRequest>& xReq,
1140 sal_uInt16 nSlot)
1142 if (nResult != RET_OK)
1143 return false;
1145 ScViewData& rViewData = GetViewData();
1146 SCTAB nTabNr = rViewData.GetTabNo();
1147 bool bDone = false;
1149 OUString aName = pDlg->GetInputString();
1151 switch ( nSlot )
1153 case FID_TAB_APPEND:
1154 bDone = AppendTable( aName );
1155 break;
1156 case FID_TAB_RENAME:
1157 bDone = RenameTable( aName, nTabNr );
1158 break;
1161 if ( bDone )
1163 if (nSlot == FID_TAB_APPEND)
1164 rViewData.GetViewShell()->SetActive();
1165 xReq->AppendItem( SfxStringItem( nSlot, aName ) );
1166 xReq->Done();
1168 else
1170 if( xReq->IsAPI() )
1172 #if HAVE_FEATURE_SCRIPTING
1173 StarBASIC::Error( ERRCODE_BASIC_SETPROP_FAILED ); // XXX error handling???
1174 #endif
1176 else
1178 OUString aErrMsg ( ScResId( STR_INVALIDTABNAME ) );
1179 std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
1180 VclMessageType::Warning, VclButtonsType::Ok, aErrMsg));
1181 xBox->run();
1185 return !bDone;
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() )
1202 return;
1204 if ( rDoc.IsTabProtected( nTabNr ) ) // ||nTabSelCount > 1
1205 return;
1207 if( pReqArgs != nullptr )
1209 bool bDone = false;
1210 const SfxPoolItem* pItem;
1211 Color aColor;
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 );
1231 else
1233 bDone = SetTabBgColor( aColor, nCurrentTab ); //ScViewFunc.SetTabBgColor
1235 if( bDone )
1237 rReq.Done( *pReqArgs );
1240 else
1242 Color aTabBgColor = rDoc.GetTabBgColor( nCurrentTab );
1243 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
1244 VclPtr<AbstractScTabBgColorDlg> pDlg(pFact->CreateScTabBgColorDlg(
1245 GetFrameWeld(),
1246 ScResId(SCSTR_SET_TAB_BG_COLOR),
1247 ScResId(SCSTR_NO_TAB_BG_COLOR),
1248 aTabBgColor));
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);
1265 else
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)
1276 return false;
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 );
1301 else
1303 bDone = SetTabBgColor( aSelectedColor, nCurrentTab ); //ScViewFunc.SetTabBgColor
1306 if ( bDone )
1308 xReq->AppendItem( SvxColorItem( aOldTabBgColor, nSlot ) );
1309 xReq->Done();
1311 else
1313 if( xReq->IsAPI() )
1315 #if HAVE_FEATURE_SCRIPTING
1316 StarBASIC::Error( ERRCODE_BASIC_SETPROP_FAILED );
1317 #endif
1321 return !bDone;
1324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */