1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #undef SC_DLLIMPLEMENTATION
12 #include <datafdlg.hxx>
13 #include <viewdata.hxx>
15 #include <tabvwsh.hxx>
17 #include <vcl/svapp.hxx>
18 #include <osl/diagnose.h>
20 ScDataFormDlg::ScDataFormDlg(weld::Window
* pParent
, ScTabViewShell
* pTabViewShellOri
)
21 : GenericDialogController(pParent
, u
"modules/scalc/ui/dataform.ui"_ustr
, u
"DataFormDialog"_ustr
)
22 , pTabViewShell(pTabViewShellOri
)
30 , m_xBtnNew(m_xBuilder
->weld_button(u
"new"_ustr
))
31 , m_xBtnDelete(m_xBuilder
->weld_button(u
"delete"_ustr
))
32 , m_xBtnRestore(m_xBuilder
->weld_button(u
"restore"_ustr
))
33 , m_xBtnPrev(m_xBuilder
->weld_button(u
"prev"_ustr
))
34 , m_xBtnNext(m_xBuilder
->weld_button(u
"next"_ustr
))
35 , m_xBtnClose(m_xBuilder
->weld_button(u
"close"_ustr
))
36 , m_xSlider(m_xBuilder
->weld_scrolled_window(u
"scrollbar"_ustr
, true))
37 , m_xGrid(m_xBuilder
->weld_container(u
"grid"_ustr
))
38 , m_xFixedText(m_xBuilder
->weld_label(u
"label"_ustr
))
40 sNewRecord
= m_xFixedText
->get_label();
42 //read header from current document, and add new controls
43 OSL_ENSURE( pTabViewShell
, "pTabViewShell is NULL! :-/" );
44 ScViewData
& rViewData
= pTabViewShell
->GetViewData();
46 pDoc
= &rViewData
.GetDocument();
50 rViewData
.GetSimpleArea( aRange
);
51 ScAddress aStart
= aRange
.aStart
;
52 ScAddress aEnd
= aRange
.aEnd
;
54 nStartCol
= aStart
.Col();
56 nStartRow
= aStart
.Row();
59 nTab
= rViewData
.GetTabNo();
60 bool bNoSelection(false);
61 //if there is no selection
62 if ((nStartCol
== nEndCol
) && (nStartRow
== nEndRow
))
67 //find last not blank cell in row
68 for (int i
=1;i
<=MAX_DATAFORM_COLS
;i
++)
71 OUString aColName
= pDoc
->GetString(nEndCol
, nStartRow
, nTab
);
72 int nColWidth
= pDoc
->GetColWidth( nEndCol
, nTab
);
73 if (aColName
.isEmpty() && nColWidth
)
80 //find first not blank cell in row
81 for (int i
=1;i
<=MAX_DATAFORM_COLS
;i
++)
87 OUString aColName
= pDoc
->GetString(nStartCol
, nStartRow
, nTab
);
88 int nColWidth
= pDoc
->GetColWidth( nEndCol
, nTab
);
89 if (aColName
.isEmpty() && nColWidth
)
96 //skip leading hide column
97 for (int i
=1;i
<=MAX_DATAFORM_COLS
;i
++)
99 int nColWidth
= pDoc
->GetColWidth( nStartCol
, nTab
);
105 if (nEndCol
< nStartCol
)
108 //find last not blank cell in row
109 for (int i
=1;i
<=MAX_DATAFORM_ROWS
;i
++)
112 OUString aColName
= pDoc
->GetString(nStartCol
, nEndRow
, nTab
);
113 if (aColName
.isEmpty())
120 //find first not blank cell in row
121 for (int i
=1;i
<=MAX_DATAFORM_ROWS
;i
++)
127 OUString aColName
= pDoc
->GetString(nStartCol
, nStartRow
, nTab
);
128 if (aColName
.isEmpty())
135 if (nEndRow
< nStartRow
)
139 nCurrentRow
= nStartRow
+ 1;
141 aColLength
= nEndCol
- nStartCol
+ 1;
144 m_aEntries
.reserve(aColLength
);
146 sal_Int32 nGridRow
= 0;
147 for(sal_uInt16 nIndex
= 0; nIndex
< aColLength
; ++nIndex
)
149 OUString aFieldName
= pDoc
->GetString(nIndex
+ nStartCol
, nStartRow
, nTab
);
150 int nColWidth
= pDoc
->GetColWidth( nIndex
+ nStartCol
, nTab
);
153 m_aEntries
.emplace_back(new ScDataFormFragment(m_xGrid
.get(), nGridRow
));
157 m_aEntries
[nIndex
]->m_xLabel
->set_label(aFieldName
);
158 m_aEntries
[nIndex
]->m_xLabel
->show();
159 m_aEntries
[nIndex
]->m_xEdit
->show();
163 m_aEntries
.emplace_back(nullptr );
165 if (m_aEntries
[nIndex
] != nullptr)
167 m_aEntries
[nIndex
]->m_xEdit
->connect_changed(LINK( this, ScDataFormDlg
, Impl_DataModifyHdl
));
168 m_aEntries
[nIndex
]->m_xEdit
->save_value();
175 m_xSlider
->vadjustment_configure(0, 0, nEndRow
- nStartRow
+ 1, 1, 10, 1);
177 m_xBtnNew
->connect_clicked(LINK( this, ScDataFormDlg
, Impl_NewHdl
));
178 m_xBtnPrev
->connect_clicked(LINK( this, ScDataFormDlg
, Impl_PrevHdl
));
179 m_xBtnNext
->connect_clicked(LINK( this, ScDataFormDlg
, Impl_NextHdl
));
181 m_xBtnRestore
->connect_clicked(LINK( this, ScDataFormDlg
, Impl_RestoreHdl
));
182 m_xBtnDelete
->connect_clicked(LINK( this, ScDataFormDlg
, Impl_DeleteHdl
));
183 m_xBtnClose
->connect_clicked(LINK( this, ScDataFormDlg
, Impl_CloseHdl
));
185 m_xSlider
->connect_vadjustment_changed(LINK( this, ScDataFormDlg
, Impl_ScrollHdl
));
190 ScDataFormDlg::~ScDataFormDlg()
194 void ScDataFormDlg::FillCtrls()
196 for (sal_uInt16 i
= 0; i
< aColLength
; ++i
)
200 if (nCurrentRow
<=nEndRow
&& pDoc
)
202 OUString
aFieldName(pDoc
->GetString(i
+ nStartCol
, nCurrentRow
, nTab
));
203 m_aEntries
[i
]->m_xEdit
->set_text(aFieldName
);
206 m_aEntries
[i
]->m_xEdit
->set_text(OUString());
210 if (nCurrentRow
<= nEndRow
)
213 OUString::number(static_cast<sal_Int32
>(nCurrentRow
- nStartRow
)) +
215 OUString::number(static_cast<sal_Int32
>(nEndRow
- nStartRow
));
216 m_xFixedText
->set_label(sLabel
);
219 m_xFixedText
->set_label(sNewRecord
);
221 m_xSlider
->vadjustment_set_value(nCurrentRow
-nStartRow
-1);
224 IMPL_LINK( ScDataFormDlg
, Impl_DataModifyHdl
, weld::Entry
&, rEdit
, void)
226 if (rEdit
.get_value_changed_from_saved())
227 m_xBtnRestore
->set_sensitive(true);
230 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_NewHdl
, weld::Button
&, void)
232 ScViewData
& rViewData
= pTabViewShell
->GetViewData();
233 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
237 bool bHasData
= std::any_of(m_aEntries
.begin(), m_aEntries
.end(),
238 [](const std::unique_ptr
<ScDataFormFragment
>& rElem
) { return (rElem
!= nullptr) && (!rElem
->m_xEdit
->get_text().isEmpty()); });
243 pTabViewShell
->DataFormPutData(nCurrentRow
, nStartRow
, nStartCol
, nEndRow
, nEndCol
, m_aEntries
, aColLength
);
245 if (nCurrentRow
>= nEndRow
+ 2)
248 m_xSlider
->vadjustment_set_upper(nEndRow
- nStartRow
+ 1);
252 pDocSh
->SetDocumentModified();
253 pDocSh
->PostPaintGridAll();
256 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_PrevHdl
, weld::Button
&, void)
260 if ( nCurrentRow
> nStartRow
+1 )
268 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_NextHdl
, weld::Button
&, void)
272 if ( nCurrentRow
<= nEndRow
)
280 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_RestoreHdl
, weld::Button
&, void)
288 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_DeleteHdl
, weld::Button
&, void)
290 ScViewData
& rViewData
= pTabViewShell
->GetViewData();
291 ScDocShell
* pDocSh
= rViewData
.GetDocShell();
295 ScRange
aRange(nStartCol
, nCurrentRow
, nTab
, nEndCol
, nCurrentRow
, nTab
);
296 pDoc
->DeleteRow(aRange
);
300 pDocSh
->GetUndoManager()->Clear();
303 pDocSh
->SetDocumentModified();
304 pDocSh
->PostPaintGridAll();
307 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_CloseHdl
, weld::Button
&, void)
309 m_xDialog
->response(RET_CANCEL
);
312 IMPL_LINK_NOARG(ScDataFormDlg
, Impl_ScrollHdl
, weld::ScrolledWindow
&, void)
314 auto nOffset
= m_xSlider
->vadjustment_get_value();
315 nCurrentRow
= nStartRow
+ nOffset
+ 1;
320 void ScDataFormDlg::SetButtonState()
322 if (nCurrentRow
> nEndRow
)
324 m_xBtnDelete
->set_sensitive( false );
325 m_xBtnNext
->set_sensitive( false );
329 m_xBtnDelete
->set_sensitive(true);
330 m_xBtnNext
->set_sensitive(true);
333 if (nCurrentRow
== nStartRow
+ 1)
334 m_xBtnPrev
->set_sensitive( false );
336 m_xBtnPrev
->set_sensitive(true);
338 m_xBtnRestore
->set_sensitive( false );
339 if (!m_aEntries
.empty() && m_aEntries
[0] != nullptr)
340 m_aEntries
[0]->m_xEdit
->grab_focus();
343 ScDataFormFragment::ScDataFormFragment(weld::Container
* pGrid
, int nLine
)
344 : m_xBuilder(Application::CreateBuilder(pGrid
, u
"modules/scalc/ui/dataformfragment.ui"_ustr
))
345 , m_xLabel(m_xBuilder
->weld_label(u
"label"_ustr
))
346 , m_xEdit(m_xBuilder
->weld_entry(u
"entry"_ustr
))
348 m_xLabel
->set_grid_left_attach(0);
349 m_xLabel
->set_grid_top_attach(nLine
);
351 m_xEdit
->set_grid_left_attach(1);
352 m_xEdit
->set_grid_top_attach(nLine
);
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */