cid#1607171 Data race condition
[LibreOffice.git] / sc / source / ui / navipi / scenwnd.cxx
blobeb62a7d5b6bc8562499fad75deecc85903942456
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 <sfx2/bindings.hxx>
21 #include <sfx2/dispatch.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <svl/slstitm.hxx>
24 #include <svl/stritem.hxx>
25 #include <svl/itemset.hxx>
26 #include <vcl/commandevent.hxx>
27 #include <vcl/event.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/weld.hxx>
30 #include <navipi.hxx>
31 #include <sc.hrc>
32 #include <globstr.hrc>
33 #include <scresid.hxx>
34 #include <helpids.h>
36 // class ScScenarioWindow ------------------------------------------------
38 void ScScenarioWindow::UpdateEntries( const std::vector<OUString> &rNewEntryList )
40 m_xLbScenario->clear();
41 m_aEntries.clear();
43 switch( rNewEntryList.size() )
45 case 0:
46 // no scenarios in current sheet
47 SetComment( OUString() );
48 break;
50 case 1:
51 // sheet is a scenario container, comment only
52 SetComment( rNewEntryList[0] );
53 break;
55 default:
57 // sheet contains scenarios
58 assert(rNewEntryList.size() % 3 == 0 && "ScScenarioListBox::UpdateEntries - wrong list size");
59 m_xLbScenario->freeze();
61 std::vector<OUString>::const_iterator iter;
62 for (iter = rNewEntryList.begin(); iter != rNewEntryList.end(); ++iter)
64 ScenarioEntry aEntry;
66 // first entry of a triple is the scenario name
67 aEntry.maName = *iter;
69 // second entry of a triple is the scenario comment
70 ++iter;
71 aEntry.maComment = *iter;
73 // third entry of a triple is the protection ("0" = not protected, "1" = protected)
74 ++iter;
75 aEntry.mbProtected = !(*iter).isEmpty() && (*iter)[0] != '0';
77 m_aEntries.push_back( aEntry );
78 m_xLbScenario->append_text(aEntry.maName);
80 m_xLbScenario->thaw();
81 m_xLbScenario->unselect_all();
82 SetComment(OUString());
87 IMPL_LINK_NOARG(ScScenarioWindow, SelectHdl, weld::TreeView&, void)
89 if (const ScenarioEntry* pEntry = GetSelectedScenarioEntry())
90 SetComment(pEntry->maComment);
93 IMPL_LINK_NOARG(ScScenarioWindow, DoubleClickHdl, weld::TreeView&, bool)
95 SelectScenario();
96 return true;
99 IMPL_LINK(ScScenarioWindow, KeyInputHdl, const KeyEvent&, rKEvt, bool)
101 bool bHandled = false;
103 vcl::KeyCode aCode = rKEvt.GetKeyCode();
104 switch( aCode.GetCode() )
106 case KEY_RETURN:
107 SelectScenario();
108 bHandled = true;
109 break;
110 case KEY_DELETE:
111 DeleteScenario();
112 bHandled = true;
113 break;
116 return bHandled;
119 IMPL_LINK(ScScenarioWindow, ContextMenuHdl, const CommandEvent&, rCEvt, bool)
121 bool bHandled = false;
123 if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
125 if (const ScenarioEntry* pEntry = GetSelectedScenarioEntry())
127 if (!pEntry->mbProtected)
129 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xLbScenario.get(), u"modules/scalc/ui/scenariomenu.ui"_ustr));
130 std::unique_ptr<weld::Menu> xPopup(xBuilder->weld_menu(u"menu"_ustr));
131 OUString sIdent(xPopup->popup_at_rect(m_xLbScenario.get(), tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1))));
132 if (sIdent == "delete")
133 DeleteScenario();
134 else if (sIdent == "edit")
135 EditScenario();
138 bHandled = true;
141 return bHandled;
144 const ScScenarioWindow::ScenarioEntry* ScScenarioWindow::GetSelectedScenarioEntry() const
146 size_t nPos = m_xLbScenario->get_selected_index();
147 return (nPos < m_aEntries.size()) ? &m_aEntries[ nPos ] : nullptr;
150 void ScScenarioWindow::ExecuteScenarioSlot(sal_uInt16 nSlotId)
152 if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() )
154 SfxStringItem aStringItem(nSlotId, m_xLbScenario->get_selected_text());
155 pViewFrm->GetDispatcher()->ExecuteList(nSlotId,
156 SfxCallMode::SLOT | SfxCallMode::RECORD, { &aStringItem } );
160 void ScScenarioWindow::SelectScenario()
162 if (m_xLbScenario->get_selected_index() != -1)
163 ExecuteScenarioSlot(SID_SELECT_SCENARIO);
166 void ScScenarioWindow::EditScenario()
168 if (m_xLbScenario->get_selected_index() != -1)
169 ExecuteScenarioSlot(SID_EDIT_SCENARIO);
172 void ScScenarioWindow::DeleteScenario()
174 if (m_xLbScenario->get_selected_index() != -1)
176 std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xLbScenario.get(),
177 VclMessageType::Question, VclButtonsType::YesNo,
178 ScResId(STR_QUERY_DELSCENARIO)));
179 xQueryBox->set_default_response(RET_YES);
180 if (xQueryBox->run() == RET_YES)
181 ExecuteScenarioSlot(SID_DELETE_SCENARIO);
185 // class ScScenarioWindow ------------------------------------------------
187 ScScenarioWindow::ScScenarioWindow(weld::Builder& rBuilder, const OUString& aQH_List,
188 const OUString& aQH_Comment)
189 : m_xLbScenario(rBuilder.weld_tree_view(u"scenariolist"_ustr))
190 , m_xEdComment(rBuilder.weld_text_view(u"scenariotext"_ustr))
192 m_xLbScenario->set_help_id(HID_SC_SCENWIN_TOP);
193 m_xEdComment->set_help_id(HID_SC_SCENWIN_BOTTOM);
195 m_xLbScenario->set_tooltip_text(aQH_List);
196 m_xEdComment->set_tooltip_text(aQH_Comment);
198 m_xLbScenario->connect_selection_changed(LINK(this, ScScenarioWindow, SelectHdl));
199 m_xLbScenario->connect_row_activated(LINK(this, ScScenarioWindow, DoubleClickHdl));
200 m_xLbScenario->connect_key_press(LINK(this, ScScenarioWindow, KeyInputHdl));
201 m_xLbScenario->connect_popup_menu(LINK(this, ScScenarioWindow, ContextMenuHdl));
203 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
204 if (pViewFrm)
206 SfxBindings& rBindings = pViewFrm->GetBindings();
207 rBindings.Invalidate( SID_SELECT_SCENARIO );
208 rBindings.Update( SID_SELECT_SCENARIO );
212 ScScenarioWindow::~ScScenarioWindow()
216 void ScScenarioWindow::NotifyState( const SfxPoolItem* pState )
218 if( pState )
220 m_xLbScenario->set_sensitive(true);
222 if ( auto pStringItem = dynamic_cast<const SfxStringItem*>( pState) )
224 const OUString& aNewEntry( pStringItem->GetValue() );
226 if (!aNewEntry.isEmpty())
227 m_xLbScenario->select_text(aNewEntry);
228 else
229 m_xLbScenario->unselect_all();
231 else if ( auto pStringListItem = dynamic_cast<const SfxStringListItem*>( pState) )
233 UpdateEntries(pStringListItem->GetList());
236 else
238 m_xLbScenario->set_sensitive(false);
239 m_xLbScenario->unselect_all();
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */