/src/libreoffice/sc/source/ui/dbgui/dbtabledlg.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 <memory> |
21 | | #include <sal/config.h> |
22 | | |
23 | | #include <cassert> |
24 | | |
25 | | #include <comphelper/string.hxx> |
26 | | #include <unotools/charclass.hxx> |
27 | | #include <vcl/svapp.hxx> |
28 | | #include <vcl/weld/MessageDialog.hxx> |
29 | | #include <o3tl/string_view.hxx> |
30 | | |
31 | | #include <reffact.hxx> |
32 | | #include <document.hxx> |
33 | | #include <globstr.hrc> |
34 | | #include <scresid.hxx> |
35 | | #include <dbtabledlg.hxx> |
36 | | #include <dbdocfun.hxx> |
37 | | #include <tablestyle.hxx> |
38 | | |
39 | | ScDbTableDlg::ScDbTableDlg(SfxBindings* pB, SfxChildWindow* pCW, weld::Window* pParent, |
40 | | ScViewData& rViewData) |
41 | 0 | : ScAnyRefDlgController(pB, pCW, pParent, u"modules/scalc/ui/definetablerangedialog.ui"_ustr, |
42 | 0 | u"tablerangedialog"_ustr) |
43 | 0 | , m_rViewData(rViewData) |
44 | 0 | , rDoc(rViewData.GetDocument()) |
45 | 0 | , bRefInputMode(true) |
46 | 0 | , aAddrDetails(rDoc.GetAddressConvention(), 0, 0) |
47 | 0 | , m_xAssignFrame(m_xBuilder->weld_frame(u"rangeframe"_ustr)) |
48 | 0 | , m_xEdAssign(new formula::RefEdit(m_xBuilder->weld_entry(u"assign"_ustr))) |
49 | 0 | , m_xRbAssign(new formula::RefButton(m_xBuilder->weld_button(u"assgnrb"_ustr))) |
50 | 0 | , m_xOptions(m_xBuilder->weld_widget(u"options"_ustr)) |
51 | 0 | , m_xBtnHeader(m_xBuilder->weld_check_button(u"bheaders"_ustr)) |
52 | 0 | , m_xBtnOk(m_xBuilder->weld_button(u"ok"_ustr)) |
53 | 0 | , m_xBtnCancel(m_xBuilder->weld_button(u"cancel"_ustr)) |
54 | 0 | { |
55 | 0 | m_xEdAssign->SetReferences(this, m_xAssignFrame.get()); |
56 | 0 | m_xRbAssign->SetReferences(this, m_xEdAssign.get()); |
57 | |
|
58 | 0 | Init(); |
59 | 0 | } |
60 | | |
61 | | ScDbTableDlg::~ScDbTableDlg() |
62 | 0 | { |
63 | 0 | if (m_xInfoBox) |
64 | 0 | m_xInfoBox->response(RET_OK); |
65 | 0 | } |
66 | | |
67 | | void ScDbTableDlg::Init() |
68 | 0 | { |
69 | 0 | m_xBtnHeader->set_active(true); // Default: with column headers |
70 | |
|
71 | 0 | m_xBtnOk->connect_clicked(LINK(this, ScDbTableDlg, OkBtnHdl)); |
72 | 0 | m_xBtnCancel->connect_clicked(LINK(this, ScDbTableDlg, CancelBtnHdl)); |
73 | 0 | m_xEdAssign->SetModifyHdl(LINK(this, ScDbTableDlg, AssModifyHdl)); |
74 | |
|
75 | 0 | SCCOL nStartCol, nEndCol = 0; |
76 | 0 | SCROW nStartRow, nEndRow = 0; |
77 | 0 | SCTAB nStartTab, nEndTab = 0; |
78 | |
|
79 | 0 | m_rViewData.GetSimpleArea(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab); |
80 | 0 | theCurArea = ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab); |
81 | 0 | OUString theAreaStr = theCurArea.Format(rDoc, ScRefFlags::RANGE_ABS_3D, aAddrDetails); |
82 | 0 | m_xEdAssign->SetText(theAreaStr); |
83 | |
|
84 | 0 | bInvalid = false; |
85 | 0 | } |
86 | | |
87 | | void ScDbTableDlg::SetReference(const ScRange& rRef, ScDocument& rDocP) |
88 | 0 | { |
89 | 0 | if (!m_xEdAssign->GetWidget()->get_sensitive()) |
90 | 0 | return; |
91 | | |
92 | 0 | if (rRef.aStart != rRef.aEnd) |
93 | 0 | RefInputStart(m_xEdAssign.get()); |
94 | |
|
95 | 0 | theCurArea = rRef; |
96 | |
|
97 | 0 | OUString aRefStr(theCurArea.Format(rDocP, ScRefFlags::RANGE_ABS_3D, aAddrDetails)); |
98 | 0 | m_xEdAssign->SetRefString(aRefStr); |
99 | 0 | m_xOptions->set_sensitive(true); |
100 | 0 | } |
101 | | |
102 | 0 | void ScDbTableDlg::Close() { DoClose(ScTableLayoutWrapper::GetChildWindowId()); } |
103 | | |
104 | | void ScDbTableDlg::SetActive() |
105 | 0 | { |
106 | 0 | m_xEdAssign->GrabFocus(); |
107 | 0 | RefInputDone(); |
108 | 0 | } |
109 | | |
110 | 0 | bool ScDbTableDlg::IsRefInputMode() const { return bRefInputMode; } |
111 | | |
112 | | void ScDbTableDlg::ErrorBox(const OUString& rString) |
113 | 0 | { |
114 | 0 | if (m_xInfoBox) |
115 | 0 | m_xInfoBox->response(RET_OK); |
116 | |
|
117 | 0 | m_xInfoBox = std::shared_ptr<weld::MessageDialog>(Application::CreateMessageDialog( |
118 | 0 | m_xDialog.get(), VclMessageType::Warning, VclButtonsType::Ok, rString)); |
119 | |
|
120 | 0 | m_xInfoBox->runAsync(m_xInfoBox, [this](sal_Int32) { m_xInfoBox = nullptr; }); |
121 | 0 | } |
122 | | |
123 | | IMPL_LINK_NOARG(ScDbTableDlg, OkBtnHdl, weld::Button&, void) |
124 | 0 | { |
125 | 0 | bInvalid = false; |
126 | |
|
127 | 0 | OUString aNewArea = m_xEdAssign->GetText(); |
128 | |
|
129 | 0 | if (aNewArea.isEmpty()) |
130 | 0 | return; |
131 | | |
132 | 0 | ScRange aTmpRange; |
133 | 0 | if (aTmpRange.ParseAny(aNewArea, rDoc, aAddrDetails) & ScRefFlags::VALID) |
134 | 0 | { |
135 | 0 | if (aTmpRange.aStart.Row() == aTmpRange.aEnd.Row()) // minimum 2 row height needs |
136 | 0 | aTmpRange.aEnd.IncRow(); |
137 | 0 | theCurArea = aTmpRange; |
138 | |
|
139 | 0 | std::vector<const ScDBData*> aDBData = rDoc.GetAllNamedDBsInArea( |
140 | 0 | theCurArea.aStart.Col(), theCurArea.aStart.Row(), theCurArea.aEnd.Col(), |
141 | 0 | theCurArea.aEnd.Row(), theCurArea.aStart.Tab()); |
142 | |
|
143 | 0 | for (const ScDBData* pDBData : aDBData) |
144 | 0 | { |
145 | 0 | if (pDBData->GetTableStyleInfo()) |
146 | 0 | { |
147 | 0 | bInvalid = true; |
148 | 0 | theCurArea = ScRange(); |
149 | 0 | break; |
150 | 0 | } |
151 | 0 | } |
152 | |
|
153 | 0 | if (bInvalid) |
154 | 0 | { |
155 | 0 | ErrorBox(ScResId(STR_INVALIDTABLE)); |
156 | 0 | m_xEdAssign->SelectAll(); |
157 | 0 | m_xEdAssign->GrabFocus(); |
158 | 0 | return; |
159 | 0 | } |
160 | | |
161 | | // insert new area |
162 | 0 | OUString aTable = ScResId(STR_CALC_TABLE); |
163 | 0 | tools::Long nCount = 0; |
164 | 0 | const ScDBData* pDummy = nullptr; |
165 | 0 | ScDBCollection::NamedDBs& rDBs = rDoc.GetDBCollection()->getNamedDBs(); |
166 | 0 | OUString aNewName; |
167 | 0 | do |
168 | 0 | { |
169 | 0 | ++nCount; |
170 | 0 | aNewName = aTable + OUString::number(nCount); |
171 | 0 | pDummy = rDBs.findByUpperName(ScGlobal::getCharClass().uppercase(aNewName)); |
172 | 0 | } while (pDummy); |
173 | |
|
174 | 0 | OUString aDefault = u""_ustr; |
175 | 0 | if (const ScTableStyles* pTableStyles = rDoc.GetTableStyles()) |
176 | 0 | { |
177 | 0 | const ScTableStyle* pTableStyle |
178 | 0 | = pTableStyles->GetTableStyle(u"TableStyleMedium2"_ustr); |
179 | 0 | if (pTableStyle) |
180 | 0 | aDefault = u"TableStyleMedium2"_ustr; |
181 | 0 | } |
182 | |
|
183 | 0 | ScDBDocFunc aFunc(*m_rViewData.GetDocShell()); |
184 | 0 | bInvalid = !aFunc.AddDBTable(aNewName, ScRange(theCurArea.aStart, theCurArea.aEnd), |
185 | 0 | m_xBtnHeader->get_active(), true, false, aDefault); |
186 | |
|
187 | 0 | m_xEdAssign->SetText(u""_ustr); |
188 | 0 | m_xBtnHeader->set_active(true); |
189 | 0 | theCurArea = ScRange(); |
190 | 0 | } |
191 | 0 | else |
192 | 0 | { |
193 | 0 | ErrorBox(ScResId(STR_ERR_INVALID_AREA)); |
194 | 0 | m_xEdAssign->SelectAll(); |
195 | 0 | m_xEdAssign->GrabFocus(); |
196 | 0 | bInvalid = true; |
197 | 0 | } |
198 | | |
199 | 0 | if (!bInvalid) |
200 | 0 | response(RET_OK); |
201 | 0 | } |
202 | | |
203 | 0 | IMPL_LINK_NOARG(ScDbTableDlg, CancelBtnHdl, weld::Button&, void) { response(RET_CANCEL); } |
204 | | |
205 | | IMPL_LINK_NOARG(ScDbTableDlg, AssModifyHdl, formula::RefEdit&, void) |
206 | 0 | { |
207 | 0 | ScRange aTmpRange; |
208 | 0 | OUString aText = m_xEdAssign->GetText(); |
209 | 0 | if (aTmpRange.ParseAny(aText, rDoc, aAddrDetails) & ScRefFlags::VALID) |
210 | 0 | theCurArea = aTmpRange; |
211 | |
|
212 | 0 | if (!aText.isEmpty()) |
213 | 0 | { |
214 | 0 | m_xBtnHeader->set_sensitive(true); |
215 | 0 | } |
216 | 0 | else |
217 | 0 | { |
218 | 0 | m_xBtnHeader->set_sensitive(false); |
219 | 0 | } |
220 | 0 | } |
221 | | |
222 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |