Line data Source code
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 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "directsql.hxx"
22 : #include "directsql.hrc"
23 : #include "dbu_dlg.hrc"
24 : #include <vcl/msgbox.hxx>
25 : #include <comphelper/types.hxx>
26 : #include <vcl/svapp.hxx>
27 : #include <osl/mutex.hxx>
28 : #include <tools/diagnose_ex.h>
29 : #include <rtl/strbuf.hxx>
30 : #include <com/sun/star/sdbc/XRow.hpp>
31 :
32 : //........................................................................
33 : namespace dbaui
34 : {
35 : //........................................................................
36 :
37 : using namespace ::com::sun::star::uno;
38 : using namespace ::com::sun::star::sdbc;
39 : using namespace ::com::sun::star::lang;
40 :
41 :
42 : //====================================================================
43 : //= LargeEntryListBox
44 : //====================================================================
45 0 : class LargeEntryListBox : public ListBox
46 : {
47 : public:
48 : LargeEntryListBox( Window* _pParent, const ResId& _rId );
49 :
50 : protected:
51 : virtual void UserDraw( const UserDrawEvent& rUDEvt );
52 : };
53 :
54 : //--------------------------------------------------------------------
55 0 : LargeEntryListBox::LargeEntryListBox( Window* _pParent, const ResId& _rId )
56 0 : :ListBox(_pParent, _rId )
57 : {
58 0 : EnableUserDraw(sal_True);
59 0 : }
60 :
61 : //--------------------------------------------------------------------
62 0 : void LargeEntryListBox::UserDraw( const UserDrawEvent& _rUDEvt )
63 : {
64 0 : if (LISTBOX_ENTRY_NOTFOUND == _rUDEvt.GetItemId())
65 0 : ListBox::UserDraw( _rUDEvt );
66 : else
67 0 : _rUDEvt.GetDevice()->DrawText( _rUDEvt.GetRect(), GetEntry( _rUDEvt.GetItemId() ), TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS);
68 0 : }
69 :
70 : //====================================================================
71 : //= DirectSQLDialog
72 : //====================================================================
73 : DBG_NAME(DirectSQLDialog)
74 : //--------------------------------------------------------------------
75 0 : DirectSQLDialog::DirectSQLDialog( Window* _pParent, const Reference< XConnection >& _rxConn )
76 : :ModalDialog(_pParent, ModuleRes(DLG_DIRECTSQL))
77 : ,m_aFrame (this, ModuleRes(FL_SQL))
78 : ,m_aSQLLabel (this, ModuleRes(FT_SQL))
79 : ,m_aSQL (this, ModuleRes(ME_SQL))
80 : ,m_aExecute (this, ModuleRes(PB_EXECUTE))
81 : ,m_aHistoryLabel (this, ModuleRes(FT_HISTORY))
82 0 : ,m_pSQLHistory(new LargeEntryListBox(this, ModuleRes(LB_HISTORY)))
83 : ,m_aStatusFrame (this, ModuleRes(FL_STATUS))
84 : ,m_aStatus (this, ModuleRes(ME_STATUS))
85 0 : ,m_pShowOutput(new CheckBox(this, ModuleRes(CB_SHOWOUTPUT)))
86 : ,m_aOutputFrame (this, ModuleRes(FL_OUTPUT))
87 : ,m_aOutput (this, ModuleRes(ME_OUTPUT))
88 : ,m_aButtonSeparator (this, ModuleRes(FL_BUTTONS))
89 : ,m_aHelp (this, ModuleRes(PB_HELP))
90 : ,m_aClose (this, ModuleRes(PB_CLOSE))
91 : ,m_nHistoryLimit(20)
92 : ,m_nStatusCount(1)
93 0 : ,m_xConnection(_rxConn)
94 : {
95 : DBG_CTOR(DirectSQLDialog,NULL);
96 :
97 0 : FreeResource();
98 :
99 0 : m_aSQL.GrabFocus();
100 :
101 0 : m_aExecute.SetClickHdl(LINK(this, DirectSQLDialog, OnExecute));
102 0 : m_aClose.SetClickHdl(LINK(this, DirectSQLDialog, OnClose));
103 0 : m_pSQLHistory->SetSelectHdl(LINK(this, DirectSQLDialog, OnListEntrySelected));
104 0 : m_pSQLHistory->SetDropDownLineCount(10);
105 :
106 : // add a dispose listener to the connection
107 0 : Reference< XComponent > xConnComp(m_xConnection, UNO_QUERY);
108 : OSL_ENSURE(xConnComp.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
109 0 : if (xConnComp.is())
110 0 : startComponentListening(xConnComp);
111 :
112 0 : m_aSQL.SetModifyHdl(LINK(this, DirectSQLDialog, OnStatementModified));
113 0 : OnStatementModified(&m_aSQL);
114 0 : }
115 :
116 : //--------------------------------------------------------------------
117 0 : DirectSQLDialog::~DirectSQLDialog()
118 : {
119 : {
120 0 : ::osl::MutexGuard aGuard(m_aMutex);
121 0 : stopAllComponentListening();
122 : }
123 0 : delete m_pSQLHistory;
124 :
125 : DBG_DTOR(DirectSQLDialog,NULL);
126 0 : }
127 :
128 : //--------------------------------------------------------------------
129 0 : void DirectSQLDialog::_disposing( const EventObject& _rSource )
130 : {
131 0 : SolarMutexGuard aSolarGuard;
132 0 : ::osl::MutexGuard aGuard(m_aMutex);
133 :
134 : OSL_ENSURE(Reference< XConnection >(_rSource.Source, UNO_QUERY).get() == m_xConnection.get(),
135 : "DirectSQLDialog::_disposing: where does this come from?");
136 : (void)_rSource;
137 :
138 : {
139 0 : String sMessage(ModuleRes(STR_DIRECTSQL_CONNECTIONLOST));
140 0 : ErrorBox aError(this, WB_OK, sMessage);
141 0 : aError.Execute();
142 : }
143 :
144 0 : PostUserEvent(LINK(this, DirectSQLDialog, OnClose));
145 0 : }
146 :
147 : //--------------------------------------------------------------------
148 0 : sal_Int32 DirectSQLDialog::getHistorySize() const
149 : {
150 : CHECK_INVARIANTS("DirectSQLDialog::getHistorySize");
151 0 : return m_aStatementHistory.size();
152 : }
153 :
154 : //--------------------------------------------------------------------
155 0 : void DirectSQLDialog::implEnsureHistoryLimit()
156 : {
157 : CHECK_INVARIANTS("DirectSQLDialog::implEnsureHistoryLimit");
158 :
159 0 : if (getHistorySize() <= m_nHistoryLimit)
160 : // nothing to do
161 0 : return;
162 :
163 0 : sal_Int32 nRemoveEntries = getHistorySize() - m_nHistoryLimit;
164 0 : while (nRemoveEntries--)
165 : {
166 0 : m_aStatementHistory.pop_front();
167 0 : m_aNormalizedHistory.pop_front();
168 0 : m_pSQLHistory->RemoveEntry((sal_uInt16)0);
169 : }
170 : }
171 :
172 : //--------------------------------------------------------------------
173 0 : void DirectSQLDialog::implAddToStatementHistory(const String& _rStatement)
174 : {
175 : CHECK_INVARIANTS("DirectSQLDialog::implAddToStatementHistory");
176 :
177 : // add the statement to the history
178 0 : m_aStatementHistory.push_back(_rStatement);
179 :
180 : // normalize the statement, and remember the normalized form, too
181 0 : String sNormalized(_rStatement);
182 0 : sNormalized.SearchAndReplaceAll((sal_Unicode)'\n', ' ');
183 0 : m_aNormalizedHistory.push_back(sNormalized);
184 :
185 : // add the normalized version to the list box
186 0 : m_pSQLHistory->InsertEntry(sNormalized);
187 :
188 : // ensure that we don't exceed the history limit
189 0 : implEnsureHistoryLimit();
190 0 : }
191 :
192 : #ifdef DBG_UTIL
193 : //--------------------------------------------------------------------
194 : const sal_Char* DirectSQLDialog::impl_CheckInvariants() const
195 : {
196 : if (m_aStatementHistory.size() != m_aNormalizedHistory.size())
197 : return "statement history is inconsistent!";
198 :
199 : if (!m_pSQLHistory)
200 : return "invalid listbox!";
201 :
202 : if (m_aStatementHistory.size() != m_pSQLHistory->GetEntryCount())
203 : return "invalid listbox entry count!";
204 :
205 : if (!m_xConnection.is())
206 : return "have no connection!";
207 :
208 : return NULL;
209 : }
210 : #endif
211 :
212 : //--------------------------------------------------------------------
213 0 : void DirectSQLDialog::implExecuteStatement(const String& _rStatement)
214 : {
215 : CHECK_INVARIANTS("DirectSQLDialog::implExecuteStatement");
216 :
217 0 : ::osl::MutexGuard aGuard(m_aMutex);
218 :
219 0 : String sStatus;
220 0 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet > xResultSet;
221 : try
222 : {
223 : // create a statement
224 0 : Reference< XStatement > xStatement = m_xConnection->createStatement();
225 : OSL_ENSURE(xStatement.is(), "DirectSQLDialog::implExecuteStatement: no statement returned by the connection!");
226 :
227 : // clear the output box
228 0 : m_aOutput.SetText(OUString());
229 0 : if (xStatement.is())
230 : {
231 0 : if (OUString(_rStatement).toAsciiUpperCase().startsWith("SELECT") && m_pShowOutput->IsChecked())
232 : {
233 : // execute it as a query
234 0 : xResultSet = xStatement->executeQuery(_rStatement);
235 : // get a handle for the rows
236 0 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > xRow( xResultSet, ::com::sun::star::uno::UNO_QUERY );
237 : // work through each of the rows
238 0 : while (xResultSet->next())
239 : {
240 : // initialise the output line for each row
241 0 : String out = OUString("");
242 : // work along the columns until that are none left
243 : try
244 : {
245 0 : int i = 1;
246 : for (;;)
247 : {
248 : // be dumb, treat everything as a string
249 0 : out += xRow->getString(i) + OUString(",");
250 0 : i++;
251 0 : }
252 : }
253 : // trap for when we fall off the end of the row
254 0 : catch (const SQLException&)
255 : {
256 : }
257 : // report the output
258 0 : addOutputText(OUString(out));
259 0 : }
260 : } else {
261 : // execute it
262 0 : xStatement->execute(_rStatement);
263 : }
264 : }
265 :
266 : // successful
267 0 : sStatus = String(ModuleRes(STR_COMMAND_EXECUTED_SUCCESSFULLY));
268 :
269 : // dispose the statement
270 0 : ::comphelper::disposeComponent(xStatement);
271 : }
272 0 : catch(const SQLException& e)
273 : {
274 0 : sStatus = e.Message;
275 : }
276 0 : catch( const Exception& )
277 : {
278 : DBG_UNHANDLED_EXCEPTION();
279 : }
280 :
281 : // add the status text
282 0 : addStatusText(sStatus);
283 0 : }
284 :
285 : //--------------------------------------------------------------------
286 0 : void DirectSQLDialog::addStatusText(const String& _rMessage)
287 : {
288 0 : OUString sAppendMessage = OUString::number(m_nStatusCount++) + ": " + _rMessage + "\n\n";
289 :
290 0 : OUString sCompleteMessage = m_aStatus.GetText() + sAppendMessage;
291 0 : m_aStatus.SetText(sCompleteMessage);
292 :
293 0 : m_aStatus.SetSelection(Selection(sCompleteMessage.getLength(), sCompleteMessage.getLength()));
294 0 : }
295 :
296 : //--------------------------------------------------------------------
297 0 : void DirectSQLDialog::addOutputText(const String& _rMessage)
298 : {
299 0 : String sAppendMessage = _rMessage;
300 0 : sAppendMessage += OUString("\n");
301 :
302 0 : String sCompleteMessage = m_aOutput.GetText();
303 0 : sCompleteMessage += sAppendMessage;
304 0 : m_aOutput.SetText(sCompleteMessage);
305 0 : }
306 :
307 : //--------------------------------------------------------------------
308 0 : void DirectSQLDialog::executeCurrent()
309 : {
310 : CHECK_INVARIANTS("DirectSQLDialog::executeCurrent");
311 :
312 0 : String sStatement = m_aSQL.GetText();
313 :
314 : // execute
315 0 : implExecuteStatement(sStatement);
316 :
317 : // add the statement to the history
318 0 : implAddToStatementHistory(sStatement);
319 :
320 0 : m_aSQL.SetSelection(Selection());
321 0 : m_aSQL.GrabFocus();
322 0 : }
323 :
324 : //--------------------------------------------------------------------
325 0 : void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos, sal_Bool _bUpdateListBox)
326 : {
327 : CHECK_INVARIANTS("DirectSQLDialog::switchToHistory");
328 :
329 0 : if ((_nHistoryPos >= 0) && (_nHistoryPos < getHistorySize()))
330 : {
331 : // set the text in the statement editor
332 0 : String sStatement = m_aStatementHistory[_nHistoryPos];
333 0 : m_aSQL.SetText(sStatement);
334 0 : OnStatementModified(&m_aSQL);
335 :
336 0 : if (_bUpdateListBox)
337 : {
338 : // selecte the normalized statement in the list box
339 0 : m_pSQLHistory->SelectEntryPos((sal_uInt16)_nHistoryPos);
340 : OSL_ENSURE(m_pSQLHistory->GetSelectEntry() == m_aNormalizedHistory[_nHistoryPos],
341 : "DirectSQLDialog::switchToHistory: inconsistent listbox entries!");
342 : }
343 :
344 0 : m_aSQL.GrabFocus();
345 0 : m_aSQL.SetSelection(Selection(sStatement.Len(), sStatement.Len()));
346 : }
347 : else
348 : OSL_FAIL("DirectSQLDialog::switchToHistory: invalid position!");
349 0 : }
350 :
351 : //--------------------------------------------------------------------
352 0 : IMPL_LINK( DirectSQLDialog, OnStatementModified, void*, /*NOTINTERESTEDIN*/ )
353 : {
354 0 : m_aExecute.Enable(!m_aSQL.GetText().isEmpty());
355 0 : return 0L;
356 : }
357 :
358 : //--------------------------------------------------------------------
359 0 : IMPL_LINK( DirectSQLDialog, OnClose, void*, /*NOTINTERESTEDIN*/ )
360 : {
361 0 : EndDialog( RET_OK );
362 0 : return 0L;
363 : }
364 :
365 : //--------------------------------------------------------------------
366 0 : IMPL_LINK( DirectSQLDialog, OnExecute, void*, /*NOTINTERESTEDIN*/ )
367 : {
368 0 : executeCurrent();
369 0 : return 0L;
370 : }
371 :
372 : //--------------------------------------------------------------------
373 0 : IMPL_LINK( DirectSQLDialog, OnListEntrySelected, void*, /*NOTINTERESTEDIN*/ )
374 : {
375 0 : if (!m_pSQLHistory->IsTravelSelect())
376 : {
377 0 : const sal_uInt16 nSelected = m_pSQLHistory->GetSelectEntryPos();
378 0 : if (LISTBOX_ENTRY_NOTFOUND != nSelected)
379 0 : switchToHistory(nSelected, sal_False);
380 : }
381 0 : return 0L;
382 : }
383 :
384 : //........................................................................
385 12 : } // namespace dbaui
386 : //........................................................................
387 :
388 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|