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 "directsql.hxx"
21 #include "dbu_dlg.hrc"
22 #include <vcl/layout.hxx>
23 #include <comphelper/types.hxx>
24 #include <vcl/svapp.hxx>
25 #include <osl/mutex.hxx>
26 #include <tools/diagnose_ex.h>
27 #include <rtl/strbuf.hxx>
28 #include <com/sun/star/sdbc/XRow.hpp>
33 using namespace ::com::sun::star::uno
;
34 using namespace ::com::sun::star::sdbc
;
35 using namespace ::com::sun::star::lang
;
38 DirectSQLDialog::DirectSQLDialog( vcl::Window
* _pParent
, const Reference
< XConnection
>& _rxConn
)
39 :ModalDialog(_pParent
, "DirectSQLDialog" , "dbaccess/ui/directsqldialog.ui")
42 ,m_xConnection(_rxConn
)
45 Size
aSize(m_pSQL
->CalcBlockSize(60, 7));
46 m_pSQL
->set_width_request(aSize
.Width());
47 m_pSQL
->set_height_request(aSize
.Height());
48 get(m_pExecute
,"execute");
49 get(m_pSQLHistory
,"sqlhistory");
50 get(m_pStatus
,"status");
51 aSize
= m_pStatus
->CalcBlockSize(60, 5);
52 m_pStatus
->set_height_request(aSize
.Height());
53 get(m_pShowOutput
,"showoutput");
54 get(m_pOutput
,"output");
55 aSize
= m_pOutput
->CalcBlockSize(60, 5);
56 m_pOutput
->set_height_request(aSize
.Height());
57 get(m_pClose
,"close");
62 m_pExecute
->SetClickHdl(LINK(this, DirectSQLDialog
, OnExecute
));
63 m_pClose
->SetClickHdl(LINK(this, DirectSQLDialog
, OnClose
));
64 m_pSQLHistory
->SetSelectHdl(LINK(this, DirectSQLDialog
, OnListEntrySelected
));
65 m_pSQLHistory
->SetDropDownLineCount(10);
67 // add a dispose listener to the connection
68 Reference
< XComponent
> xConnComp(m_xConnection
, UNO_QUERY
);
69 OSL_ENSURE(xConnComp
.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
71 startComponentListening(xConnComp
);
73 m_pSQL
->SetModifyHdl(LINK(this, DirectSQLDialog
, OnStatementModified
));
74 OnStatementModified(m_pSQL
);
77 DirectSQLDialog::~DirectSQLDialog()
82 void DirectSQLDialog::dispose()
85 ::osl::MutexGuard
aGuard(m_aMutex
);
86 stopAllComponentListening();
90 m_pSQLHistory
.clear();
92 m_pShowOutput
.clear();
95 ModalDialog::dispose();
98 void DirectSQLDialog::_disposing( const EventObject
& _rSource
)
100 SolarMutexGuard aSolarGuard
;
101 ::osl::MutexGuard
aGuard(m_aMutex
);
103 OSL_ENSURE(Reference
< XConnection
>(_rSource
.Source
, UNO_QUERY
).get() == m_xConnection
.get(),
104 "DirectSQLDialog::_disposing: where does this come from?");
108 OUString
sMessage(ModuleRes(STR_DIRECTSQL_CONNECTIONLOST
));
109 ScopedVclPtrInstance
< MessageDialog
> aError(this, sMessage
);
113 PostUserEvent(LINK(this, DirectSQLDialog
, OnClose
), NULL
, true);
116 sal_Int32
DirectSQLDialog::getHistorySize() const
118 CHECK_INVARIANTS("DirectSQLDialog::getHistorySize");
119 return m_aStatementHistory
.size();
122 void DirectSQLDialog::implEnsureHistoryLimit()
124 CHECK_INVARIANTS("DirectSQLDialog::implEnsureHistoryLimit");
126 if (getHistorySize() <= m_nHistoryLimit
)
130 sal_Int32 nRemoveEntries
= getHistorySize() - m_nHistoryLimit
;
131 while (nRemoveEntries
--)
133 m_aStatementHistory
.pop_front();
134 m_aNormalizedHistory
.pop_front();
135 m_pSQLHistory
->RemoveEntry((sal_uInt16
)0);
139 void DirectSQLDialog::implAddToStatementHistory(const OUString
& _rStatement
)
141 CHECK_INVARIANTS("DirectSQLDialog::implAddToStatementHistory");
143 // add the statement to the history
144 m_aStatementHistory
.push_back(_rStatement
);
146 // normalize the statement, and remember the normalized form, too
147 OUString
sNormalized(_rStatement
);
148 sNormalized
= sNormalized
.replaceAll("\n", " ");
149 m_aNormalizedHistory
.push_back(sNormalized
);
151 // add the normalized version to the list box
152 m_pSQLHistory
->InsertEntry(sNormalized
);
154 // ensure that we don't exceed the history limit
155 implEnsureHistoryLimit();
159 const sal_Char
* DirectSQLDialog::impl_CheckInvariants() const
161 if (m_aStatementHistory
.size() != m_aNormalizedHistory
.size())
162 return "statement history is inconsistent!";
165 return "invalid listbox!";
167 if (m_aStatementHistory
.size() != static_cast<size_t>(m_pSQLHistory
->GetEntryCount()))
168 return "invalid listbox entry count!";
170 if (!m_xConnection
.is())
171 return "have no connection!";
177 void DirectSQLDialog::implExecuteStatement(const OUString
& _rStatement
)
179 CHECK_INVARIANTS("DirectSQLDialog::implExecuteStatement");
181 ::osl::MutexGuard
aGuard(m_aMutex
);
184 ::com::sun::star::uno::Reference
< ::com::sun::star::sdbc::XResultSet
> xResultSet
;
187 // create a statement
188 Reference
< XStatement
> xStatement
= m_xConnection
->createStatement();
189 OSL_ENSURE(xStatement
.is(), "DirectSQLDialog::implExecuteStatement: no statement returned by the connection!");
191 // clear the output box
192 m_pOutput
->SetText(OUString());
195 if (OUString(_rStatement
).toAsciiUpperCase().startsWith("SELECT") && m_pShowOutput
->IsChecked())
197 // execute it as a query
198 xResultSet
= xStatement
->executeQuery(_rStatement
);
199 // get a handle for the rows
200 ::com::sun::star::uno::Reference
< ::com::sun::star::sdbc::XRow
> xRow( xResultSet
, ::com::sun::star::uno::UNO_QUERY
);
201 // work through each of the rows
202 while (xResultSet
->next())
204 // initialise the output line for each row
206 // work along the columns until that are none left
212 // be dumb, treat everything as a string
213 out
+= xRow
->getString(i
) + ",";
217 // trap for when we fall off the end of the row
218 catch (const SQLException
&)
222 addOutputText(OUString(out
));
226 xStatement
->execute(_rStatement
);
231 sStatus
= ModuleRes(STR_COMMAND_EXECUTED_SUCCESSFULLY
);
233 // dispose the statement
234 ::comphelper::disposeComponent(xStatement
);
236 catch(const SQLException
& e
)
240 catch( const Exception
& )
242 DBG_UNHANDLED_EXCEPTION();
245 // add the status text
246 addStatusText(sStatus
);
249 void DirectSQLDialog::addStatusText(const OUString
& _rMessage
)
251 OUString sAppendMessage
= OUString::number(m_nStatusCount
++) + ": " + _rMessage
+ "\n\n";
253 OUString sCompleteMessage
= m_pStatus
->GetText() + sAppendMessage
;
254 m_pStatus
->SetText(sCompleteMessage
);
256 m_pStatus
->SetSelection(Selection(sCompleteMessage
.getLength(), sCompleteMessage
.getLength()));
259 void DirectSQLDialog::addOutputText(const OUString
& _rMessage
)
261 OUString sAppendMessage
= _rMessage
;
262 sAppendMessage
+= "\n";
264 OUString sCompleteMessage
= m_pOutput
->GetText();
265 sCompleteMessage
+= sAppendMessage
;
266 m_pOutput
->SetText(sCompleteMessage
);
269 void DirectSQLDialog::executeCurrent()
271 CHECK_INVARIANTS("DirectSQLDialog::executeCurrent");
273 OUString sStatement
= m_pSQL
->GetText();
276 implExecuteStatement(sStatement
);
278 // add the statement to the history
279 implAddToStatementHistory(sStatement
);
281 m_pSQL
->SetSelection(Selection());
285 void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos
, bool _bUpdateListBox
)
287 CHECK_INVARIANTS("DirectSQLDialog::switchToHistory");
289 if ((_nHistoryPos
>= 0) && (_nHistoryPos
< getHistorySize()))
291 // set the text in the statement editor
292 OUString sStatement
= m_aStatementHistory
[_nHistoryPos
];
293 m_pSQL
->SetText(sStatement
);
294 OnStatementModified(m_pSQL
);
298 // selecte the normalized statement in the list box
299 m_pSQLHistory
->SelectEntryPos((sal_uInt16
)_nHistoryPos
);
300 OSL_ENSURE(m_pSQLHistory
->GetSelectEntry() == m_aNormalizedHistory
[_nHistoryPos
],
301 "DirectSQLDialog::switchToHistory: inconsistent listbox entries!");
305 m_pSQL
->SetSelection(Selection(sStatement
.getLength(), sStatement
.getLength()));
308 OSL_FAIL("DirectSQLDialog::switchToHistory: invalid position!");
311 IMPL_LINK_NOARG( DirectSQLDialog
, OnStatementModified
)
313 m_pExecute
->Enable(!m_pSQL
->GetText().isEmpty());
317 IMPL_LINK_NOARG( DirectSQLDialog
, OnClose
)
323 IMPL_LINK_NOARG( DirectSQLDialog
, OnExecute
)
329 IMPL_LINK_NOARG( DirectSQLDialog
, OnListEntrySelected
)
331 if (!m_pSQLHistory
->IsTravelSelect())
333 const sal_Int32 nSelected
= m_pSQLHistory
->GetSelectEntryPos();
334 if (LISTBOX_ENTRY_NOTFOUND
!= nSelected
)
335 switchToHistory(nSelected
, false);
342 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */