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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 #include <com/sun/star/sdb/DatabaseContext.hpp>
24 #include <com/sun/star/sdb/CommandType.hpp>
25 #include <comphelper/processfactory.hxx>
26 #include <comphelper/sequence.hxx>
27 #include <sfx2/viewfrm.hxx>
28 #include <o3tl/string_view.hxx>
33 #include <changedb.hxx>
35 #include <strings.hrc>
36 #include <bitmaps.hlst>
38 using namespace ::com::sun::star::container
;
39 using namespace ::com::sun::star::lang
;
40 using namespace ::com::sun::star::sdb
;
41 using namespace ::com::sun::star::uno
;
44 SwChangeDBDlg::SwChangeDBDlg(SwView
const & rVw
)
45 : SfxDialogController(rVw
.GetViewFrame().GetFrameWeld(), "modules/swriter/ui/exchangedatabases.ui",
46 "ExchangeDatabasesDialog")
47 , m_pSh(rVw
.GetWrtShellPtr())
48 , m_xUsedDBTLB(m_xBuilder
->weld_tree_view("inuselb"))
49 , m_xAvailDBTLB(new SwDBTreeList(m_xBuilder
->weld_tree_view("availablelb")))
50 , m_xAddDBPB(m_xBuilder
->weld_button("browse"))
51 , m_xDocDBNameFT(m_xBuilder
->weld_label("dbnameft"))
52 , m_xDefineBT(m_xBuilder
->weld_button("ok"))
54 int nWidth
= m_xUsedDBTLB
->get_approximate_digit_width() * 25;
55 int nHeight
= m_xUsedDBTLB
->get_height_rows(8);
56 m_xUsedDBTLB
->set_size_request(nWidth
, nHeight
);
57 m_xAvailDBTLB
->set_size_request(nWidth
, nHeight
);
59 m_xAvailDBTLB
->SetWrtShell(*m_pSh
);
62 ShowDBName(m_pSh
->GetDBData());
63 m_xDefineBT
->connect_clicked(LINK(this, SwChangeDBDlg
, ButtonHdl
));
64 m_xAddDBPB
->connect_clicked(LINK(this, SwChangeDBDlg
, AddDBHdl
));
66 m_xUsedDBTLB
->set_selection_mode(SelectionMode::Multiple
);
67 m_xUsedDBTLB
->make_sorted();
69 Link
<weld::TreeView
&,void> aLink
= LINK(this, SwChangeDBDlg
, TreeSelectHdl
);
71 m_xUsedDBTLB
->connect_changed(aLink
);
72 m_xAvailDBTLB
->connect_changed(aLink
);
76 // initialise database listboxes
77 void SwChangeDBDlg::FillDBPopup()
79 Reference
< XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
80 Reference
<XDatabaseContext
> xDBContext
= DatabaseContext::create(xContext
);
81 const SwDBData
& rDBData
= m_pSh
->GetDBData();
82 m_xAvailDBTLB
->Select(rDBData
.sDataSource
, rDBData
.sCommand
, u
"");
85 Sequence
< OUString
> aDBNames
= xDBContext
->getElementNames();
86 auto aAllDBNames
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(aDBNames
);
88 std::vector
<OUString
> aDBNameList
;
89 m_pSh
->GetAllUsedDB( aDBNameList
, &aAllDBNames
);
91 size_t nCount
= aDBNameList
.size();
92 m_xUsedDBTLB
->clear();
93 std::unique_ptr
<weld::TreeIter
> xFirst
;
95 for(size_t k
= 0; k
< nCount
; k
++)
97 std::unique_ptr
<weld::TreeIter
> xLast
= Insert(o3tl::getToken(aDBNameList
[k
], 0, ';'));
99 xFirst
= std::move(xLast
);
104 m_xUsedDBTLB
->expand_row(*xFirst
);
105 m_xUsedDBTLB
->scroll_to_row(*xFirst
);
106 m_xUsedDBTLB
->select(*xFirst
);
110 std::unique_ptr
<weld::TreeIter
> SwChangeDBDlg::Insert(std::u16string_view rDBName
)
113 const OUString
sDBName(o3tl::getToken(rDBName
, 0, DB_DELIM
, nIdx
));
114 const OUString
sTableName(o3tl::getToken(rDBName
, 0, DB_DELIM
, nIdx
));
115 OUString
sUserData( o3tl::getToken(rDBName
, 0, DB_DELIM
, nIdx
) );
116 sal_Int32 nCommandType
= sUserData
.toInt32();
118 const OUString
& rToInsert ( nCommandType
? RID_BMP_DBQUERY
: RID_BMP_DBTABLE
);
120 std::unique_ptr
<weld::TreeIter
> xIter(m_xUsedDBTLB
->make_iterator());
121 if (m_xUsedDBTLB
->get_iter_first(*xIter
))
125 if (sDBName
== m_xUsedDBTLB
->get_text(*xIter
))
127 if (m_xUsedDBTLB
->iter_has_child(*xIter
))
129 std::unique_ptr
<weld::TreeIter
> xChild(m_xUsedDBTLB
->make_iterator(xIter
.get()));
130 if (m_xUsedDBTLB
->iter_children(*xChild
))
134 if (sTableName
== m_xUsedDBTLB
->get_text(*xChild
))
136 } while (m_xUsedDBTLB
->iter_next_sibling(*xChild
));
139 m_xUsedDBTLB
->insert(xIter
.get(), -1, &sTableName
, &sUserData
, nullptr, nullptr,
141 m_xUsedDBTLB
->set_image(*xIter
, rToInsert
);
144 } while (m_xUsedDBTLB
->iter_next_sibling(*xIter
));
147 m_xUsedDBTLB
->insert(nullptr, -1, &sDBName
, nullptr, nullptr, nullptr,
149 m_xUsedDBTLB
->set_image(*xIter
, RID_BMP_DB
);
150 m_xUsedDBTLB
->insert(xIter
.get(), -1, &sTableName
, &sUserData
, nullptr, nullptr,
152 m_xUsedDBTLB
->set_image(*xIter
, rToInsert
);
157 SwChangeDBDlg::~SwChangeDBDlg()
161 short SwChangeDBDlg::run()
163 short nRet
= SfxDialogController::run();
169 void SwChangeDBDlg::UpdateFields()
171 std::vector
<OUString
> aDBNames
;
173 m_xUsedDBTLB
->selected_foreach([this, &aDBNames
](weld::TreeIter
& rEntry
){
174 if (m_xUsedDBTLB
->get_iter_depth(rEntry
))
176 std::unique_ptr
<weld::TreeIter
> xIter(m_xUsedDBTLB
->make_iterator(&rEntry
));
177 m_xUsedDBTLB
->iter_parent(*xIter
);
178 OUString
sTmp(m_xUsedDBTLB
->get_text(*xIter
) +
179 OUStringChar(DB_DELIM
) + m_xUsedDBTLB
->get_text(rEntry
) + OUStringChar(DB_DELIM
) +
180 m_xUsedDBTLB
->get_id(rEntry
));
181 aDBNames
.push_back(sTmp
);
186 m_pSh
->StartAllAction();
188 OUString sColumnName
;
189 sal_Bool bIsTable
= false;
190 const OUString
DBName(m_xAvailDBTLB
->GetDBName(sTableName
, sColumnName
, &bIsTable
));
191 const OUString sTemp
= DBName
192 + OUStringChar(DB_DELIM
)
194 + OUStringChar(DB_DELIM
)
195 + OUString::number(bIsTable
197 : CommandType::QUERY
);
198 m_pSh
->ChangeDBFields( aDBNames
, sTemp
);
199 m_pSh
->EndAllAction();
202 IMPL_LINK_NOARG(SwChangeDBDlg
, ButtonHdl
, weld::Button
&, void)
205 OUString sColumnName
;
207 sal_Bool bIsTable
= false;
208 aData
.sDataSource
= m_xAvailDBTLB
->GetDBName(sTableName
, sColumnName
, &bIsTable
);
209 aData
.sCommand
= sTableName
;
210 aData
.nCommandType
= bIsTable
? 0 : 1;
211 m_pSh
->ChgDBData(aData
);
212 ShowDBName(m_pSh
->GetDBData());
213 m_xDialog
->response(RET_OK
);
216 IMPL_LINK_NOARG(SwChangeDBDlg
, TreeSelectHdl
, weld::TreeView
&, void)
221 void SwChangeDBDlg::TreeSelect()
223 bool bEnable
= false;
224 std::unique_ptr
<weld::TreeIter
> xIter(m_xAvailDBTLB
->make_iterator());
225 if (m_xAvailDBTLB
->get_selected(xIter
.get()))
227 if (m_xAvailDBTLB
->get_iter_depth(*xIter
))
230 m_xDefineBT
->set_sensitive(bEnable
);
234 // convert database name for display
235 void SwChangeDBDlg::ShowDBName(const SwDBData
& rDBData
)
237 if (rDBData
.sDataSource
.isEmpty() && rDBData
.sCommand
.isEmpty())
239 m_xDocDBNameFT
->set_label(SwResId(SW_STR_NONE
));
243 const OUString
sName(rDBData
.sDataSource
+ "." + rDBData
.sCommand
);
244 m_xDocDBNameFT
->set_label(sName
.replaceAll("~", "~~"));
248 IMPL_LINK_NOARG(SwChangeDBDlg
, AddDBHdl
, weld::Button
&, void)
250 const OUString sNewDB
= SwDBManager::LoadAndRegisterDataSource(m_xDialog
.get());
251 if (!sNewDB
.isEmpty())
253 m_xAvailDBTLB
->AddDataSource(sNewDB
);
258 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */