/src/libreoffice/sc/source/ui/view/viewfun6.cxx
Line | Count | Source |
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 <formula/token.hxx> |
21 | | #include <svx/svdocapt.hxx> |
22 | | #include <sfx2/bindings.hxx> |
23 | | #include <sfx2/dispatch.hxx> |
24 | | #include <sfx2/lokhelper.hxx> |
25 | | #include <svl/stritem.hxx> |
26 | | #include <svl/numformat.hxx> |
27 | | #include <svl/zforlist.hxx> |
28 | | #include <svl/zformat.hxx> |
29 | | #include <vcl/uitest/logger.hxx> |
30 | | #include <vcl/uitest/eventdescription.hxx> |
31 | | #include <vcl/keycod.hxx> |
32 | | #include <vcl/keycodes.hxx> |
33 | | #include <editeng/editview.hxx> |
34 | | #include <rtl/math.hxx> |
35 | | #include <sal/log.hxx> |
36 | | |
37 | | #include <viewfunc.hxx> |
38 | | #include <viewdata.hxx> |
39 | | #include <drwlayer.hxx> |
40 | | #include <docsh.hxx> |
41 | | #include <futext.hxx> |
42 | | #include <docfunc.hxx> |
43 | | #include <sc.hrc> |
44 | | #include <reftokenhelper.hxx> |
45 | | #include <externalrefmgr.hxx> |
46 | | #include <markdata.hxx> |
47 | | #include <drawview.hxx> |
48 | | #include <inputhdl.hxx> |
49 | | #include <tabvwsh.hxx> |
50 | | #include <scmod.hxx> |
51 | | #include <postit.hxx> |
52 | | #include <comphelper/scopeguard.hxx> |
53 | | |
54 | | #include <vector> |
55 | | |
56 | | namespace |
57 | | { |
58 | | |
59 | | void collectUIInformation( const OUString& aevent ) |
60 | 0 | { |
61 | 0 | EventDescription aDescription; |
62 | 0 | aDescription.aID = "grid_window"; |
63 | 0 | aDescription.aParameters = {{ aevent , ""}}; |
64 | 0 | aDescription.aAction = "COMMENT"; |
65 | 0 | aDescription.aParent = "MainWindow"; |
66 | 0 | aDescription.aKeyWord = "ScGridWinUIObject"; |
67 | 0 | UITestLogger::getInstance().logEvent(aDescription); |
68 | 0 | } |
69 | | |
70 | | } |
71 | | |
72 | | void ScViewFunc::DetectiveAddPred() |
73 | 0 | { |
74 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
75 | 0 | pDocSh->GetDocFunc().DetectiveAddPred( GetViewData().GetCurPos() ); |
76 | 0 | RecalcPPT(); //! use broadcast in DocFunc instead? |
77 | 0 | } |
78 | | |
79 | | void ScViewFunc::DetectiveDelPred() |
80 | 0 | { |
81 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
82 | 0 | pDocSh->GetDocFunc().DetectiveDelPred( GetViewData().GetCurPos() ); |
83 | 0 | RecalcPPT(); |
84 | 0 | } |
85 | | |
86 | | void ScViewFunc::DetectiveAddSucc() |
87 | 0 | { |
88 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
89 | 0 | pDocSh->GetDocFunc().DetectiveAddSucc( GetViewData().GetCurPos() ); |
90 | 0 | RecalcPPT(); |
91 | 0 | } |
92 | | |
93 | | void ScViewFunc::DetectiveDelSucc() |
94 | 0 | { |
95 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
96 | 0 | pDocSh->GetDocFunc().DetectiveDelSucc( GetViewData().GetCurPos() ); |
97 | 0 | RecalcPPT(); |
98 | 0 | } |
99 | | |
100 | | void ScViewFunc::DetectiveAddError() |
101 | 0 | { |
102 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
103 | 0 | pDocSh->GetDocFunc().DetectiveAddError( GetViewData().GetCurPos() ); |
104 | 0 | RecalcPPT(); |
105 | 0 | } |
106 | | |
107 | | void ScViewFunc::DetectiveDelAll() |
108 | 0 | { |
109 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
110 | 0 | pDocSh->GetDocFunc().DetectiveDelAll( GetViewData().CurrentTabForData() ); |
111 | 0 | RecalcPPT(); |
112 | 0 | } |
113 | | |
114 | | void ScViewFunc::DetectiveMarkInvalid() |
115 | 0 | { |
116 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
117 | 0 | pDocSh->GetDocFunc().DetectiveMarkInvalid( GetViewData().CurrentTabForData() ); |
118 | 0 | RecalcPPT(); |
119 | 0 | } |
120 | | |
121 | | void ScViewFunc::DetectiveRefresh() |
122 | 0 | { |
123 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
124 | 0 | pDocSh->GetDocFunc().DetectiveRefresh(); |
125 | 0 | RecalcPPT(); |
126 | 0 | } |
127 | | |
128 | | static void lcl_jumpToRange(const ScRange& rRange, ScViewData* pView, const ScDocument& rDoc) |
129 | 0 | { |
130 | 0 | OUString aAddrText(rRange.Format(rDoc, ScRefFlags::RANGE_ABS_3D)); |
131 | 0 | SfxStringItem aPosItem(SID_CURRENTCELL, aAddrText); |
132 | 0 | SfxBoolItem aUnmarkItem(FN_PARAM_1, true); // remove existing selection |
133 | 0 | pView->GetDispatcher().ExecuteList( |
134 | 0 | SID_CURRENTCELL, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, |
135 | 0 | { &aPosItem, &aUnmarkItem }); |
136 | 0 | } |
137 | | |
138 | | void ScViewFunc::MarkAndJumpToRanges(const ScRangeList& rRanges) |
139 | 0 | { |
140 | 0 | ScViewData& rView = GetViewData(); |
141 | 0 | ScDocShell* pDocSh = rView.GetDocShell(); |
142 | |
|
143 | 0 | ScRangeList aRangesToMark; |
144 | 0 | ScAddress aCurPos = rView.GetCurPos(); |
145 | 0 | size_t ListSize = rRanges.size(); |
146 | 0 | for ( size_t i = 0; i < ListSize; ++i ) |
147 | 0 | { |
148 | 0 | const ScRange & r = rRanges[i]; |
149 | | // Collect only those ranges that are on the same sheet as the current |
150 | | // cursor. |
151 | 0 | if (r.aStart.Tab() == aCurPos.Tab()) |
152 | 0 | aRangesToMark.push_back(r); |
153 | 0 | } |
154 | |
|
155 | 0 | if (aRangesToMark.empty()) |
156 | 0 | return; |
157 | | |
158 | | // Jump to the first range of all precedent ranges. |
159 | 0 | const ScRange & r = aRangesToMark.front(); |
160 | 0 | lcl_jumpToRange(r, &rView, pDocSh->GetDocument()); |
161 | |
|
162 | 0 | ListSize = aRangesToMark.size(); |
163 | 0 | for ( size_t i = 0; i < ListSize; ++i ) |
164 | 0 | { |
165 | 0 | MarkRange(aRangesToMark[i], false, true); |
166 | 0 | } |
167 | 0 | } |
168 | | |
169 | | void ScViewFunc::DetectiveMarkPred() |
170 | 0 | { |
171 | 0 | ScViewData& rView = GetViewData(); |
172 | 0 | ScDocShell* pDocSh = rView.GetDocShell(); |
173 | 0 | ScDocument& rDoc = pDocSh->GetDocument(); |
174 | 0 | ScMarkData& rMarkData = rView.GetMarkData(); |
175 | 0 | ScAddress aCurPos = rView.GetCurPos(); |
176 | 0 | ScRangeList aRanges; |
177 | 0 | if (rMarkData.IsMarked() || rMarkData.IsMultiMarked()) |
178 | 0 | rMarkData.FillRangeListWithMarks(&aRanges, false); |
179 | 0 | else |
180 | 0 | aRanges.push_back(ScRange(aCurPos)); |
181 | |
|
182 | 0 | std::vector<ScTokenRef> aRefTokens; |
183 | 0 | pDocSh->GetDocFunc().DetectiveCollectAllPreds(aRanges, aRefTokens); |
184 | |
|
185 | 0 | if (aRefTokens.empty()) |
186 | | // No precedents found. Nothing to do. |
187 | 0 | return; |
188 | | |
189 | 0 | ScTokenRef p = aRefTokens.front(); |
190 | 0 | if (ScRefTokenHelper::isExternalRef(p)) |
191 | 0 | { |
192 | | // This is external. Open the external document if available, and |
193 | | // jump to the destination. |
194 | |
|
195 | 0 | sal_uInt16 nFileId = p->GetIndex(); |
196 | 0 | ScExternalRefManager* pRefMgr = rDoc.GetExternalRefManager(); |
197 | 0 | const OUString* pPath = pRefMgr->getExternalFileName(nFileId); |
198 | |
|
199 | 0 | ScRange aRange; |
200 | 0 | if (pPath && ScRefTokenHelper::getRangeFromToken(&rDoc, aRange, p, aCurPos, true)) |
201 | 0 | { |
202 | 0 | OUString aTabName = p->GetString().getString(); |
203 | 0 | OUString aRangeStr(aRange.Format(rDoc, ScRefFlags::VALID)); |
204 | 0 | OUString sUrl = |
205 | 0 | *pPath + |
206 | 0 | "#" + |
207 | 0 | aTabName + |
208 | 0 | "." + |
209 | 0 | aRangeStr; |
210 | |
|
211 | 0 | ScGlobal::OpenURL(sUrl, OUString()); |
212 | 0 | } |
213 | 0 | return; |
214 | 0 | } |
215 | 0 | else |
216 | 0 | { |
217 | 0 | ScRange aRange; |
218 | 0 | ScRefTokenHelper::getRangeFromToken(&rDoc, aRange, p, aCurPos); |
219 | 0 | if (aRange.aStart.Tab() != aCurPos.Tab()) |
220 | 0 | { |
221 | | // The first precedent range is on a different sheet. Jump to it |
222 | | // immediately and forget the rest. |
223 | 0 | lcl_jumpToRange(aRange, &rView, rDoc); |
224 | 0 | return; |
225 | 0 | } |
226 | 0 | } |
227 | | |
228 | 0 | ScRangeList aDestRanges; |
229 | 0 | ScRefTokenHelper::getRangeListFromTokens(&rDoc, aDestRanges, aRefTokens, aCurPos); |
230 | 0 | MarkAndJumpToRanges(aDestRanges); |
231 | 0 | } |
232 | | |
233 | | void ScViewFunc::DetectiveMarkSucc() |
234 | 0 | { |
235 | 0 | ScViewData& rView = GetViewData(); |
236 | 0 | ScDocShell* pDocSh = rView.GetDocShell(); |
237 | 0 | ScMarkData& rMarkData = rView.GetMarkData(); |
238 | 0 | ScAddress aCurPos = rView.GetCurPos(); |
239 | 0 | ScRangeList aRanges; |
240 | 0 | if (rMarkData.IsMarked() || rMarkData.IsMultiMarked()) |
241 | 0 | rMarkData.FillRangeListWithMarks(&aRanges, false); |
242 | 0 | else |
243 | 0 | aRanges.push_back(ScRange(aCurPos)); |
244 | |
|
245 | 0 | std::vector<ScTokenRef> aRefTokens; |
246 | 0 | pDocSh->GetDocFunc().DetectiveCollectAllSuccs(aRanges, aRefTokens); |
247 | |
|
248 | 0 | if (aRefTokens.empty()) |
249 | | // No dependents found. Nothing to do. |
250 | 0 | return; |
251 | | |
252 | 0 | ScRangeList aDestRanges; |
253 | 0 | ScRefTokenHelper::getRangeListFromTokens(&rView.GetDocument(), aDestRanges, aRefTokens, aCurPos); |
254 | 0 | MarkAndJumpToRanges(aDestRanges); |
255 | 0 | } |
256 | | |
257 | | /** Insert date or time into current cell. |
258 | | |
259 | | If cell is in input or edit mode, insert date/time at cursor position, else |
260 | | create a date or time or date+time cell as follows: |
261 | | |
262 | | - key date on time cell => current date + time of cell => date+time formatted cell |
263 | | - unless time cell was empty or 00:00 time => current date => date formatted cell |
264 | | - key date on date+time cell => current date + 00:00 time => date+time formatted cell |
265 | | - unless date was current date => current date => date formatted cell |
266 | | - key date on other cell => current date => date formatted cell |
267 | | - key time on date cell => date of cell + current time => date+time formatted cell |
268 | | - unless date cell was empty => current time => time formatted cell |
269 | | - key time on date+time cell => current time => time formatted cell |
270 | | - unless cell was empty => current date+time => date+time formatted cell |
271 | | - key time on other cell => current time => time formatted cell |
272 | | */ |
273 | | void ScViewFunc::InsertCurrentTime(SvNumFormatType nReqFmt, const OUString& rUndoStr) |
274 | 0 | { |
275 | 0 | ScViewData& rViewData = GetViewData(); |
276 | |
|
277 | 0 | ScInputHandler* pInputHdl = ScModule::get()->GetInputHdl(rViewData.GetViewShell()); |
278 | 0 | bool bInputMode = (pInputHdl && pInputHdl->IsInputMode()); |
279 | |
|
280 | 0 | ScDocShell* pDocSh = rViewData.GetDocShell(); |
281 | 0 | ScDocument& rDoc = pDocSh->GetDocument(); |
282 | 0 | ScAddress aCurPos = rViewData.GetCurPos(); |
283 | 0 | const sal_uInt32 nCurNumFormat = rDoc.GetNumberFormat(ScRange(aCurPos)); |
284 | 0 | SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); |
285 | 0 | const SvNumberformat* pCurNumFormatEntry = pFormatter->GetEntry(nCurNumFormat); |
286 | 0 | const SvNumFormatType nCurNumFormatType = (pCurNumFormatEntry ? |
287 | 0 | pCurNumFormatEntry->GetMaskedType() : SvNumFormatType::UNDEFINED); |
288 | |
|
289 | 0 | const int nView(comphelper::LibreOfficeKit::isActive() ? SfxLokHelper::getCurrentView() : -1); |
290 | 0 | if (nView >= 0) |
291 | 0 | { |
292 | 0 | const auto [isTimezoneSet, aTimezone] = SfxLokHelper::getViewTimezone(nView); |
293 | 0 | comphelper::LibreOfficeKit::setTimezone(isTimezoneSet, aTimezone); |
294 | 0 | } |
295 | |
|
296 | 0 | comphelper::ScopeGuard aAutoUserTimezone( |
297 | 0 | [nView]() |
298 | 0 | { |
299 | 0 | if (nView >= 0) |
300 | 0 | { |
301 | 0 | const auto [isTimezoneSet, aTimezone] = SfxLokHelper::getDefaultTimezone(); |
302 | 0 | comphelper::LibreOfficeKit::setTimezone(isTimezoneSet, aTimezone); |
303 | 0 | } |
304 | 0 | }); |
305 | |
|
306 | 0 | if (bInputMode) |
307 | 0 | { |
308 | 0 | double fVal = 0.0; |
309 | 0 | sal_uInt32 nFormat = 0; |
310 | 0 | switch (nReqFmt) |
311 | 0 | { |
312 | 0 | case SvNumFormatType::DATE: |
313 | 0 | { |
314 | 0 | Date aActDate( Date::SYSTEM ); |
315 | 0 | fVal = aActDate - pFormatter->GetNullDate(); |
316 | 0 | if (nCurNumFormatType == SvNumFormatType::DATE) |
317 | 0 | nFormat = nCurNumFormat; |
318 | 0 | } |
319 | 0 | break; |
320 | 0 | case SvNumFormatType::TIME: |
321 | 0 | { |
322 | 0 | tools::Time aActTime( tools::Time::SYSTEM ); |
323 | 0 | fVal = aActTime.GetTimeInDays(); |
324 | 0 | if (nCurNumFormatType == SvNumFormatType::TIME) |
325 | 0 | nFormat = nCurNumFormat; |
326 | 0 | } |
327 | 0 | break; |
328 | 0 | default: |
329 | 0 | SAL_WARN("sc.ui","unhandled current date/time request"); |
330 | 0 | nReqFmt = SvNumFormatType::DATETIME; |
331 | 0 | [[fallthrough]]; |
332 | 0 | case SvNumFormatType::DATETIME: |
333 | 0 | { |
334 | 0 | DateTime aActDateTime( DateTime::SYSTEM ); |
335 | 0 | fVal = DateTime::Sub( aActDateTime, DateTime( pFormatter->GetNullDate())); |
336 | 0 | if (nCurNumFormatType == SvNumFormatType::DATETIME) |
337 | 0 | nFormat = nCurNumFormat; |
338 | 0 | } |
339 | 0 | break; |
340 | 0 | } |
341 | | |
342 | 0 | if (!nFormat) |
343 | 0 | { |
344 | 0 | const LanguageType nLang = (pCurNumFormatEntry ? pCurNumFormatEntry->GetLanguage() : ScGlobal::eLnge); |
345 | 0 | nFormat = pFormatter->GetStandardFormat( nReqFmt, nLang); |
346 | | // This would return a more precise format with seconds and 100th |
347 | | // seconds for a time request. |
348 | | //nFormat = pFormatter->GetStandardFormat( fVal, nFormat, nReqFmt, nLang); |
349 | 0 | } |
350 | 0 | OUString aString; |
351 | 0 | const Color* pColor; |
352 | 0 | pFormatter->GetOutputString( fVal, nFormat, aString, &pColor); |
353 | |
|
354 | 0 | pInputHdl->DataChanging(); |
355 | 0 | EditView* pTopView = pInputHdl->GetTopView(); |
356 | 0 | if (pTopView) |
357 | 0 | pTopView->InsertText( aString); |
358 | 0 | EditView* pTableView = pInputHdl->GetTableView(); |
359 | 0 | if (pTableView) |
360 | 0 | pTableView->InsertText( aString); |
361 | 0 | pInputHdl->DataChanged(); |
362 | 0 | } |
363 | 0 | else |
364 | 0 | { |
365 | | // Clear "Enter pastes" mode. |
366 | 0 | rViewData.SetPasteMode( ScPasteFlags::NONE ); |
367 | | // Clear CopySourceOverlay in each window of a split/frozen tabview. |
368 | 0 | rViewData.GetViewShell()->UpdateCopySourceOverlay(); |
369 | |
|
370 | 0 | bool bForceReqFmt = false; |
371 | 0 | const double fCell = rDoc.GetValue( aCurPos); |
372 | | // Combine requested date/time stamp with existing cell time/date, if any. |
373 | 0 | switch (nReqFmt) |
374 | 0 | { |
375 | 0 | case SvNumFormatType::DATE: |
376 | 0 | switch (nCurNumFormatType) |
377 | 0 | { |
378 | 0 | case SvNumFormatType::TIME: |
379 | | // An empty cell formatted as time (or 00:00 time) shall |
380 | | // not result in the current date with 00:00 time, but only |
381 | | // in current date. |
382 | 0 | if (fCell != 0.0) |
383 | 0 | nReqFmt = SvNumFormatType::DATETIME; |
384 | 0 | break; |
385 | 0 | case SvNumFormatType::DATETIME: |
386 | 0 | { |
387 | | // Force to only date if the existing date+time is the |
388 | | // current date. This way inserting current date twice |
389 | | // on an existing date+time cell can be used to force |
390 | | // date, which otherwise would only be possible by |
391 | | // applying a date format. |
392 | 0 | double fDate = rtl::math::approxFloor( fCell); |
393 | 0 | if (fDate == (Date( Date::SYSTEM) - pFormatter->GetNullDate())) |
394 | 0 | bForceReqFmt = true; |
395 | 0 | } |
396 | 0 | break; |
397 | 0 | default: break; |
398 | 0 | } |
399 | 0 | break; |
400 | 0 | case SvNumFormatType::TIME: |
401 | 0 | switch (nCurNumFormatType) |
402 | 0 | { |
403 | 0 | case SvNumFormatType::DATE: |
404 | | // An empty cell formatted as date shall not result in the |
405 | | // null date and current time, but only in current time. |
406 | 0 | if (fCell != 0.0) |
407 | 0 | nReqFmt = SvNumFormatType::DATETIME; |
408 | 0 | break; |
409 | 0 | case SvNumFormatType::DATETIME: |
410 | | // Requesting current time on an empty date+time cell |
411 | | // inserts both current date+time. |
412 | 0 | if (fCell == 0.0) |
413 | 0 | nReqFmt = SvNumFormatType::DATETIME; |
414 | 0 | else |
415 | 0 | { |
416 | | // Add current time to an existing date+time where time is |
417 | | // zero and date is current date, else force time only. |
418 | 0 | double fDate = rtl::math::approxFloor( fCell); |
419 | 0 | double fTime = fCell - fDate; |
420 | 0 | if (fTime == 0.0 && fDate == (Date( Date::SYSTEM) - pFormatter->GetNullDate())) |
421 | 0 | nReqFmt = SvNumFormatType::DATETIME; |
422 | 0 | else |
423 | 0 | bForceReqFmt = true; |
424 | 0 | } |
425 | 0 | break; |
426 | 0 | default: break; |
427 | 0 | } |
428 | 0 | break; |
429 | 0 | default: |
430 | 0 | SAL_WARN("sc.ui","unhandled current date/time request"); |
431 | 0 | nReqFmt = SvNumFormatType::DATETIME; |
432 | 0 | [[fallthrough]]; |
433 | 0 | case SvNumFormatType::DATETIME: |
434 | 0 | break; |
435 | 0 | } |
436 | 0 | double fVal = 0.0; |
437 | 0 | switch (nReqFmt) |
438 | 0 | { |
439 | 0 | case SvNumFormatType::DATE: |
440 | 0 | { |
441 | 0 | Date aActDate( Date::SYSTEM ); |
442 | 0 | fVal = aActDate - pFormatter->GetNullDate(); |
443 | 0 | } |
444 | 0 | break; |
445 | 0 | case SvNumFormatType::TIME: |
446 | 0 | { |
447 | 0 | tools::Time aActTime( tools::Time::SYSTEM ); |
448 | 0 | fVal = aActTime.GetTimeInDays(); |
449 | 0 | } |
450 | 0 | break; |
451 | 0 | case SvNumFormatType::DATETIME: |
452 | 0 | switch (nCurNumFormatType) |
453 | 0 | { |
454 | 0 | case SvNumFormatType::DATE: |
455 | 0 | { |
456 | 0 | double fDate = rtl::math::approxFloor( fCell); |
457 | 0 | tools::Time aActTime( tools::Time::SYSTEM ); |
458 | 0 | fVal = fDate + aActTime.GetTimeInDays(); |
459 | 0 | } |
460 | 0 | break; |
461 | 0 | case SvNumFormatType::TIME: |
462 | 0 | { |
463 | 0 | double fTime = fCell - rtl::math::approxFloor( fCell); |
464 | 0 | Date aActDate( Date::SYSTEM ); |
465 | 0 | fVal = (aActDate - pFormatter->GetNullDate()) + fTime; |
466 | 0 | } |
467 | 0 | break; |
468 | 0 | default: |
469 | 0 | { |
470 | 0 | DateTime aActDateTime( DateTime::SYSTEM ); |
471 | 0 | fVal = DateTime::Sub( aActDateTime, DateTime( pFormatter->GetNullDate())); |
472 | 0 | } |
473 | 0 | } |
474 | 0 | break; |
475 | 0 | default: break; |
476 | |
|
477 | 0 | } |
478 | | |
479 | 0 | SfxUndoManager* pUndoMgr = pDocSh->GetUndoManager(); |
480 | 0 | pUndoMgr->EnterListAction(rUndoStr, rUndoStr, 0, rViewData.GetViewShell()->GetViewShellId()); |
481 | |
|
482 | 0 | pDocSh->GetDocFunc().SetValueCell(aCurPos, fVal, true); |
483 | | |
484 | | // Set the new cell format only when it differs from the current cell |
485 | | // format type. Preserve a date+time format unless we force a format |
486 | | // through. |
487 | 0 | if (bForceReqFmt || (nReqFmt != nCurNumFormatType && nCurNumFormatType != SvNumFormatType::DATETIME)) |
488 | 0 | SetNumberFormat(nReqFmt); |
489 | 0 | else |
490 | 0 | rViewData.UpdateInputHandler(); // update input bar with new value |
491 | |
|
492 | 0 | pUndoMgr->LeaveListAction(); |
493 | 0 | } |
494 | 0 | } |
495 | | |
496 | | void ScViewFunc::ShowNote( bool bShow ) |
497 | 0 | { |
498 | 0 | if( bShow ) |
499 | 0 | HideNoteOverlay(); |
500 | 0 | const ScViewData& rViewData = GetViewData(); |
501 | 0 | ScAddress aPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.CurrentTabForData() ); |
502 | | // show note moved to ScDocFunc, to be able to use it in notesuno.cxx |
503 | 0 | rViewData.GetDocShell()->GetDocFunc().ShowNote( aPos, bShow ); |
504 | 0 | } |
505 | | |
506 | | void ScViewFunc::EditNote() |
507 | 0 | { |
508 | | // HACK: If another text object is selected, make sure it gets unselected |
509 | 0 | if (FuText* pOldFuText = dynamic_cast<FuText*>(GetDrawFuncPtr())) |
510 | 0 | pOldFuText->KeyInput(KeyEvent(0, vcl::KeyCode(KEY_ESCAPE))); |
511 | | |
512 | | // for editing display and activate |
513 | |
|
514 | 0 | ScDocShell* pDocSh = GetViewData().GetDocShell(); |
515 | 0 | ScDocument& rDoc = pDocSh->GetDocument(); |
516 | 0 | SCCOL nCol = GetViewData().GetCurX(); |
517 | 0 | SCROW nRow = GetViewData().GetCurY(); |
518 | 0 | SCTAB nTab = GetViewData().CurrentTabForData(); |
519 | 0 | ScAddress aPos( nCol, nRow, nTab ); |
520 | | |
521 | | // start drawing undo to catch undo action for insertion of the caption object |
522 | 0 | pDocSh->MakeDrawLayer(); |
523 | 0 | ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); |
524 | 0 | pDrawLayer->BeginCalcUndo(true); |
525 | | // generated undo action is processed in FuText::StopEditMode |
526 | | |
527 | | // get existing note or create a new note (including caption drawing object) |
528 | 0 | ScPostIt* pNote = rDoc.GetOrCreateNote( aPos ); |
529 | 0 | if(!pNote) |
530 | 0 | return; |
531 | | |
532 | | // hide temporary note caption |
533 | 0 | HideNoteOverlay(); |
534 | | // show caption object without changing internal visibility state |
535 | 0 | pNote->ShowCaptionTemp( aPos ); |
536 | | |
537 | | /* Drawing object has been created in ScDocument::GetOrCreateNote() or |
538 | | in ScPostIt::ShowCaptionTemp(), so ScPostIt::GetCaption() should |
539 | | return a caption object. */ |
540 | 0 | SdrCaptionObj* pCaption = pNote->GetCaption(); |
541 | 0 | if( !pCaption ) |
542 | 0 | return; |
543 | | |
544 | 0 | if ( ScDrawView* pScDrawView = GetScDrawView() ) |
545 | 0 | pScDrawView->SyncForGrid( pCaption ); |
546 | | |
547 | | // activate object (as in FuSelection::TestComment) |
548 | 0 | GetViewData().GetDispatcher().Execute( SID_DRAW_NOTEEDIT, SfxCallMode::SYNCHRON | SfxCallMode::RECORD ); |
549 | | // now get the created FuText and set into EditMode |
550 | 0 | FuText* pFuText = dynamic_cast<FuText*>(GetDrawFuncPtr()); |
551 | 0 | if (pFuText) |
552 | 0 | { |
553 | 0 | ScrollToObject( pCaption ); // make object fully visible |
554 | 0 | pFuText->SetInEditMode( pCaption ); |
555 | |
|
556 | 0 | ScTabView::OnLOKNoteStateChanged( pNote ); |
557 | 0 | } |
558 | 0 | collectUIInformation(u"OPEN"_ustr); |
559 | 0 | } |
560 | | |
561 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |