LibreOffice Module sc (master)  1
datafdlg.cxx
Go to the documentation of this file.
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 
10 #undef SC_DLLIMPLEMENTATION
11 
12 #include <datafdlg.hxx>
13 #include <viewdata.hxx>
14 #include <docsh.hxx>
15 #include <tabvwsh.hxx>
16 
17 #include <vcl/svapp.hxx>
18 
20  : GenericDialogController(pParent, "modules/scalc/ui/dataform.ui", "DataFormDialog")
21  , pTabViewShell(pTabViewShellOri)
22  , aColLength(0)
23  , nCurrentRow(0)
24  , nStartCol(0)
25  , nEndCol(0)
26  , nStartRow(0)
27  , nEndRow(0)
28  , nTab(0)
29  , m_xBtnNew(m_xBuilder->weld_button("new"))
30  , m_xBtnDelete(m_xBuilder->weld_button("delete"))
31  , m_xBtnRestore(m_xBuilder->weld_button("restore"))
32  , m_xBtnPrev(m_xBuilder->weld_button("prev"))
33  , m_xBtnNext(m_xBuilder->weld_button("next"))
34  , m_xBtnClose(m_xBuilder->weld_button("close"))
35  , m_xSlider(m_xBuilder->weld_scrolled_window("scrollbar", true))
36  , m_xGrid(m_xBuilder->weld_container("grid"))
37  , m_xFixedText(m_xBuilder->weld_label("label"))
38 {
39  sNewRecord = m_xFixedText->get_label();
40 
41  //read header from current document, and add new controls
42  OSL_ENSURE( pTabViewShell, "pTabViewShell is NULL! :-/" );
43  ScViewData& rViewData = pTabViewShell->GetViewData();
44 
45  pDoc = &rViewData.GetDocument();
46 
47  {
48  ScRange aRange;
49  rViewData.GetSimpleArea( aRange );
50  ScAddress aStart = aRange.aStart;
51  ScAddress aEnd = aRange.aEnd;
52 
53  nStartCol = aStart.Col();
54  nEndCol = aEnd.Col();
55  nStartRow = aStart.Row();
56  nEndRow = aEnd.Row();
57 
58  nTab = rViewData.GetTabNo();
59  bool bNoSelection(false);
60  //if there is no selection
61  if ((nStartCol == nEndCol) && (nStartRow == nEndRow))
62  bNoSelection = true;
63 
64  if (bNoSelection)
65  {
66  //find last not blank cell in row
67  for (int i=1;i<=MAX_DATAFORM_COLS;i++)
68  {
69  nEndCol++;
70  OUString aColName = pDoc->GetString(nEndCol, nStartRow, nTab);
71  int nColWidth = pDoc->GetColWidth( nEndCol, nTab );
72  if (aColName.isEmpty() && nColWidth)
73  {
74  nEndCol--;
75  break;
76  }
77  }
78 
79  //find first not blank cell in row
80  for (int i=1;i<=MAX_DATAFORM_COLS;i++)
81  {
82  if (nStartCol <= 0)
83  break;
84  nStartCol--;
85 
86  OUString aColName = pDoc->GetString(nStartCol, nStartRow, nTab);
87  int nColWidth = pDoc->GetColWidth( nEndCol, nTab );
88  if (aColName.isEmpty() && nColWidth)
89  {
90  nStartCol++;
91  break;
92  }
93  }
94 
95  //skip leading hide column
96  for (int i=1;i<=MAX_DATAFORM_COLS;i++)
97  {
98  int nColWidth = pDoc->GetColWidth( nStartCol, nTab );
99  if (nColWidth)
100  break;
101  nStartCol++;
102  }
103 
104  if (nEndCol < nStartCol)
105  nEndCol = nStartCol;
106 
107  //find last not blank cell in row
108  for (int i=1;i<=MAX_DATAFORM_ROWS;i++)
109  {
110  nEndRow++;
111  OUString aColName = pDoc->GetString(nStartCol, nEndRow, nTab);
112  if (aColName.isEmpty())
113  {
114  nEndRow--;
115  break;
116  }
117  }
118 
119  //find first not blank cell in row
120  for (int i=1;i<=MAX_DATAFORM_ROWS;i++)
121  {
122  if (nStartRow <= 0)
123  break;
124  nStartRow--;
125 
126  OUString aColName = pDoc->GetString(nStartCol, nStartRow, nTab);
127  if (aColName.isEmpty())
128  {
129  nStartRow++;
130  break;
131  }
132  }
133 
134  if (nEndRow < nStartRow)
135  nEndRow = nStartRow;
136  }
137 
138  nCurrentRow = nStartRow + 1;
139 
140  aColLength = nEndCol - nStartCol + 1;
141 
142  //new the controls
143  m_aEntries.reserve(aColLength);
144 
145  sal_Int32 nGridRow = 0;
146  for(sal_uInt16 nIndex = 0; nIndex < aColLength; ++nIndex)
147  {
148  OUString aFieldName = pDoc->GetString(nIndex + nStartCol, nStartRow, nTab);
149  int nColWidth = pDoc->GetColWidth( nIndex + nStartCol, nTab );
150  if (nColWidth)
151  {
152  m_aEntries.emplace_back(new ScDataFormFragment(m_xGrid.get(), nGridRow));
153 
154  ++nGridRow;
155 
156  m_aEntries[nIndex]->m_xLabel->set_label(aFieldName);
157  m_aEntries[nIndex]->m_xLabel->show();
158  m_aEntries[nIndex]->m_xEdit->show();
159  }
160  else
161  {
162  m_aEntries.emplace_back(nullptr );
163  }
164  if (m_aEntries[nIndex] != nullptr)
165  {
166  m_aEntries[nIndex]->m_xEdit->connect_changed(LINK( this, ScDataFormDlg, Impl_DataModifyHdl));
167  m_aEntries[nIndex]->m_xEdit->save_value();
168  }
169  }
170  }
171 
172  FillCtrls();
173 
174  m_xSlider->vadjustment_configure(0, 0, nEndRow - nStartRow + 1, 1, 10, 1);
175 
176  m_xBtnNew->connect_clicked(LINK( this, ScDataFormDlg, Impl_NewHdl));
177  m_xBtnPrev->connect_clicked(LINK( this, ScDataFormDlg, Impl_PrevHdl));
178  m_xBtnNext->connect_clicked(LINK( this, ScDataFormDlg, Impl_NextHdl));
179 
180  m_xBtnRestore->connect_clicked(LINK( this, ScDataFormDlg, Impl_RestoreHdl));
181  m_xBtnDelete->connect_clicked(LINK( this, ScDataFormDlg, Impl_DeleteHdl));
182  m_xBtnClose->connect_clicked(LINK( this, ScDataFormDlg, Impl_CloseHdl));
183 
184  m_xSlider->connect_vadjustment_changed(LINK( this, ScDataFormDlg, Impl_ScrollHdl));
185 
186  SetButtonState();
187 }
188 
190 {
191 }
192 
194 {
195  for (sal_uInt16 i = 0; i < aColLength; ++i)
196  {
197  if (m_aEntries[i])
198  {
199  if (nCurrentRow<=nEndRow && pDoc)
200  {
201  OUString aFieldName(pDoc->GetString(i + nStartCol, nCurrentRow, nTab));
202  m_aEntries[i]->m_xEdit->set_text(aFieldName);
203  }
204  else
205  m_aEntries[i]->m_xEdit->set_text(OUString());
206  }
207  }
208 
209  if (nCurrentRow <= nEndRow)
210  {
211  OUString sLabel =
212  OUString::number(static_cast<sal_Int32>(nCurrentRow - nStartRow)) +
213  " / " +
214  OUString::number(static_cast<sal_Int32>(nEndRow - nStartRow));
215  m_xFixedText->set_label(sLabel);
216  }
217  else
218  m_xFixedText->set_label(sNewRecord);
219 
220  m_xSlider->vadjustment_set_value(nCurrentRow-nStartRow-1);
221 }
222 
223 IMPL_LINK( ScDataFormDlg, Impl_DataModifyHdl, weld::Entry&, rEdit, void)
224 {
226  m_xBtnRestore->set_sensitive(true);
227 }
228 
230 {
231  ScViewData& rViewData = pTabViewShell->GetViewData();
232  ScDocShell* pDocSh = rViewData.GetDocShell();
233  if ( !pDoc )
234  return;
235 
236  bool bHasData = std::any_of(m_aEntries.begin(), m_aEntries.end(),
237  [](const std::unique_ptr<ScDataFormFragment>& rElem) { return (rElem != nullptr) && (!rElem->m_xEdit->get_text().isEmpty()); });
238 
239  if ( !bHasData )
240  return;
241 
242  pTabViewShell->DataFormPutData(nCurrentRow, nStartRow, nStartCol, nEndRow, nEndCol, m_aEntries, aColLength);
243  nCurrentRow++;
244  if (nCurrentRow >= nEndRow + 2)
245  {
246  nEndRow++;
247  m_xSlider->vadjustment_set_upper(nEndRow - nStartRow + 1);
248  }
249  SetButtonState();
250  FillCtrls();
251  pDocSh->SetDocumentModified();
252  pDocSh->PostPaintGridAll();
253 }
254 
256 {
257  if (pDoc)
258  {
259  if ( nCurrentRow > nStartRow +1 )
260  nCurrentRow--;
261 
262  SetButtonState();
263  FillCtrls();
264  }
265 }
266 
268 {
269  if (pDoc)
270  {
271  if ( nCurrentRow <= nEndRow)
272  nCurrentRow++;
273 
274  SetButtonState();
275  FillCtrls();
276  }
277 }
278 
279 IMPL_LINK_NOARG(ScDataFormDlg, Impl_RestoreHdl, weld::Button&, void)
280 {
281  if (pDoc)
282  {
283  FillCtrls();
284  }
285 }
286 
288 {
289  ScViewData& rViewData = pTabViewShell->GetViewData();
290  ScDocShell* pDocSh = rViewData.GetDocShell();
291  if (!pDoc)
292  return;
293 
294  ScRange aRange(nStartCol, nCurrentRow, nTab, nEndCol, nCurrentRow, nTab);
295  pDoc->DeleteRow(aRange);
296  nEndRow--;
297 
298  SetButtonState();
299  pDocSh->GetUndoManager()->Clear();
300 
301  FillCtrls();
302  pDocSh->SetDocumentModified();
303  pDocSh->PostPaintGridAll();
304 }
305 
307 {
308  m_xDialog->response(RET_CANCEL);
309 }
310 
312 {
313  auto nOffset = m_xSlider->vadjustment_get_value();
314  nCurrentRow = nStartRow + nOffset + 1;
315  SetButtonState();
316  FillCtrls();
317 }
318 
320 {
321  if (nCurrentRow > nEndRow)
322  {
323  m_xBtnDelete->set_sensitive( false );
324  m_xBtnNext->set_sensitive( false );
325  }
326  else
327  {
328  m_xBtnDelete->set_sensitive(true);
329  m_xBtnNext->set_sensitive(true);
330  }
331 
332  if (nCurrentRow == nStartRow + 1)
333  m_xBtnPrev->set_sensitive( false );
334  else
335  m_xBtnPrev->set_sensitive(true);
336 
337  m_xBtnRestore->set_sensitive( false );
338  if (!m_aEntries.empty() && m_aEntries[0] != nullptr)
339  m_aEntries[0]->m_xEdit->grab_focus();
340 }
341 
343  : m_xBuilder(Application::CreateBuilder(pGrid, "modules/scalc/ui/dataformfragment.ui"))
344  , m_xLabel(m_xBuilder->weld_label("label"))
345  , m_xEdit(m_xBuilder->weld_entry("entry"))
346 {
347  m_xLabel->set_grid_left_attach(0);
348  m_xLabel->set_grid_top_attach(nLine);
349 
350  m_xEdit->set_grid_left_attach(1);
351  m_xEdit->set_grid_top_attach(nLine);
352 }
353 
354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< weld::Label > m_xLabel
Definition: viewfunc.hxx:65
SCROW nEndRow
Definition: datafdlg.hxx:35
sal_Int32 nIndex
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScAddress aStart
Definition: address.hxx:500
std::unique_ptr< weld::Label > m_xFixedText
Definition: datafdlg.hxx:46
SCROW Row() const
Definition: address.hxx:262
void PostPaintGridAll()
Definition: docsh3.cxx:180
SCCOL nStartCol
Definition: datafdlg.hxx:32
std::unique_ptr< weld::Entry > m_xEdit
Definition: viewfunc.hxx:66
void SetDocumentModified()
Definition: docsh.cxx:2820
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
ScAddress aEnd
Definition: address.hxx:501
std::unique_ptr< weld::ScrolledWindow > m_xSlider
Definition: datafdlg.hxx:44
SCROW nStartRow
Definition: datafdlg.hxx:34
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
RET_CANCEL
std::unique_ptr< weld::Label > m_xLabel
std::unique_ptr< weld::Button > m_xBtnDelete
Definition: datafdlg.hxx:39
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2806
std::unique_ptr< weld::Button > m_xBtnRestore
Definition: datafdlg.hxx:40
#define MAX_DATAFORM_ROWS
Definition: datafdlg.hxx:21
IMPL_LINK(ScDataFormDlg, Impl_DataModifyHdl, weld::Entry &, rEdit, void)
Definition: datafdlg.cxx:223
SC_DLLPUBLIC OUString GetString(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScInterpreterContext *pContext=nullptr) const
Definition: document.cxx:3484
void SetButtonState()
Definition: datafdlg.cxx:319
ScViewData & GetViewData()
Definition: tabview.hxx:334
OUString sNewRecord
Definition: datafdlg.hxx:26
int i
void FillCtrls()
Definition: datafdlg.cxx:193
SCROW nCurrentRow
Definition: datafdlg.hxx:31
virtual ~ScDataFormDlg() override
Definition: datafdlg.cxx:189
std::unique_ptr< weld::Button > m_xBtnNew
Definition: datafdlg.hxx:38
virtual void Clear()
SCCOL nEndCol
Definition: datafdlg.hxx:33
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1170
#define MAX_DATAFORM_COLS
Definition: datafdlg.hxx:20
std::unique_ptr< weld::Button > m_xBtnPrev
Definition: datafdlg.hxx:41
sal_uInt16 aColLength
Definition: datafdlg.hxx:30
SCCOL Col() const
Definition: address.hxx:267
ScTabViewShell * pTabViewShell
Definition: datafdlg.hxx:28
std::unique_ptr< weld::Button > m_xBtnNext
Definition: datafdlg.hxx:42
ScDocument * pDoc
Definition: datafdlg.hxx:29
std::unique_ptr< weld::Button > m_xBtnClose
Definition: datafdlg.hxx:43
weld::Entry & rEdit
std::vector< std::unique_ptr< ScDataFormFragment > > m_aEntries
Definition: datafdlg.hxx:47
ScDataFormDlg(weld::Window *pParent, ScTabViewShell *pTabViewShell)
Definition: datafdlg.cxx:19
bool get_value_changed_from_saved() const
Reference< XExecutableDialog > m_xDialog
IMPL_LINK_NOARG(ScDataFormDlg, Impl_NewHdl, weld::Button &, void)
Definition: datafdlg.cxx:229
std::unique_ptr< weld::Container > m_xGrid
Definition: datafdlg.hxx:45
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4118
ScDataFormFragment(weld::Container *pGrid, int nLine)
Definition: datafdlg.cxx:342