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