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