xref: /trunk/main/dbaccess/source/ui/dlg/directsql.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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