xref: /trunk/main/dbaccess/source/ui/dlg/directsql.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #ifndef _DBACCESS_UI_DIRECTSQL_HXX_
32 #include "directsql.hxx"
33 #endif
34 #ifndef _DBACCESS_UI_DIRECTSQL_HRC_
35 #include "directsql.hrc"
36 #endif
37 #ifndef _DBU_DLG_HRC_
38 #include "dbu_dlg.hrc"
39 #endif
40 #ifndef _SV_MSGBOX_HXX
41 #include <vcl/msgbox.hxx>
42 #endif
43 #ifndef _COMPHELPER_TYPES_HXX_
44 #include <comphelper/types.hxx>
45 #endif
46 #ifndef _SV_MSGBOX_HXX
47 #include <vcl/msgbox.hxx>
48 #endif
49 #ifndef _SV_SVAPP_HXX
50 #include <vcl/svapp.hxx>
51 #endif
52 #ifndef _VOS_MUTEX_HXX_
53 #include <vos/mutex.hxx>
54 #endif
55 #ifndef TOOLS_DIAGNOSE_EX_H
56 #include <tools/diagnose_ex.h>
57 #endif
58 
59 //........................................................................
60 namespace dbaui
61 {
62 //........................................................................
63 
64 	using namespace ::com::sun::star::uno;
65 	using namespace ::com::sun::star::sdbc;
66 	using namespace ::com::sun::star::lang;
67 
68 	//====================================================================
69 	//= LargeEntryListBox
70 	//====================================================================
71 	class LargeEntryListBox : public ListBox
72 	{
73 	public:
74 		LargeEntryListBox( Window* _pParent, const ResId& _rId );
75 
76 	protected:
77 		virtual void	UserDraw( const UserDrawEvent& rUDEvt );
78 	};
79 
80 	//--------------------------------------------------------------------
81 	LargeEntryListBox::LargeEntryListBox( Window* _pParent, const ResId& _rId )
82 		:ListBox(_pParent, _rId )
83 	{
84 		EnableUserDraw(sal_True);
85 	}
86 
87 	//--------------------------------------------------------------------
88 	void LargeEntryListBox::UserDraw( const UserDrawEvent& _rUDEvt )
89 	{
90 		if (LISTBOX_ENTRY_NOTFOUND == _rUDEvt.GetItemId())
91 			ListBox::UserDraw( _rUDEvt );
92 		else
93 			_rUDEvt.GetDevice()->DrawText( _rUDEvt.GetRect(), GetEntry( _rUDEvt.GetItemId() ), TEXT_DRAW_LEFT | TEXT_DRAW_VCENTER | TEXT_DRAW_ENDELLIPSIS);
94 	}
95 
96 	//====================================================================
97 	//= DirectSQLDialog
98 	//====================================================================
99 DBG_NAME(DirectSQLDialog)
100 //--------------------------------------------------------------------
101 	DirectSQLDialog::DirectSQLDialog( Window* _pParent, const Reference< XConnection >& _rxConn )
102 		:ModalDialog(_pParent, ModuleRes(DLG_DIRECTSQL))
103 		,m_aFrame				(this, ModuleRes(FL_SQL))
104 		,m_aSQLLabel			(this, ModuleRes(FT_SQL))
105 		,m_aSQL					(this, ModuleRes(ME_SQL))
106 		,m_aExecute				(this, ModuleRes(PB_EXECUTE))
107 		,m_aHistoryLabel		(this, ModuleRes(FT_HISTORY))
108 		,m_pSQLHistory(new LargeEntryListBox(this, ModuleRes(LB_HISTORY)))
109 		,m_aStatusFrame			(this, ModuleRes(FL_STATUS))
110 		,m_aStatus				(this, ModuleRes(ME_STATUS))
111 		,m_aButtonSeparator		(this, ModuleRes(FL_BUTTONS))
112 		,m_aHelp				(this, ModuleRes(PB_HELP))
113 		,m_aClose				(this, ModuleRes(PB_CLOSE))
114 		,m_nHistoryLimit(20)
115 		,m_nStatusCount(1)
116 		,m_xConnection(_rxConn)
117 	{
118         DBG_CTOR(DirectSQLDialog,NULL);
119 
120 		FreeResource();
121 
122 		m_aSQL.GrabFocus();
123 
124 		m_aExecute.SetClickHdl(LINK(this, DirectSQLDialog, OnExecute));
125 		m_aClose.SetClickHdl(LINK(this, DirectSQLDialog, OnClose));
126 		m_pSQLHistory->SetSelectHdl(LINK(this, DirectSQLDialog, OnListEntrySelected));
127 		m_pSQLHistory->SetDropDownLineCount(10);
128 
129 		// add a dispose listener to the connection
130 		Reference< XComponent > xConnComp(m_xConnection, UNO_QUERY);
131 		OSL_ENSURE(xConnComp.is(), "DirectSQLDialog::DirectSQLDialog: invalid connection!");
132 		if (xConnComp.is())
133 			startComponentListening(xConnComp);
134 
135 		m_aSQL.SetModifyHdl(LINK(this, DirectSQLDialog, OnStatementModified));
136 		OnStatementModified(&m_aSQL);
137 	}
138 
139 	//--------------------------------------------------------------------
140 	DirectSQLDialog::~DirectSQLDialog()
141 	{
142 		{
143 			::osl::MutexGuard aGuard(m_aMutex);
144 			stopAllComponentListening();
145 		}
146 		delete m_pSQLHistory;
147 
148         DBG_DTOR(DirectSQLDialog,NULL);
149     }
150 
151 	//--------------------------------------------------------------------
152 	void DirectSQLDialog::_disposing( const EventObject& _rSource )
153 	{
154 		::vos::OGuard aSolarGuard(Application::GetSolarMutex());
155 		::osl::MutexGuard aGuard(m_aMutex);
156 
157 		OSL_ENSURE(Reference< XConnection >(_rSource.Source, UNO_QUERY).get() == m_xConnection.get(),
158 			"DirectSQLDialog::_disposing: where does this come from?");
159         (void)_rSource;
160 
161 		{
162 			String sMessage(ModuleRes(STR_DIRECTSQL_CONNECTIONLOST));
163 			ErrorBox aError(this, WB_OK, sMessage);
164 			aError.Execute();
165 		}
166 
167 		PostUserEvent(LINK(this, DirectSQLDialog, OnClose));
168 	}
169 
170 	//--------------------------------------------------------------------
171 	sal_Int32 DirectSQLDialog::getHistorySize() const
172 	{
173 		CHECK_INVARIANTS("DirectSQLDialog::getHistorySize");
174 		return m_aStatementHistory.size();
175 	}
176 
177 	//--------------------------------------------------------------------
178 	void DirectSQLDialog::implEnsureHistoryLimit()
179 	{
180 		CHECK_INVARIANTS("DirectSQLDialog::implEnsureHistoryLimit");
181 
182 		if (getHistorySize() <= m_nHistoryLimit)
183 			// nothing to do
184 			return;
185 
186 		sal_Int32 nRemoveEntries = getHistorySize() - m_nHistoryLimit;
187 		while (nRemoveEntries--)
188 		{
189 			m_aStatementHistory.pop_front();
190 			m_aNormalizedHistory.pop_front();
191 			m_pSQLHistory->RemoveEntry((sal_uInt16)0);
192 		}
193 	}
194 
195 	//--------------------------------------------------------------------
196 	void DirectSQLDialog::implAddToStatementHistory(const String& _rStatement)
197 	{
198 		CHECK_INVARIANTS("DirectSQLDialog::implAddToStatementHistory");
199 
200 		// add the statement to the history
201 		m_aStatementHistory.push_back(_rStatement);
202 
203 		// normalize the statement, and remember the normalized form, too
204 		String sNormalized(_rStatement);
205 		sNormalized.SearchAndReplaceAll((sal_Unicode)'\n', ' ');
206 		m_aNormalizedHistory.push_back(sNormalized);
207 
208 		// add the normalized version to the list box
209 		m_pSQLHistory->InsertEntry(sNormalized);
210 
211 		// ensure that we don't exceed the history limit
212 		implEnsureHistoryLimit();
213 	}
214 
215 #ifdef DBG_UTIL
216 	//--------------------------------------------------------------------
217 	const sal_Char* DirectSQLDialog::impl_CheckInvariants() const
218 	{
219 		if (m_aStatementHistory.size() != m_aNormalizedHistory.size())
220 			return "statement history is inconsistent!";
221 
222 		if (!m_pSQLHistory)
223 			return "invalid listbox!";
224 
225 		if (m_aStatementHistory.size() != m_pSQLHistory->GetEntryCount())
226 			return "invalid listbox entry count!";
227 
228 		if (!m_xConnection.is())
229 			return "have no connection!";
230 
231 		return NULL;
232 	}
233 #endif
234 
235 	//--------------------------------------------------------------------
236 	void DirectSQLDialog::implExecuteStatement(const String& _rStatement)
237 	{
238 		CHECK_INVARIANTS("DirectSQLDialog::implExecuteStatement");
239 
240 		::osl::MutexGuard aGuard(m_aMutex);
241 
242 		String sStatus;
243 		try
244 		{
245 			// create a statement
246 			Reference< XStatement > xStatement = m_xConnection->createStatement();
247 			OSL_ENSURE(xStatement.is(), "DirectSQLDialog::implExecuteStatement: no statement returned by the connection!");
248 
249 			// execute it
250 			if (xStatement.is())
251 				xStatement->execute(_rStatement);
252 
253 			// successfull
254 			sStatus = String(ModuleRes(STR_COMMAND_EXECUTED_SUCCESSFULLY));
255 
256 			// dispose the statement
257 			::comphelper::disposeComponent(xStatement);
258 		}
259 		catch(const SQLException& e)
260 		{
261 			sStatus = e.Message;
262 		}
263         catch( const Exception& )
264         {
265             DBG_UNHANDLED_EXCEPTION();
266         }
267 
268 		// add the status text
269 		addStatusText(sStatus);
270 	}
271 
272 	//--------------------------------------------------------------------
273 	void DirectSQLDialog::addStatusText(const String& _rMessage)
274 	{
275 		String sAppendMessage = String::CreateFromInt32(m_nStatusCount++);
276 		sAppendMessage += String::CreateFromAscii(": ");
277 		sAppendMessage += _rMessage;
278 		sAppendMessage += String::CreateFromAscii("\n\n");
279 
280 		String sCompleteMessage = m_aStatus.GetText();
281 		sCompleteMessage += sAppendMessage;
282 		m_aStatus.SetText(sCompleteMessage);
283 
284 		m_aStatus.SetSelection(Selection(sCompleteMessage.Len(), sCompleteMessage.Len()));
285 	}
286 
287 	//--------------------------------------------------------------------
288 	void DirectSQLDialog::executeCurrent()
289 	{
290 		CHECK_INVARIANTS("DirectSQLDialog::executeCurrent");
291 
292 		String sStatement = m_aSQL.GetText();
293 
294 		// execute
295 		implExecuteStatement(sStatement);
296 
297 		// add the statement to the history
298 		implAddToStatementHistory(sStatement);
299 
300 		m_aSQL.SetSelection(Selection());
301 		m_aSQL.GrabFocus();
302 	}
303 
304 	//--------------------------------------------------------------------
305 	void DirectSQLDialog::switchToHistory(sal_Int32 _nHistoryPos, sal_Bool _bUpdateListBox)
306 	{
307 		CHECK_INVARIANTS("DirectSQLDialog::switchToHistory");
308 
309 		if ((_nHistoryPos >= 0) && (_nHistoryPos < getHistorySize()))
310 		{
311 			// set the text in the statement editor
312 			String sStatement = m_aStatementHistory[_nHistoryPos];
313 			m_aSQL.SetText(sStatement);
314 			OnStatementModified(&m_aSQL);
315 
316 			if (_bUpdateListBox)
317 			{
318 				// selecte the normalized statement in the list box
319 				m_pSQLHistory->SelectEntryPos((sal_uInt16)_nHistoryPos);
320 				OSL_ENSURE(m_pSQLHistory->GetSelectEntry() == m_aNormalizedHistory[_nHistoryPos],
321 					"DirectSQLDialog::switchToHistory: inconsistent listbox entries!");
322 			}
323 
324 			m_aSQL.GrabFocus();
325 			m_aSQL.SetSelection(Selection(sStatement.Len(), sStatement.Len()));
326 		}
327 		else
328 			OSL_ENSURE(sal_False, "DirectSQLDialog::switchToHistory: invalid position!");
329 	}
330 
331 	//--------------------------------------------------------------------
332 	IMPL_LINK( DirectSQLDialog, OnStatementModified, void*, /*NOTINTERESTEDIN*/ )
333 	{
334 		m_aExecute.Enable(0 != m_aSQL.GetText().Len());
335 		return 0L;
336 	}
337 
338 	//--------------------------------------------------------------------
339 	IMPL_LINK( DirectSQLDialog, OnClose, void*, /*NOTINTERESTEDIN*/ )
340 	{
341 		EndDialog( RET_OK );
342 		return 0L;
343 	}
344 
345 	//--------------------------------------------------------------------
346 	IMPL_LINK( DirectSQLDialog, OnExecute, void*, /*NOTINTERESTEDIN*/ )
347 	{
348 		executeCurrent();
349 		return 0L;
350 	}
351 
352 	//--------------------------------------------------------------------
353 	IMPL_LINK( DirectSQLDialog, OnListEntrySelected, void*, /*NOTINTERESTEDIN*/ )
354 	{
355 		if (!m_pSQLHistory->IsTravelSelect())
356 		{
357 			const sal_uInt16 nSelected = m_pSQLHistory->GetSelectEntryPos();
358 			if (LISTBOX_ENTRY_NOTFOUND != nSelected)
359 				switchToHistory(nSelected, sal_False);
360 		}
361 		return 0L;
362 	}
363 
364 //........................................................................
365 }	// namespace dbaui
366 //........................................................................
367 
368