1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <com/sun/star/table/BorderLineStyle.hpp>
21
22 #include <comphelper/lok.hxx>
23 #include <editeng/boxitem.hxx>
24 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
25 #include <o3tl/temporary.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/lokhelper.hxx>
28 #include <sfx2/request.hxx>
29 #include <sfx2/sfxdlg.hxx>
30 #include <sfx2/sidebar/Sidebar.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <svl/ilstitem.hxx>
33 #include <svl/int64item.hxx>
34 #include <svl/srchitem.hxx>
35 #include <svl/srchdefs.hxx>
36 #include <svl/stritem.hxx>
37 #include <svl/whiter.hxx>
38 #include <svx/numinf.hxx>
39 #include <svx/zoomslideritem.hxx>
40
41 #include <global.hxx>
42 #include <appoptio.hxx>
43 #include <attrib.hxx>
44 #include <cellform.hxx>
45 #include <cellvalue.hxx>
46 #include <compiler.hxx>
47 #include <docsh.hxx>
48 #include <document.hxx>
49 #include <formulacell.hxx>
50 #include <globstr.hrc>
51 #include <inputhdl.hxx>
52 #include <inputwin.hxx>
53 #include <markdata.hxx>
54 #include <patattr.hxx>
55 #include <sc.hrc>
56 #include <scabstdlg.hxx>
57 #include <scitems.hxx>
58 #include <scmod.hxx>
59 #include <scresid.hxx>
60 #include <stlpool.hxx>
61 #include <tabvwsh.hxx>
62 #include <tokenarray.hxx>
63 #include <viewdata.hxx>
64
65 #include <memory>
66
67 using namespace com::sun::star;
68
GetFunction(OUString & rFuncStr,FormulaError nErrCode)69 bool ScTabViewShell::GetFunction( OUString& rFuncStr, FormulaError nErrCode )
70 {
71 sal_uInt32 nFuncs = SC_MOD()->GetAppOptions().GetStatusFunc();
72 ScViewData& rViewData = GetViewData();
73 ScMarkData& rMark = rViewData.GetMarkData();
74 bool bIgnoreError = (rMark.IsMarked() || rMark.IsMultiMarked());
75 bool bFirst = true;
76 for ( sal_uInt16 nFunc = 0; nFunc < 32; nFunc++ )
77 {
78 if ( !(nFuncs & (1 << nFunc)) )
79 continue;
80 ScSubTotalFunc eFunc = static_cast<ScSubTotalFunc>(nFunc);
81
82 if (bIgnoreError && (eFunc == SUBTOTAL_FUNC_CNT || eFunc == SUBTOTAL_FUNC_CNT2))
83 nErrCode = FormulaError::NONE;
84
85 if (nErrCode != FormulaError::NONE)
86 {
87 rFuncStr = ScGlobal::GetLongErrorString(nErrCode);
88 return true;
89 }
90
91 const char* pGlobStrId = nullptr;
92 switch (eFunc)
93 {
94 case SUBTOTAL_FUNC_AVE: pGlobStrId = STR_FUN_TEXT_AVG; break;
95 case SUBTOTAL_FUNC_CNT: pGlobStrId = STR_FUN_TEXT_COUNT; break;
96 case SUBTOTAL_FUNC_CNT2: pGlobStrId = STR_FUN_TEXT_COUNT2; break;
97 case SUBTOTAL_FUNC_MAX: pGlobStrId = STR_FUN_TEXT_MAX; break;
98 case SUBTOTAL_FUNC_MIN: pGlobStrId = STR_FUN_TEXT_MIN; break;
99 case SUBTOTAL_FUNC_SUM: pGlobStrId = STR_FUN_TEXT_SUM; break;
100 case SUBTOTAL_FUNC_SELECTION_COUNT: pGlobStrId = STR_FUN_TEXT_SELECTION_COUNT; break;
101
102 default:
103 {
104 // added to avoid warnings
105 }
106 }
107 if (pGlobStrId)
108 {
109 ScDocument* pDoc = rViewData.GetDocument();
110 SCCOL nPosX = rViewData.GetCurX();
111 SCROW nPosY = rViewData.GetCurY();
112 SCTAB nTab = rViewData.GetTabNo();
113
114 OUString aStr = ScResId(pGlobStrId) + ": ";
115
116 ScAddress aCursor( nPosX, nPosY, nTab );
117 double nVal;
118 if ( pDoc->GetSelectionFunction( eFunc, aCursor, rMark, nVal ) )
119 {
120 if ( nVal == 0.0 )
121 aStr += "0";
122 else
123 {
124 // Number in the standard format, the other on the cursor position
125 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
126 sal_uInt32 nNumFmt = 0;
127 if ( eFunc != SUBTOTAL_FUNC_CNT && eFunc != SUBTOTAL_FUNC_CNT2 && eFunc != SUBTOTAL_FUNC_SELECTION_COUNT)
128 {
129 // number format from attributes or formula
130 pDoc->GetNumberFormat( nPosX, nPosY, nTab, nNumFmt );
131 }
132
133 OUString aValStr;
134 Color* pDummy;
135 pFormatter->GetOutputString( nVal, nNumFmt, aValStr, &pDummy );
136 aStr += aValStr;
137 }
138 }
139 if ( bFirst )
140 {
141 rFuncStr += aStr;
142 bFirst = false;
143 }
144 else
145 rFuncStr += "; " + aStr;
146 }
147 }
148
149 return !rFuncStr.isEmpty();
150 }
151
152 // Functions that are disabled, depending on the selection
153 // Default:
154 // SID_DELETE,
155 // SID_DELETE_CONTENTS,
156 // FID_DELETE_CELL
157 // FID_VALIDATION
158
GetState(SfxItemSet & rSet)159 void ScTabViewShell::GetState( SfxItemSet& rSet )
160 {
161 ScViewData& rViewData = GetViewData();
162 ScDocument* pDoc = rViewData.GetDocument();
163 ScDocShell* pDocShell = rViewData.GetDocShell();
164 ScMarkData& rMark = rViewData.GetMarkData();
165 SCCOL nPosX = rViewData.GetCurX();
166 SCROW nPosY = rViewData.GetCurY();
167 SCTAB nTab = rViewData.GetTabNo();
168
169 SfxViewFrame* pThisFrame = GetViewFrame();
170 bool bOle = GetViewFrame()->GetFrame().IsInPlace();
171
172 SCTAB nTabSelCount = rMark.GetSelectCount();
173
174 SfxWhichIter aIter(rSet);
175 sal_uInt16 nWhich = aIter.FirstWhich();
176
177 while ( nWhich )
178 {
179 switch ( nWhich )
180 {
181 case FID_CHG_COMMENT:
182 {
183 ScDocShell* pDocSh = GetViewData().GetDocShell();
184 ScAddress aPos( nPosX, nPosY, nTab );
185 if ( pDocSh->IsReadOnly() || !pDocSh->GetChangeAction(aPos) || pDocSh->IsDocShared() )
186 rSet.DisableItem( nWhich );
187 }
188 break;
189
190 case SID_OPENDLG_EDIT_PRINTAREA:
191 case SID_ADD_PRINTAREA:
192 case SID_DEFINE_PRINTAREA:
193 {
194 if ( pDocShell && pDocShell->IsDocShared() )
195 {
196 rSet.DisableItem( nWhich );
197 }
198 }
199 break;
200
201 case SID_DELETE_PRINTAREA:
202 if ( pDocShell && pDocShell->IsDocShared() )
203 {
204 rSet.DisableItem( nWhich );
205 }
206 else if (pDoc->IsPrintEntireSheet(nTab))
207 rSet.DisableItem(nWhich);
208 break;
209
210 case SID_STATUS_PAGESTYLE:
211 case SID_HFEDIT:
212 GetViewData().GetDocShell()->GetStatePageStyle( rSet, nTab );
213 break;
214
215 case SID_SEARCH_ITEM:
216 {
217 SvxSearchItem aItem(ScGlobal::GetSearchItem()); // make a copy.
218 // Search on current selection if a range is marked.
219 aItem.SetSelection(rMark.IsMarked());
220 rSet.Put(aItem);
221 break;
222 }
223
224 case SID_SEARCH_OPTIONS:
225 {
226 // Anything goes
227 SearchOptionFlags nOptions = SearchOptionFlags::ALL;
228
229 // No replacement if ReadOnly
230 if (GetViewData().GetDocShell()->IsReadOnly())
231 nOptions &= ~SearchOptionFlags( SearchOptionFlags::REPLACE | SearchOptionFlags::REPLACE_ALL );
232 rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(nOptions) ) );
233 }
234 break;
235
236 case SID_CURRENTCELL:
237 {
238 ScAddress aScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(), 0 );
239 OUString aAddr(aScAddress.Format(ScRefFlags::ADDR_ABS, nullptr, pDoc->GetAddressConvention()));
240 SfxStringItem aPosItem( SID_CURRENTCELL, aAddr );
241
242 rSet.Put( aPosItem );
243 }
244 break;
245
246 case SID_CURRENTTAB:
247 // Table for Basic is 1-based
248 rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(GetViewData().GetTabNo()) + 1 ) );
249 break;
250
251 case SID_CURRENTDOC:
252 rSet.Put( SfxStringItem( nWhich, GetViewData().GetDocShell()->GetTitle() ) );
253 break;
254
255 case FID_TOGGLEINPUTLINE:
256 {
257 sal_uInt16 nId = ScInputWindowWrapper::GetChildWindowId();
258
259 if ( pThisFrame->KnowsChildWindow( nId ) )
260 {
261 SfxChildWindow* pWnd = pThisFrame->GetChildWindow( nId );
262 rSet.Put( SfxBoolItem( nWhich, pWnd != nullptr ) );
263 }
264 else
265 rSet.DisableItem( nWhich );
266 }
267 break;
268
269 case FID_DEL_MANUALBREAKS:
270 if (!pDoc->HasManualBreaks(nTab))
271 rSet.DisableItem( nWhich );
272 break;
273
274 case FID_RESET_PRINTZOOM:
275 {
276 // disable if already set to default
277
278 OUString aStyleName = pDoc->GetPageStyle( nTab );
279 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
280 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName,
281 SfxStyleFamily::Page );
282 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
283 if ( pStyleSheet )
284 {
285 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
286 sal_uInt16 nScale = rStyleSet.Get(ATTR_PAGE_SCALE).GetValue();
287 sal_uInt16 nPages = rStyleSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue();
288 if ( nScale == 100 && nPages == 0 )
289 rSet.DisableItem( nWhich );
290 }
291 }
292 break;
293
294 case FID_SCALE:
295 case SID_ATTR_ZOOM:
296 if ( bOle )
297 rSet.DisableItem( nWhich );
298 else
299 {
300 const Fraction& rOldY = GetViewData().GetZoomY();
301 sal_uInt16 nZoom = static_cast<sal_uInt16>(long( rOldY * 100 ));
302 rSet.Put( SvxZoomItem( SvxZoomType::PERCENT, nZoom, nWhich ) );
303 }
304 break;
305
306 case SID_ATTR_ZOOMSLIDER:
307 {
308 if ( bOle )
309 rSet.DisableItem( nWhich );
310 else
311 {
312 const Fraction& rOldY = GetViewData().GetZoomY();
313 sal_uInt16 nCurrentZoom = static_cast<sal_uInt16>(long( rOldY * 100 ));
314
315 if( nCurrentZoom )
316 {
317 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
318 aZoomSliderItem.AddSnappingPoint( 100 );
319 rSet.Put( aZoomSliderItem );
320 }
321 }
322 }
323 break;
324
325 case FID_FUNCTION_BOX:
326 {
327 const bool bBoxOpen = ::sfx2::sidebar::Sidebar::IsPanelVisible("ScFunctionsPanel",
328 pThisFrame->GetFrame().GetFrameInterface());
329 rSet.Put(SfxBoolItem(nWhich, bBoxOpen));
330 break;
331 }
332
333 case FID_TOGGLESYNTAX:
334 rSet.Put(SfxBoolItem(nWhich, GetViewData().IsSyntaxMode()));
335 break;
336
337 case FID_TOGGLEHEADERS:
338 rSet.Put(SfxBoolItem(nWhich, GetViewData().IsHeaderMode()));
339 break;
340
341 case FID_TOGGLEFORMULA:
342 {
343 const ScViewOptions& rOpts = rViewData.GetOptions();
344 bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
345 rSet.Put(SfxBoolItem(nWhich, bFormulaMode ));
346 }
347 break;
348
349 case FID_NORMALVIEWMODE:
350 case FID_PAGEBREAKMODE:
351 // always handle both slots - they exclude each other
352 if ( bOle )
353 {
354 rSet.DisableItem( FID_NORMALVIEWMODE );
355 rSet.DisableItem( FID_PAGEBREAKMODE );
356 }
357 else
358 {
359 rSet.Put(SfxBoolItem(FID_NORMALVIEWMODE, !GetViewData().IsPagebreakMode()));
360 rSet.Put(SfxBoolItem(FID_PAGEBREAKMODE, GetViewData().IsPagebreakMode()));
361 }
362 break;
363
364 case FID_PROTECT_DOC:
365 {
366 if ( pDocShell && pDocShell->IsDocShared() )
367 {
368 rSet.DisableItem( nWhich );
369 }
370 else
371 {
372 rSet.Put( SfxBoolItem( nWhich, pDoc->IsDocProtected() ) );
373 }
374 }
375 break;
376
377 case FID_PROTECT_TABLE:
378 {
379 if ( pDocShell && pDocShell->IsDocShared() )
380 {
381 rSet.DisableItem( nWhich );
382 }
383 else
384 {
385 rSet.Put( SfxBoolItem( nWhich, pDoc->IsTabProtected( nTab ) ) );
386 }
387 }
388 break;
389
390 case SID_AUTO_OUTLINE:
391 {
392 if (pDoc->GetChangeTrack()!=nullptr || GetViewData().IsMultiMarked())
393 {
394 rSet.DisableItem( nWhich );
395 }
396 }
397 break;
398
399 case SID_OUTLINE_DELETEALL:
400 {
401 SCTAB nOlTab = GetViewData().GetTabNo();
402 ScOutlineTable* pOlTable = pDoc->GetOutlineTable( nOlTab );
403 if (pOlTable == nullptr)
404 rSet.DisableItem( nWhich );
405 }
406 break;
407
408 case SID_WINDOW_SPLIT:
409 rSet.Put(SfxBoolItem(nWhich,
410 rViewData.GetHSplitMode() == SC_SPLIT_NORMAL ||
411 rViewData.GetVSplitMode() == SC_SPLIT_NORMAL ));
412 break;
413
414 case SID_WINDOW_FIX:
415 rSet.Put(SfxBoolItem(nWhich,
416 rViewData.GetHSplitMode() == SC_SPLIT_FIX ||
417 rViewData.GetVSplitMode() == SC_SPLIT_FIX ));
418 break;
419
420 case FID_CHG_SHOW:
421 {
422 if ( pDoc->GetChangeTrack() == nullptr || ( pDocShell && pDocShell->IsDocShared() ) )
423 rSet.DisableItem( nWhich );
424 }
425 break;
426 case FID_CHG_ACCEPT:
427 {
428 if(
429 ( !pDoc->GetChangeTrack() && !pThisFrame->HasChildWindow(FID_CHG_ACCEPT) )
430 ||
431 ( pDocShell && pDocShell->IsDocShared() )
432 )
433 {
434 rSet.DisableItem( nWhich);
435 }
436 else
437 {
438 rSet.Put(SfxBoolItem(FID_CHG_ACCEPT,
439 pThisFrame->HasChildWindow(FID_CHG_ACCEPT)));
440 }
441 }
442 break;
443
444 case SID_FORMATPAGE:
445 // in protected tables
446 if ( pDocShell && ( pDocShell->IsReadOnly() || pDocShell->IsDocShared() ) )
447 rSet.DisableItem( nWhich );
448 break;
449
450 case SID_PRINTPREVIEW:
451 // Toggle slot needs a State
452 rSet.Put( SfxBoolItem( nWhich, false ) );
453 break;
454
455 case SID_READONLY_MODE:
456 rSet.Put( SfxBoolItem( nWhich, GetViewData().GetDocShell()->IsReadOnly() ) );
457 break;
458
459 case FID_TAB_DESELECTALL:
460 if ( nTabSelCount == 1 )
461 rSet.DisableItem( nWhich ); // enabled only if several sheets are selected
462 break;
463
464 } // switch ( nWitch )
465 nWhich = aIter.NextWhich();
466 } // while ( nWitch )
467 }
468
ExecuteCellFormatDlg(SfxRequest & rReq,const OString & rName)469 void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest& rReq, const OString &rName)
470 {
471 ScDocument* pDoc = GetViewData().GetDocument();
472
473 std::shared_ptr<SvxBoxItem> aLineOuter(std::make_shared<SvxBoxItem>(ATTR_BORDER));
474 std::shared_ptr<SvxBoxInfoItem> aLineInner(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));
475
476 const ScPatternAttr* pOldAttrs = GetSelectionPattern();
477
478 std::shared_ptr<SfxItemSet> pOldSet(new SfxItemSet(pOldAttrs->GetItemSet()));
479 std::shared_ptr<SvxNumberInfoItem> pNumberInfoItem;
480
481 pOldSet->MergeRange(XATTR_FILLSTYLE, XATTR_FILLCOLOR);
482
483 pOldSet->MergeRange(SID_ATTR_BORDER_STYLES, SID_ATTR_BORDER_DEFAULT_WIDTH);
484
485 // We only allow these border line types.
486 const std::vector<sal_Int32> aBorderStyles{
487 table::BorderLineStyle::SOLID,
488 table::BorderLineStyle::DOTTED,
489 table::BorderLineStyle::DASHED,
490 table::BorderLineStyle::FINE_DASHED,
491 table::BorderLineStyle::DASH_DOT,
492 table::BorderLineStyle::DASH_DOT_DOT,
493 table::BorderLineStyle::DOUBLE_THIN };
494
495 SfxIntegerListItem aBorderStylesItem(SID_ATTR_BORDER_STYLES, aBorderStyles);
496 pOldSet->Put(aBorderStylesItem);
497
498 // Set the default border width to 0.75 points.
499 SfxInt64Item aBorderWidthItem(SID_ATTR_BORDER_DEFAULT_WIDTH, 75);
500 pOldSet->Put(aBorderWidthItem);
501
502 // Get border items and put them in the set:
503 GetSelectionFrame( aLineOuter, aLineInner );
504
505 //Fix border incorrect for RTL fdo#62399
506 if( pDoc->IsLayoutRTL( GetViewData().GetTabNo() ) )
507 {
508 std::shared_ptr<SvxBoxItem> aNewFrame(static_cast<SvxBoxItem*>(aLineOuter->Clone()));
509 std::shared_ptr<SvxBoxInfoItem> aTempInfo(static_cast<SvxBoxInfoItem*>(aLineInner->Clone()));
510
511 if ( aLineInner->IsValid(SvxBoxInfoItemValidFlags::LEFT) )
512 aNewFrame->SetLine( aLineOuter->GetLeft(), SvxBoxItemLine::RIGHT );
513 if ( aLineInner->IsValid(SvxBoxInfoItemValidFlags::RIGHT) )
514 aNewFrame->SetLine( aLineOuter->GetRight(), SvxBoxItemLine::LEFT );
515
516 aLineInner->SetValid( SvxBoxInfoItemValidFlags::LEFT, aTempInfo->IsValid(SvxBoxInfoItemValidFlags::RIGHT));
517 aLineInner->SetValid( SvxBoxInfoItemValidFlags::RIGHT, aTempInfo->IsValid(SvxBoxInfoItemValidFlags::LEFT));
518
519 pOldSet->Put( *aNewFrame );
520 }
521 else
522 {
523 pOldSet->Put( *aLineOuter );
524 }
525
526 pOldSet->Put( *aLineInner );
527
528 // Generate NumberFormat Value from Value and Language and box it.
529 pOldSet->Put( SfxUInt32Item( ATTR_VALUE_FORMAT,
530 pOldAttrs->GetNumberFormat( pDoc->GetFormatTable() ) ) );
531
532 pNumberInfoItem = MakeNumberInfoItem(pDoc, &GetViewData());
533
534 pOldSet->MergeRange( SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO );
535 pOldSet->Put(*pNumberInfoItem );
536
537 bInFormatDialog = true;
538 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
539
540 VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScAttrDlg(GetFrameWeld(), pOldSet.get()));
541
542 if (!rName.isEmpty())
543 pDlg->SetCurPageId(rName);
544
545 std::shared_ptr<SfxRequest> pRequest(new SfxRequest(rReq));
546 rReq.Ignore(); // the 'old' request is not relevant any more
547
548 pDlg->StartExecuteAsync([pDlg, pOldSet, pRequest, this](sal_Int32 nResult){
549 bInFormatDialog = false;
550
551 if ( nResult == RET_OK )
552 {
553 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
554
555 const SfxPoolItem* pItem=nullptr;
556 if(pOutSet->GetItemState(SID_ATTR_NUMBERFORMAT_INFO,true,&pItem)==SfxItemState::SET)
557 {
558 UpdateNumberFormatter(static_cast<const SvxNumberInfoItem&>(*pItem));
559 }
560
561 ApplyAttributes(pOutSet, pOldSet.get());
562
563 pRequest->Done(*pOutSet);
564 }
565
566 pDlg->disposeOnce();
567 });
568 }
569
IsRefInputMode() const570 bool ScTabViewShell::IsRefInputMode() const
571 {
572 ScModule* pScMod = SC_MOD();
573 if ( pScMod )
574 {
575 if( pScMod->IsRefDialogOpen() )
576 return pScMod->IsFormulaMode();
577 if( pScMod->IsFormulaMode() )
578 {
579 ScInputHandler* pHdl = pScMod->GetInputHdl();
580 if ( pHdl )
581 {
582 OUString aString = pHdl->GetEditString();
583 if ( !pHdl->GetSelIsRef() && aString.getLength() > 1 &&
584 ( aString[0] == '+' || aString[0] == '-' ) )
585 {
586 const ScViewData& rViewData = GetViewData();
587 ScDocument* pDoc = rViewData.GetDocument();
588 if ( pDoc )
589 {
590 const ScAddress aPos( rViewData.GetCurPos() );
591 ScCompiler aComp( pDoc, aPos, pDoc->GetGrammar() );
592 aComp.SetCloseBrackets( false );
593 std::unique_ptr<ScTokenArray> pArr(aComp.CompileString(aString));
594 if ( pArr && pArr->MayReferenceFollow() )
595 {
596 return true;
597 }
598 }
599 }
600 else
601 {
602 return true;
603 }
604 }
605 }
606 }
607
608 return false;
609 }
610
ExecuteInputDirect()611 void ScTabViewShell::ExecuteInputDirect()
612 {
613 if ( !IsRefInputMode() )
614 {
615 ScModule* pScMod = SC_MOD();
616 if ( pScMod )
617 {
618 pScMod->InputEnterHandler();
619 }
620 }
621 }
622
UpdateInputHandler(bool bForce,bool bStopEditing)623 void ScTabViewShell::UpdateInputHandler( bool bForce /* = sal_False */, bool bStopEditing /* = sal_True */ )
624 {
625 ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : SC_MOD()->GetInputHdl();
626
627 if ( pHdl )
628 {
629 OUString aString;
630 const EditTextObject* pObject = nullptr;
631 ScViewData& rViewData = GetViewData();
632 ScDocument* pDoc = rViewData.GetDocument();
633 SCCOL nPosX = rViewData.GetCurX();
634 SCROW nPosY = rViewData.GetCurY();
635 SCTAB nTab = rViewData.GetTabNo();
636 SCTAB nStartTab = 0;
637 SCTAB nEndTab = 0;
638 SCCOL nStartCol = 0;
639 SCROW nStartRow = 0;
640 SCCOL nEndCol = 0;
641 SCROW nEndRow = 0;
642 ScAddress aPos = rViewData.GetCurPos();
643
644 rViewData.GetSimpleArea( nStartCol, nStartRow, nStartTab,
645 nEndCol, nEndRow, nEndTab );
646
647 PutInOrder( nStartCol, nEndCol );
648 PutInOrder( nStartRow, nEndRow );
649 PutInOrder( nStartTab, nEndTab );
650
651 bool bHideFormula = false;
652 bool bHideAll = false;
653
654 if (pDoc->IsTabProtected(nTab))
655 {
656 const ScProtectionAttr* pProt = pDoc->GetAttr( nPosX,nPosY,nTab,
657 ATTR_PROTECTION);
658 bHideFormula = pProt->GetHideFormula();
659 bHideAll = pProt->GetHideCell();
660 }
661
662 if (!bHideAll)
663 {
664 ScRefCellValue rCell(*pDoc, aPos);
665 if (rCell.meType == CELLTYPE_FORMULA)
666 {
667 if (!bHideFormula)
668 rCell.mpFormula->GetFormula(aString);
669 }
670 else if (rCell.meType == CELLTYPE_EDIT)
671 {
672 pObject = rCell.mpEditText;
673 }
674 else
675 {
676 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
677 sal_uInt32 nNumFmt = pDoc->GetNumberFormat( aPos );
678
679 ScCellFormat::GetInputString( rCell, nNumFmt, aString, *pFormatter, pDoc );
680 if (rCell.meType == CELLTYPE_STRING)
681 {
682 // Put a ' in front if necessary, so that the string is not
683 // unintentionally interpreted as a number, and to show the
684 // user that it is a string (#35060#).
685 //! also for numberformat "Text"? -> then remove when editing
686 if ( pFormatter->IsNumberFormat(aString, nNumFmt, o3tl::temporary(double())) )
687 aString = "'" + aString;
688 }
689 }
690 }
691
692 ScInputHdlState aState( ScAddress( nPosX, nPosY, nTab ),
693 ScAddress( nStartCol, nStartRow, nTab ),
694 ScAddress( nEndCol, nEndRow, nTab ),
695 aString,
696 pObject );
697
698 // if using the view's local input handler, this view can always be set
699 // as current view inside NotifyChange.
700 ScTabViewShell* pSourceSh = mpInputHandler ? this : nullptr;
701
702 pHdl->NotifyChange( &aState, bForce, pSourceSh, bStopEditing );
703 }
704
705 SfxBindings& rBindings = GetViewFrame()->GetBindings();
706 rBindings.Invalidate( SID_STATUS_SUM ); // always together with the input row
707 rBindings.Invalidate( SID_ATTR_SIZE );
708 rBindings.Invalidate( SID_TABLE_CELL );
709 }
710
UpdateInputHandlerCellAdjust(SvxCellHorJustify eJust)711 void ScTabViewShell::UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust )
712 {
713 if( ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : SC_MOD()->GetInputHdl() )
714 pHdl->UpdateCellAdjust( eJust );
715 }
716
ExecuteSave(SfxRequest & rReq)717 void ScTabViewShell::ExecuteSave( SfxRequest& rReq )
718 {
719 // only SID_SAVEDOC / SID_SAVEASDOC
720 bool bCommitChanges = true;
721 const SfxItemSet* pReqArgs = rReq.GetArgs();
722 const SfxPoolItem* pItem;
723
724 if (pReqArgs && pReqArgs->HasItem(FN_PARAM_1, &pItem))
725 bCommitChanges = !static_cast<const SfxBoolItem*>(pItem)->GetValue();
726
727 // Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed
728 if (bCommitChanges)
729 {
730 if (comphelper::LibreOfficeKit::isActive())
731 {
732 // Normally this isn't needed, but in Calc when editing a cell formula
733 // and manually saving (without changing cells or hitting enter), while
734 // InputEnterHandler will mark the doc as modified (when it is), because
735 // we will save the doc immediately afterwards, the modified state event
736 // is clobbered. To avoid that, we notify all views immediately of the
737 // modified state, apply the modification, then save the document.
738 ScInputHandler* pHdl = GetInputHandler();
739 if (pHdl != nullptr && pHdl->GetModified())
740 SfxLokHelper::notifyAllViews(LOK_CALLBACK_STATE_CHANGED, ".uno:ModifiedStatus=true");
741 }
742
743 SC_MOD()->InputEnterHandler();
744 }
745
746 if ( GetViewData().GetDocShell()->IsDocShared() )
747 {
748 GetViewData().GetDocShell()->SetDocumentModified();
749 }
750
751 // otherwise as normal
752 GetViewData().GetDocShell()->ExecuteSlot( rReq );
753 }
754
GetSaveState(SfxItemSet & rSet)755 void ScTabViewShell::GetSaveState( SfxItemSet& rSet )
756 {
757 SfxShell* pDocSh = GetViewData().GetDocShell();
758
759 SfxWhichIter aIter(rSet);
760 sal_uInt16 nWhich = aIter.FirstWhich();
761 while( nWhich )
762 {
763 if ( nWhich != SID_SAVEDOC || !GetViewData().GetDocShell()->IsDocShared() )
764 {
765 // get state from DocShell
766 pDocSh->GetSlotState( nWhich, nullptr, &rSet );
767 }
768 nWhich = aIter.NextWhich();
769 }
770 }
771
ExecDrawOpt(const SfxRequest & rReq)772 void ScTabViewShell::ExecDrawOpt( const SfxRequest& rReq )
773 {
774 ScViewOptions aViewOptions = GetViewData().GetOptions();
775 ScGridOptions aGridOptions = aViewOptions.GetGridOptions();
776
777 SfxBindings& rBindings = GetViewFrame()->GetBindings();
778 const SfxItemSet* pArgs = rReq.GetArgs();
779 const SfxPoolItem* pItem;
780 sal_uInt16 nSlotId = rReq.GetSlot();
781 switch (nSlotId)
782 {
783 case SID_GRID_VISIBLE:
784 if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
785 {
786 aGridOptions.SetGridVisible( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
787 aViewOptions.SetGridOptions(aGridOptions);
788 rBindings.Invalidate(SID_GRID_VISIBLE);
789 }
790 break;
791
792 case SID_GRID_USE:
793 if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
794 {
795 aGridOptions.SetUseGridSnap( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
796 aViewOptions.SetGridOptions(aGridOptions);
797 rBindings.Invalidate(SID_GRID_USE);
798 }
799 break;
800
801 case SID_HELPLINES_MOVE:
802 if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
803 {
804 aViewOptions.SetOption( VOPT_HELPLINES, static_cast<const SfxBoolItem*>(pItem)->GetValue() );
805 rBindings.Invalidate(SID_HELPLINES_MOVE);
806 }
807 break;
808 }
809
810 GetViewData().SetOptions(aViewOptions);
811 }
812
GetDrawOptState(SfxItemSet & rSet)813 void ScTabViewShell::GetDrawOptState( SfxItemSet& rSet )
814 {
815 SfxBoolItem aBool;
816
817 const ScViewOptions& rViewOptions = GetViewData().GetOptions();
818 const ScGridOptions& rGridOptions = rViewOptions.GetGridOptions();
819
820 aBool.SetValue(rGridOptions.GetGridVisible());
821 aBool.SetWhich( SID_GRID_VISIBLE );
822 rSet.Put( aBool );
823
824 aBool.SetValue(rGridOptions.GetUseGridSnap());
825 aBool.SetWhich( SID_GRID_USE );
826 rSet.Put( aBool );
827
828 aBool.SetValue(rViewOptions.GetOption( VOPT_HELPLINES ));
829 aBool.SetWhich( SID_HELPLINES_MOVE );
830 rSet.Put( aBool );
831 }
832
833 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
834