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