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 //-------------------------------------------------------------------- 77 LargeEntryListBox::LargeEntryListBox( Window* _pParent, const ResId& _rId ) 78 :ListBox(_pParent, _rId ) 79 { 80 EnableUserDraw(sal_True); 81 } 82 83 //-------------------------------------------------------------------- 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 //==================================================================== 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 167 sal_Int32 DirectSQLDialog::getHistorySize() const 168 { 169 CHECK_INVARIANTS("DirectSQLDialog::getHistorySize"); 170 return m_aStatementHistory.size(); 171 } 172 173 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 213 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 //-------------------------------------------------------------------- 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 // successful 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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 //-------------------------------------------------------------------- 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