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