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