Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "adtabdlg.hxx"
22 : #include "browserids.hxx"
23 : #include "dbu_qry.hrc"
24 : #include "dbu_reghelper.hxx"
25 : #include "dbustrings.hrc"
26 : #include "defaultobjectnamecheck.hxx"
27 : #include "dlgsave.hxx"
28 : #include "localresaccess.hxx"
29 : #include "QTableWindow.hxx"
30 : #include "QTableWindowData.hxx"
31 : #include "querycontainerwindow.hxx"
32 : #include "querycontroller.hxx"
33 : #include "QueryDesignView.hxx"
34 : #include "QueryTableView.hxx"
35 : #include "QueryTextView.hxx"
36 : #include "queryview.hxx"
37 : #include "QueryViewSwitch.hxx"
38 : #include "sqlmessage.hxx"
39 : #include "TableConnectionData.hxx"
40 : #include "TableFieldDescription.hxx"
41 : #include "UITools.hxx"
42 :
43 : #include <com/sun/star/beans/PropertyAttribute.hpp>
44 : #include <com/sun/star/container/XChild.hpp>
45 : #include <com/sun/star/container/XNameContainer.hpp>
46 : #include <com/sun/star/frame/FrameSearchFlag.hpp>
47 : #include <com/sun/star/frame/XLoadEventListener.hpp>
48 : #include <com/sun/star/io/XActiveDataSink.hpp>
49 : #include <com/sun/star/io/XActiveDataSource.hpp>
50 : #include <com/sun/star/sdb/CommandType.hpp>
51 : #include <com/sun/star/sdb/SQLContext.hpp>
52 : #include <com/sun/star/sdb/XQueriesSupplier.hpp>
53 : #include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp>
54 : #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
55 : #include <com/sun/star/sdbc/SQLWarning.hpp>
56 : #include <com/sun/star/sdbc/XRow.hpp>
57 : #include <com/sun/star/sdbcx/XAppend.hpp>
58 : #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
59 : #include <com/sun/star/sdbcx/XDrop.hpp>
60 : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
61 : #include <com/sun/star/sdbcx/XViewsSupplier.hpp>
62 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
63 : #include <com/sun/star/util/XCloseable.hpp>
64 : #include <com/sun/star/util/VetoException.hpp>
65 : #include <com/sun/star/frame/XUntitledNumbers.hpp>
66 :
67 : #include <comphelper/basicio.hxx>
68 : #include <comphelper/extract.hxx>
69 : #include <comphelper/processfactory.hxx>
70 : #include <comphelper/property.hxx>
71 : #include <comphelper/seqstream.hxx>
72 : #include <comphelper/streamsection.hxx>
73 : #include <comphelper/types.hxx>
74 : #include <connectivity/dbexception.hxx>
75 : #include <connectivity/dbtools.hxx>
76 : #include <cppuhelper/exc_hlp.hxx>
77 : #include <sfx2/sfxsids.hrc>
78 : #include <svtools/localresaccess.hxx>
79 : #include <toolkit/helper/vclunohelper.hxx>
80 : #include <tools/diagnose_ex.h>
81 : #include <osl/diagnose.h>
82 : #include <vcl/msgbox.hxx>
83 : #include <vcl/svapp.hxx>
84 : #include <osl/mutex.hxx>
85 : #include <rtl/strbuf.hxx>
86 : #include <vector>
87 :
88 0 : extern "C" void SAL_CALL createRegistryInfo_OQueryControl()
89 : {
90 0 : static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OQueryController > aAutoRegistration;
91 0 : }
92 : namespace dbaui
93 : {
94 : using namespace ::com::sun::star::uno;
95 : using namespace ::com::sun::star::beans;
96 : using namespace ::com::sun::star::frame;
97 : using namespace ::com::sun::star::util;
98 : using namespace ::com::sun::star::lang;
99 :
100 0 : class OViewController : public OQueryController
101 : {
102 : //------------------------------------------------------------------------------
103 0 : virtual ::rtl::OUString SAL_CALL getImplementationName() throw( RuntimeException )
104 : {
105 0 : return getImplementationName_Static();
106 : }
107 : //-------------------------------------------------------------------------
108 0 : virtual Sequence< ::rtl::OUString> SAL_CALL getSupportedServiceNames() throw(RuntimeException)
109 : {
110 0 : return getSupportedServiceNames_Static();
111 : }
112 : public:
113 0 : OViewController(const Reference< XMultiServiceFactory >& _rM) : OQueryController(_rM){}
114 :
115 : // need by registration
116 0 : static ::rtl::OUString getImplementationName_Static() throw( RuntimeException )
117 : {
118 0 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.OViewDesign"));
119 : }
120 0 : static Sequence< ::rtl::OUString > getSupportedServiceNames_Static(void) throw( RuntimeException )
121 : {
122 0 : Sequence< ::rtl::OUString> aSupported(1);
123 0 : aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.ViewDesign"));
124 0 : return aSupported;
125 : }
126 0 : static Reference< XInterface > SAL_CALL Create(const Reference< XMultiServiceFactory >& _rM)
127 : {
128 0 : return *(new OViewController(_rM));
129 : }
130 : };
131 : }
132 0 : extern "C" void SAL_CALL createRegistryInfo_OViewControl()
133 : {
134 0 : static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::OViewController > aAutoRegistration;
135 0 : }
136 :
137 : namespace dbaui
138 : {
139 : using namespace ::connectivity;
140 : #if OSL_DEBUG_LEVEL > 1
141 : namespace
142 : {
143 : // -----------------------------------------------------------------------------
144 : void insertParseTree(SvTreeListBox* _pBox,::connectivity::OSQLParseNode* _pNode,SvTreeListEntry* _pParent = NULL)
145 : {
146 : ::rtl::OUString rString;
147 : if (!_pNode->isToken())
148 : {
149 : // Regelnamen als rule: ...
150 : rString = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("RULE_ID: "));
151 : rString += ::rtl::OUString::valueOf( (sal_Int32)_pNode->getRuleID());
152 : rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("("));
153 : rString += OSQLParser::RuleIDToStr(_pNode->getRuleID());
154 : rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(")"));
155 :
156 :
157 : _pParent = _pBox->InsertEntry(rString,_pParent);
158 :
159 : // einmal auswerten wieviel Subtrees dieser Knoten besitzt
160 : sal_uInt32 nStop = _pNode->count();
161 : // hol dir den ersten Subtree
162 : for(sal_uInt32 i=0;i<nStop;++i)
163 : insertParseTree(_pBox,_pNode->getChild(i),_pParent);
164 : }
165 : else
166 : {
167 : // ein Token gefunden
168 : // tabs fuer das Einruecken entsprechend nLevel
169 :
170 : switch (_pNode->getNodeType())
171 : {
172 :
173 : case SQL_NODE_KEYWORD:
174 : {
175 : rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_KEYWORD:"));
176 : ::rtl::OString sT = OSQLParser::TokenIDToStr(_pNode->getTokenID());
177 : rString += ::rtl::OStringToOUString(sT, RTL_TEXTENCODING_UTF8);
178 : break;}
179 :
180 : case SQL_NODE_COMPARISON:
181 : {
182 : rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_COMPARISON:"));
183 : rString += _pNode->getTokenValue(); // haenge Nodevalue an
184 : // und beginne neu Zeile
185 : break;}
186 :
187 : case SQL_NODE_NAME:
188 : {
189 : rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_NAME:"));
190 : rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\""));
191 : rString += _pNode->getTokenValue();
192 : rString+= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\""));
193 : break;}
194 :
195 : case SQL_NODE_STRING:
196 : {
197 : rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_STRING:'"));
198 : rString += _pNode->getTokenValue();
199 : break;}
200 :
201 : case SQL_NODE_INTNUM:
202 : {
203 : rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_INTNUM:"));
204 : rString += _pNode->getTokenValue();
205 : break;}
206 :
207 : case SQL_NODE_APPROXNUM:
208 : {
209 : rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_APPROXNUM:"));
210 : rString += _pNode->getTokenValue();
211 : break;}
212 :
213 : case SQL_NODE_PUNCTUATION:
214 : {
215 : rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_PUNCTUATION:"));
216 : rString += _pNode->getTokenValue(); // haenge Nodevalue an
217 : break;}
218 :
219 : case SQL_NODE_AMMSC:
220 : {
221 : rString += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SQL_AMMSC:"));
222 : rString += _pNode->getTokenValue(); // haenge Nodevalue an
223 : break;}
224 :
225 : default:
226 : OSL_FAIL("OSQLParser::ShowParseTree: unzulaessiger NodeType");
227 : rString += _pNode->getTokenValue();
228 : }
229 : _pBox->InsertEntry(rString,_pParent);
230 : }
231 : }
232 : }
233 : #endif // OSL_DEBUG_LEVEL
234 :
235 : namespace
236 : {
237 : // -----------------------------------------------------------------------------
238 0 : String lcl_getObjectResourceString( sal_uInt16 _nResId, sal_Int32 _nCommandType )
239 : {
240 0 : String sMessageText = String( ModuleRes( _nResId ) );
241 0 : String sObjectType;
242 : {
243 0 : LocalResourceAccess aLocalRes( RSC_QUERY_OBJECT_TYPE, RSC_RESOURCE );
244 0 : sObjectType = String( ModuleRes( (sal_uInt16)( _nCommandType + 1 ) ) );
245 : }
246 0 : sMessageText.SearchAndReplace( rtl::OUString("$object$"), sObjectType );
247 0 : return sMessageText;
248 : }
249 : }
250 :
251 : using namespace ::com::sun::star::uno;
252 : using namespace ::com::sun::star::io;
253 : using namespace ::com::sun::star::beans;
254 : using namespace ::com::sun::star::frame;
255 : using namespace ::com::sun::star::util;
256 : using namespace ::com::sun::star::lang;
257 : using namespace ::com::sun::star::container;
258 : using namespace ::com::sun::star::sdbcx;
259 : using namespace ::com::sun::star::sdbc;
260 : using namespace ::com::sun::star::sdb;
261 : using namespace ::com::sun::star::ui::dialogs;
262 : using namespace ::com::sun::star::awt;
263 : using namespace ::dbtools;
264 :
265 : using namespace ::comphelper;
266 :
267 : namespace
268 : {
269 0 : void ensureToolbars( OQueryController& _rController, sal_Bool _bDesign )
270 : {
271 0 : Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = _rController.getLayoutManager( _rController.getFrame() );
272 0 : if ( xLayoutManager.is() )
273 : {
274 0 : xLayoutManager->lock();
275 0 : static ::rtl::OUString s_sDesignToolbar(RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/designobjectbar"));
276 0 : static ::rtl::OUString s_sSqlToolbar(RTL_CONSTASCII_USTRINGPARAM("private:resource/toolbar/sqlobjectbar"));
277 0 : if ( _bDesign )
278 : {
279 0 : xLayoutManager->destroyElement( s_sSqlToolbar );
280 0 : xLayoutManager->createElement( s_sDesignToolbar );
281 : }
282 : else
283 : {
284 0 : xLayoutManager->destroyElement( s_sDesignToolbar );
285 0 : xLayoutManager->createElement( s_sSqlToolbar );
286 : }
287 0 : xLayoutManager->unlock();
288 0 : xLayoutManager->doLayout();
289 0 : }
290 0 : }
291 : }
292 :
293 : //------------------------------------------------------------------------------
294 0 : ::rtl::OUString SAL_CALL OQueryController::getImplementationName() throw( RuntimeException )
295 : {
296 0 : return getImplementationName_Static();
297 : }
298 :
299 : //------------------------------------------------------------------------------
300 0 : ::rtl::OUString OQueryController::getImplementationName_Static() throw( RuntimeException )
301 : {
302 0 : return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.OQueryDesign"));
303 : }
304 : //------------------------------------------------------------------------------
305 0 : Sequence< ::rtl::OUString> OQueryController::getSupportedServiceNames_Static(void) throw( RuntimeException )
306 : {
307 0 : Sequence< ::rtl::OUString> aSupported(1);
308 0 : aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.QueryDesign"));
309 0 : return aSupported;
310 : }
311 : //-------------------------------------------------------------------------
312 0 : Sequence< ::rtl::OUString> SAL_CALL OQueryController::getSupportedServiceNames() throw(RuntimeException)
313 : {
314 0 : return getSupportedServiceNames_Static();
315 : }
316 : // -------------------------------------------------------------------------
317 0 : Reference< XInterface > SAL_CALL OQueryController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
318 : {
319 0 : return *(new OQueryController(_rxFactory));
320 : }
321 : DBG_NAME(OQueryController);
322 : // -----------------------------------------------------------------------------
323 0 : OQueryController::OQueryController(const Reference< XMultiServiceFactory >& _rM)
324 : :OJoinController(_rM)
325 0 : ,OQueryController_PBase( getBroadcastHelper() )
326 0 : ,m_pParseContext( new svxform::OSystemParseContext )
327 : ,m_aSqlParser( comphelper::getComponentContext(_rM), m_pParseContext )
328 : ,m_pSqlIterator(NULL)
329 : ,m_nVisibleRows(0x400)
330 : ,m_nSplitPos(-1)
331 : ,m_nCommandType( CommandType::QUERY )
332 : ,m_bGraphicalDesign(sal_False)
333 : ,m_bDistinct(sal_False)
334 : ,m_bViewAlias(sal_False)
335 : ,m_bViewTable(sal_False)
336 : ,m_bViewFunction(sal_False)
337 0 : ,m_bEscapeProcessing(sal_True)
338 : {
339 : DBG_CTOR(OQueryController,NULL);
340 0 : InvalidateAll();
341 :
342 : registerProperty( PROPERTY_ACTIVECOMMAND, PROPERTY_ID_ACTIVECOMMAND, PropertyAttribute::READONLY | PropertyAttribute::BOUND,
343 0 : &m_sStatement, ::getCppuType( &m_sStatement ) );
344 : registerProperty( PROPERTY_ESCAPE_PROCESSING, PROPERTY_ID_ESCAPE_PROCESSING, PropertyAttribute::READONLY | PropertyAttribute::BOUND,
345 0 : &m_bEscapeProcessing, ::getCppuType( &m_bEscapeProcessing ) );
346 0 : }
347 :
348 : // -----------------------------------------------------------------------------
349 0 : OQueryController::~OQueryController()
350 : {
351 : DBG_DTOR(OQueryController,NULL);
352 0 : if ( !getBroadcastHelper().bDisposed && !getBroadcastHelper().bInDispose )
353 : {
354 : OSL_FAIL("Please check who doesn't dispose this component!");
355 : // increment ref count to prevent double call of Dtor
356 0 : osl_atomic_increment( &m_refCount );
357 0 : dispose();
358 : }
359 0 : }
360 :
361 0 : IMPLEMENT_FORWARD_XINTERFACE2( OQueryController, OJoinController, OQueryController_PBase )
362 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2( OQueryController, OJoinController, OQueryController_PBase )
363 :
364 : //-------------------------------------------------------------------------
365 0 : Reference< XPropertySetInfo > SAL_CALL OQueryController::getPropertySetInfo() throw(RuntimeException)
366 : {
367 0 : Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
368 0 : return xInfo;
369 : }
370 :
371 : //-------------------------------------------------------------------------
372 0 : sal_Bool SAL_CALL OQueryController::convertFastPropertyValue( Any& o_rConvertedValue, Any& o_rOldValue, sal_Int32 i_nHandle, const Any& i_rValue ) throw (IllegalArgumentException)
373 : {
374 0 : return OPropertyContainer::convertFastPropertyValue( o_rConvertedValue, o_rOldValue, i_nHandle, i_rValue );
375 : }
376 :
377 : //-------------------------------------------------------------------------
378 0 : void SAL_CALL OQueryController::setFastPropertyValue_NoBroadcast( sal_Int32 i_nHandle, const Any& i_rValue ) throw ( Exception )
379 : {
380 0 : OPropertyContainer::setFastPropertyValue_NoBroadcast( i_nHandle, i_rValue );
381 0 : }
382 :
383 : //-------------------------------------------------------------------------
384 0 : void SAL_CALL OQueryController::getFastPropertyValue( Any& o_rValue, sal_Int32 i_nHandle ) const
385 : {
386 0 : switch ( i_nHandle )
387 : {
388 : case PROPERTY_ID_CURRENT_QUERY_DESIGN:
389 : {
390 0 : ::comphelper::NamedValueCollection aCurrentDesign;
391 0 : aCurrentDesign.put( "GraphicalDesign", isGraphicalDesign() );
392 0 : aCurrentDesign.put( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, m_bEscapeProcessing );
393 :
394 0 : if ( isGraphicalDesign() )
395 : {
396 0 : getContainer()->SaveUIConfig();
397 0 : saveViewSettings( aCurrentDesign, true );
398 0 : aCurrentDesign.put( "Statement", m_sStatement );
399 : }
400 : else
401 : {
402 0 : aCurrentDesign.put( "Statement", getContainer()->getStatement() );
403 : }
404 :
405 0 : o_rValue <<= aCurrentDesign.getPropertyValues();
406 : }
407 0 : break;
408 :
409 : default:
410 0 : OPropertyContainer::getFastPropertyValue( o_rValue, i_nHandle );
411 0 : break;
412 : }
413 0 : }
414 :
415 : //-------------------------------------------------------------------------
416 0 : ::cppu::IPropertyArrayHelper& OQueryController::getInfoHelper()
417 : {
418 0 : return *const_cast< OQueryController* >( this )->getArrayHelper();
419 : }
420 :
421 : //--------------------------------------------------------------------
422 0 : ::cppu::IPropertyArrayHelper* OQueryController::createArrayHelper( ) const
423 : {
424 0 : Sequence< Property > aProps;
425 0 : describeProperties( aProps );
426 :
427 : // one additional property:
428 0 : const sal_Int32 nLength = aProps.getLength();
429 0 : aProps.realloc( nLength + 1 );
430 0 : aProps[ nLength ] = Property(
431 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CurrentQueryDesign" ) ),
432 : PROPERTY_ID_CURRENT_QUERY_DESIGN,
433 0 : ::cppu::UnoType< Sequence< PropertyValue > >::get(),
434 : PropertyAttribute::READONLY
435 0 : );
436 :
437 : ::std::sort(
438 : aProps.getArray(),
439 0 : aProps.getArray() + aProps.getLength(),
440 : ::comphelper::PropertyCompareByName()
441 0 : );
442 :
443 0 : return new ::cppu::OPropertyArrayHelper(aProps);
444 : }
445 :
446 : // -----------------------------------------------------------------------------
447 0 : void OQueryController::deleteIterator()
448 : {
449 0 : if(m_pSqlIterator)
450 : {
451 0 : delete m_pSqlIterator->getParseTree();
452 0 : m_pSqlIterator->dispose();
453 0 : delete m_pSqlIterator;
454 0 : m_pSqlIterator = NULL;
455 : }
456 0 : }
457 : // -----------------------------------------------------------------------------
458 0 : void OQueryController::disposing()
459 : {
460 0 : OQueryController_PBase::disposing();
461 :
462 0 : deleteIterator();
463 :
464 0 : delete m_pParseContext;
465 :
466 0 : clearFields();
467 0 : OTableFields().swap(m_vUnUsedFieldsDesc);
468 :
469 0 : ::comphelper::disposeComponent(m_xComposer);
470 0 : OJoinController::disposing();
471 0 : OQueryController_PBase::disposing();
472 0 : }
473 : // -----------------------------------------------------------------------------
474 0 : void OQueryController::clearFields()
475 : {
476 0 : OTableFields().swap(m_vTableFieldDesc);
477 0 : }
478 : // -----------------------------------------------------------------------------
479 0 : FeatureState OQueryController::GetState(sal_uInt16 _nId) const
480 : {
481 0 : FeatureState aReturn;
482 0 : aReturn.bEnabled = sal_True;
483 : // (disabled automatically)
484 :
485 0 : switch (_nId)
486 : {
487 : case ID_BROWSER_EDITDOC:
488 0 : if ( editingCommand() )
489 0 : aReturn.bEnabled = sal_False;
490 0 : else if ( editingView() && !m_xAlterView.is() )
491 0 : aReturn.bEnabled = sal_False;
492 : else
493 0 : aReturn = OJoinController::GetState( _nId );
494 0 : break;
495 :
496 : case ID_BROWSER_ESACPEPROCESSING:
497 0 : aReturn.bChecked = !m_bEscapeProcessing;
498 0 : aReturn.bEnabled = ( m_pSqlIterator != NULL ) && !m_bGraphicalDesign;
499 0 : break;
500 : case SID_RELATION_ADD_RELATION:
501 0 : aReturn.bEnabled = isEditable() && m_bGraphicalDesign && m_vTableData.size() > 1;
502 0 : break;
503 : case ID_BROWSER_SAVEASDOC:
504 0 : aReturn.bEnabled = !editingCommand() && !editingView() && (!m_bGraphicalDesign || !(m_vTableFieldDesc.empty() || m_vTableData.empty()));
505 0 : break;
506 : case ID_BROWSER_SAVEDOC:
507 0 : aReturn.bEnabled = impl_isModified() && (!m_bGraphicalDesign || !(m_vTableFieldDesc.empty() || m_vTableData.empty()));
508 0 : break;
509 : case SID_PRINTDOCDIRECT:
510 0 : break;
511 : case ID_BROWSER_CUT:
512 0 : aReturn.bEnabled = isEditable() && getContainer() && getContainer()->isCutAllowed();
513 0 : break;
514 : case ID_BROWSER_COPY:
515 0 : aReturn.bEnabled = getContainer() && getContainer()->isCopyAllowed();
516 0 : break;
517 : case ID_BROWSER_PASTE:
518 0 : aReturn.bEnabled = isEditable() && getContainer() && getContainer()->isPasteAllowed();
519 0 : break;
520 : case ID_BROWSER_SQL:
521 0 : aReturn.bEnabled = m_bEscapeProcessing && m_pSqlIterator;
522 0 : aReturn.bChecked = m_bGraphicalDesign;
523 0 : break;
524 : case SID_BROWSER_CLEAR_QUERY:
525 0 : aReturn.bEnabled = isEditable() && (!m_sStatement.isEmpty() || !m_vTableData.empty());
526 0 : break;
527 : case SID_QUERY_VIEW_FUNCTIONS:
528 : case SID_QUERY_VIEW_TABLES:
529 : case SID_QUERY_VIEW_ALIASES:
530 0 : aReturn.bChecked = getContainer() && getContainer()->isSlotEnabled(_nId);
531 0 : aReturn.bEnabled = m_bGraphicalDesign;
532 0 : break;
533 : case SID_QUERY_DISTINCT_VALUES:
534 0 : aReturn.bEnabled = m_bGraphicalDesign && isEditable();
535 0 : aReturn.bChecked = m_bDistinct;
536 0 : break;
537 : case ID_BROWSER_QUERY_EXECUTE:
538 0 : aReturn.bEnabled = sal_True;
539 0 : break;
540 : case SID_DB_QUERY_PREVIEW:
541 0 : aReturn.bEnabled = sal_True;
542 0 : aReturn.bChecked = getContainer() && getContainer()->getPreviewFrame().is();
543 0 : break;
544 : #if OSL_DEBUG_LEVEL > 1
545 : case ID_EDIT_QUERY_SQL:
546 : break;
547 : case ID_EDIT_QUERY_DESIGN:
548 : break;
549 : #endif
550 : case ID_BROWSER_ADDTABLE:
551 0 : if ( !m_bGraphicalDesign )
552 : {
553 0 : aReturn.bEnabled = sal_False;
554 0 : break;
555 : }
556 : // run through
557 : default:
558 0 : aReturn = OJoinController::GetState(_nId);
559 0 : break;
560 : }
561 0 : return aReturn;
562 : }
563 : // -----------------------------------------------------------------------------
564 0 : void OQueryController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs)
565 : {
566 0 : switch(_nId)
567 : {
568 : case ID_BROWSER_ESACPEPROCESSING:
569 0 : setEscapeProcessing_fireEvent( !m_bEscapeProcessing );
570 0 : if ( !editingView() )
571 0 : setModified(sal_True);
572 0 : InvalidateFeature(ID_BROWSER_SQL);
573 0 : break;
574 : case ID_BROWSER_SAVEASDOC:
575 : case ID_BROWSER_SAVEDOC:
576 0 : doSaveAsDoc(ID_BROWSER_SAVEASDOC == _nId);
577 0 : break;
578 : case SID_RELATION_ADD_RELATION:
579 : {
580 0 : OJoinDesignView* pView = getJoinView();
581 0 : if( pView )
582 0 : static_cast<OQueryTableView*>(pView->getTableView())->createNewConnection();
583 : }
584 0 : break;
585 : case SID_PRINTDOCDIRECT:
586 0 : break;
587 : case ID_BROWSER_CUT:
588 0 : getContainer()->cut();
589 0 : break;
590 : case ID_BROWSER_COPY:
591 0 : getContainer()->copy();
592 0 : break;
593 : case ID_BROWSER_PASTE:
594 0 : getContainer()->paste();
595 0 : break;
596 : case ID_BROWSER_SQL:
597 : {
598 0 : if ( !getContainer()->checkStatement() )
599 : break;
600 0 : SQLExceptionInfo aError;
601 : try
602 : {
603 0 : ::rtl::OUString aErrorMsg;
604 0 : setStatement_fireEvent( getContainer()->getStatement() );
605 0 : if(m_sStatement.isEmpty() && m_pSqlIterator)
606 : {
607 : // change the view of the data
608 0 : delete m_pSqlIterator->getParseTree();
609 0 : m_pSqlIterator->setParseTree(NULL);
610 0 : m_bGraphicalDesign = !m_bGraphicalDesign;
611 0 : impl_setViewMode( &aError );
612 : }
613 : else
614 : {
615 0 : ::connectivity::OSQLParseNode* pNode = m_aSqlParser.parseTree(aErrorMsg,m_sStatement,m_bGraphicalDesign);
616 0 : if ( pNode )
617 : {
618 0 : delete m_pSqlIterator->getParseTree();
619 0 : m_pSqlIterator->setParseTree(pNode);
620 0 : m_pSqlIterator->traverseAll();
621 :
622 0 : if ( m_pSqlIterator->hasErrors() )
623 : {
624 0 : aError = m_pSqlIterator->getErrors();
625 : }
626 : else
627 : {
628 0 : const OSQLTables& xTabs = m_pSqlIterator->getTables();
629 0 : if ( m_pSqlIterator->getStatementType() != SQL_STATEMENT_SELECT || xTabs.begin() == xTabs.end() )
630 : {
631 : aError = SQLException(
632 : String( ModuleRes( STR_QRY_NOSELECT ) ),
633 : NULL,
634 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ),
635 : 1000,
636 : Any()
637 0 : );
638 : }
639 : else
640 : {
641 : // change the view of the data
642 0 : m_bGraphicalDesign = !m_bGraphicalDesign;
643 0 : ::rtl::OUString sNewStatement;
644 0 : pNode->parseNodeToStr( sNewStatement, getConnection() );
645 0 : setStatement_fireEvent( sNewStatement );
646 0 : getContainer()->SaveUIConfig();
647 0 : m_vTableConnectionData.clear();
648 0 : impl_setViewMode( &aError );
649 : }
650 : }
651 : }
652 : else
653 : {
654 : aError = SQLException(
655 : String( ModuleRes( STR_QRY_SYNTAX ) ),
656 : NULL,
657 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "S1000" ) ),
658 : 1000,
659 : Any()
660 0 : );
661 : }
662 0 : }
663 : }
664 0 : catch(const SQLException&)
665 : {
666 0 : aError = ::cppu::getCaughtException();
667 : }
668 0 : catch(const Exception&)
669 : {
670 : DBG_UNHANDLED_EXCEPTION();
671 : }
672 :
673 0 : if ( aError.isValid() )
674 0 : showError( aError );
675 :
676 0 : if(m_bGraphicalDesign)
677 : {
678 0 : InvalidateFeature(ID_BROWSER_ADDTABLE);
679 0 : InvalidateFeature(SID_RELATION_ADD_RELATION);
680 0 : }
681 : }
682 0 : break;
683 : case SID_BROWSER_CLEAR_QUERY:
684 : {
685 0 : GetUndoManager().EnterListAction( String( ModuleRes(STR_QUERY_UNDO_TABWINDELETE) ), String() );
686 0 : getContainer()->clear();
687 0 : GetUndoManager().LeaveListAction();
688 :
689 0 : setStatement_fireEvent( ::rtl::OUString() );
690 0 : if(m_bGraphicalDesign)
691 0 : InvalidateFeature(ID_BROWSER_ADDTABLE);
692 : }
693 0 : break;
694 : case SID_QUERY_VIEW_FUNCTIONS:
695 : case SID_QUERY_VIEW_TABLES:
696 : case SID_QUERY_VIEW_ALIASES:
697 0 : getContainer()->setSlotEnabled(_nId,!getContainer()->isSlotEnabled(_nId));
698 0 : setModified(sal_True);
699 0 : break;
700 : case SID_QUERY_DISTINCT_VALUES:
701 0 : m_bDistinct = !m_bDistinct;
702 0 : setModified(sal_True);
703 0 : break;
704 : case ID_BROWSER_QUERY_EXECUTE:
705 0 : if ( getContainer()->checkStatement() )
706 0 : executeQuery();
707 0 : break;
708 : case SID_DB_QUERY_PREVIEW:
709 : try
710 : {
711 0 : Reference< ::com::sun::star::util::XCloseable > xCloseFrame( getContainer()->getPreviewFrame(), UNO_QUERY );
712 0 : if ( xCloseFrame.is() )
713 : {
714 : try
715 : {
716 0 : xCloseFrame->close( sal_True );
717 : }
718 0 : catch(const Exception&)
719 : {
720 : OSL_FAIL( "OQueryController::Execute(SID_DB_QUERY_PREVIEW): *nobody* is expected to veto closing the preview frame!" );
721 : }
722 : }
723 : else
724 0 : Execute(ID_BROWSER_QUERY_EXECUTE,Sequence< PropertyValue >());
725 : }
726 0 : catch(const Exception&)
727 : {
728 : }
729 0 : break;
730 : case ID_QUERY_ZOOM_IN:
731 : {
732 : }
733 0 : break;
734 : case ID_QUERY_ZOOM_OUT:
735 : {
736 : }
737 0 : break;
738 : #if OSL_DEBUG_LEVEL > 1
739 : case ID_EDIT_QUERY_DESIGN:
740 : case ID_EDIT_QUERY_SQL:
741 : {
742 : ::rtl::OUString aErrorMsg;
743 : setStatement_fireEvent( getContainer()->getStatement() );
744 : ::connectivity::OSQLParseNode* pNode = m_aSqlParser.parseTree( aErrorMsg, m_sStatement, m_bGraphicalDesign );
745 : if ( pNode )
746 : {
747 : Window* pView = getView();
748 : ModalDialog* pWindow = new ModalDialog( pView, WB_STDMODAL | WB_SIZEMOVE | WB_CENTER );
749 : pWindow->SetSizePixel( ::Size( pView->GetSizePixel().Width() / 2, pView->GetSizePixel().Height() / 2 ) );
750 : SvTreeListBox* pTreeBox = new SvTreeListBox( pWindow, WB_BORDER | WB_HASLINES | WB_HASBUTTONS | WB_HASBUTTONSATROOT | WB_HASLINESATROOT | WB_VSCROLL );
751 : pTreeBox->SetPosSizePixel( ::Point( 6, 6 ), ::Size( pWindow->GetSizePixel().Width() - 12, pWindow->GetSizePixel().Height() - 12 ));
752 : pTreeBox->SetNodeDefaultImages();
753 :
754 : if ( _nId == ID_EDIT_QUERY_DESIGN )
755 : {
756 : ::connectivity::OSQLParseNode* pTemp = pNode ? pNode->getChild(3)->getChild(1) : NULL;
757 : // no where clause found
758 : if ( pTemp && !pTemp->isLeaf() )
759 : {
760 : ::connectivity::OSQLParseNode * pCondition = pTemp->getChild(1);
761 : if ( pCondition ) // no where clause
762 : {
763 : ::connectivity::OSQLParseNode::negateSearchCondition(pCondition);
764 : ::connectivity::OSQLParseNode *pNodeTmp = pTemp->getChild(1);
765 :
766 : ::connectivity::OSQLParseNode::disjunctiveNormalForm(pNodeTmp);
767 : pNodeTmp = pTemp->getChild(1);
768 : ::connectivity::OSQLParseNode::absorptions(pNodeTmp);
769 : pNodeTmp = pTemp->getChild(1);
770 : OSQLParseNode::compress(pNodeTmp);
771 : pNodeTmp = pTemp->getChild(1);
772 : }
773 : ::rtl::OUString sTemp;
774 : pNode->parseNodeToStr(sTemp,getConnection());
775 : getContainer()->setStatement(sTemp);
776 : }
777 : }
778 :
779 : insertParseTree(pTreeBox,pNode);
780 :
781 : pTreeBox->Show();
782 : pWindow->Execute();
783 :
784 : delete pTreeBox;
785 : delete pWindow;
786 : delete pNode;
787 : }
788 : break;
789 : }
790 : #endif
791 : default:
792 0 : OJoinController::Execute(_nId,aArgs);
793 0 : return; // else we would invalidate twice
794 : }
795 0 : InvalidateFeature(_nId);
796 : }
797 :
798 : // -----------------------------------------------------------------------------
799 0 : void OQueryController::impl_showAutoSQLViewError( const ::com::sun::star::uno::Any& _rErrorDetails )
800 : {
801 0 : SQLContext aErrorContext;
802 0 : aErrorContext.Message = lcl_getObjectResourceString( STR_ERROR_PARSING_STATEMENT, m_nCommandType );
803 0 : aErrorContext.Context = *this;
804 0 : aErrorContext.Details = lcl_getObjectResourceString( STR_INFO_OPENING_IN_SQL_VIEW, m_nCommandType );
805 0 : aErrorContext.NextException = _rErrorDetails;
806 0 : showError( aErrorContext );
807 0 : }
808 :
809 : // -----------------------------------------------------------------------------
810 0 : bool OQueryController::impl_setViewMode( ::dbtools::SQLExceptionInfo* _pErrorInfo )
811 : {
812 : OSL_PRECOND( getContainer(), "OQueryController::impl_setViewMode: illegal call!" );
813 :
814 0 : bool wasModified = isModified();
815 :
816 0 : SQLExceptionInfo aError;
817 0 : bool bSuccess = getContainer()->switchView( &aError );
818 0 : if ( !bSuccess )
819 : {
820 0 : m_bGraphicalDesign = !m_bGraphicalDesign;
821 : // restore old state
822 0 : getContainer()->switchView( NULL );
823 : // don't pass &aError here, this would overwrite the error which the first switchView call
824 : // returned in this location.
825 0 : if ( _pErrorInfo )
826 0 : *_pErrorInfo = aError;
827 : else
828 0 : showError( aError );
829 : }
830 : else
831 : {
832 0 : ensureToolbars( *this, m_bGraphicalDesign );
833 : }
834 :
835 0 : setModified( wasModified );
836 0 : return bSuccess;
837 : }
838 :
839 : // -----------------------------------------------------------------------------
840 0 : void OQueryController::impl_initialize()
841 : {
842 0 : OJoinController::impl_initialize();
843 :
844 0 : const NamedValueCollection& rArguments( getInitParams() );
845 :
846 0 : ::rtl::OUString sCommand;
847 0 : m_nCommandType = CommandType::QUERY;
848 :
849 : // �����������������������������������������������������������������������������������������������������������������
850 : // � reading parameters
851 : // �����������������������������������������������������������������������������������������������������������������
852 : // legacy parameters first (later overwritten by regular parameters)
853 0 : ::rtl::OUString sIndependentSQLCommand;
854 0 : if ( rArguments.get_ensureType( "IndependentSQLCommand", sIndependentSQLCommand ) )
855 : {
856 : OSL_FAIL( "OQueryController::impl_initialize: IndependentSQLCommand is regognized for compatibility only!" );
857 0 : sCommand = sIndependentSQLCommand;
858 0 : m_nCommandType = CommandType::COMMAND;
859 : }
860 :
861 0 : ::rtl::OUString sCurrentQuery;
862 0 : if ( rArguments.get_ensureType( "CurrentQuery", sCurrentQuery ) )
863 : {
864 : OSL_FAIL( "OQueryController::impl_initialize: CurrentQuery is regognized for compatibility only!" );
865 0 : sCommand = sCurrentQuery;
866 0 : m_nCommandType = CommandType::QUERY;
867 : }
868 :
869 0 : sal_Bool bCreateView( sal_False );
870 0 : if ( rArguments.get_ensureType( "CreateView", bCreateView ) && bCreateView )
871 : {
872 : OSL_FAIL( "OQueryController::impl_initialize: CurrentQuery is regognized for compatibility only!" );
873 0 : m_nCommandType = CommandType::TABLE;
874 : }
875 :
876 : // non-legacy parameters which overwrite the legacy parameters
877 0 : rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sCommand );
878 0 : rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, m_nCommandType );
879 :
880 : // translate Command/Type into proper members
881 : // TODO/Later: all this (including those members) should be hidden behind some abstact interface,
882 : // which is implemented for all the three commands
883 0 : switch ( m_nCommandType )
884 : {
885 : case CommandType::QUERY:
886 0 : m_sName = sCommand;
887 0 : break;
888 : case CommandType::TABLE:
889 0 : m_sName = sCommand;
890 0 : break;
891 : case CommandType::COMMAND:
892 0 : setStatement_fireEvent( sCommand );
893 0 : m_sName = ::rtl::OUString();
894 0 : break;
895 : default:
896 : OSL_FAIL( "OQueryController::impl_initialize: logic error in code!" );
897 0 : throw RuntimeException();
898 : }
899 :
900 : // more legacy parameters
901 0 : sal_Bool bGraphicalDesign( sal_True );
902 0 : if ( rArguments.get_ensureType( (::rtl::OUString)PROPERTY_QUERYDESIGNVIEW, bGraphicalDesign ) )
903 : {
904 : OSL_FAIL( "OQueryController::impl_initialize: QueryDesignView is regognized for compatibility only!" );
905 0 : m_bGraphicalDesign = bGraphicalDesign;
906 : }
907 :
908 : // more non-legacy
909 0 : rArguments.get_ensureType( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, m_bGraphicalDesign );
910 :
911 0 : bool bEscapeProcessing( sal_True );
912 0 : if ( rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEscapeProcessing ) )
913 : {
914 0 : setEscapeProcessing_fireEvent( bEscapeProcessing );
915 :
916 : OSL_ENSURE( m_bEscapeProcessing || !m_bGraphicalDesign, "OQueryController::impl_initialize: can't do the graphical design without escape processing!" );
917 0 : if ( !m_bEscapeProcessing )
918 0 : m_bGraphicalDesign = false;
919 : }
920 :
921 : // .................................................................................................................
922 : // . initial design
923 0 : bool bForceInitialDesign = false;
924 0 : Sequence< PropertyValue > aCurrentQueryDesignProps;
925 0 : aCurrentQueryDesignProps = rArguments.getOrDefault( "CurrentQueryDesign", aCurrentQueryDesignProps );
926 :
927 0 : if ( aCurrentQueryDesignProps.getLength() )
928 : {
929 0 : ::comphelper::NamedValueCollection aCurrentQueryDesign( aCurrentQueryDesignProps );
930 0 : if ( aCurrentQueryDesign.has( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN ) )
931 : {
932 0 : aCurrentQueryDesign.get_ensureType( (::rtl::OUString)PROPERTY_GRAPHICAL_DESIGN, m_bGraphicalDesign );
933 : }
934 0 : if ( aCurrentQueryDesign.has( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING ) )
935 : {
936 0 : aCurrentQueryDesign.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, m_bEscapeProcessing );
937 : }
938 0 : if ( aCurrentQueryDesign.has( "Statement" ) )
939 : {
940 0 : ::rtl::OUString sStatement;
941 0 : aCurrentQueryDesign.get_ensureType( "Statement", sStatement );
942 0 : aCurrentQueryDesign.remove( "Statement" );
943 0 : setStatement_fireEvent( sStatement );
944 : }
945 :
946 0 : loadViewSettings( aCurrentQueryDesign );
947 :
948 0 : bForceInitialDesign = true;
949 : }
950 :
951 : // �����������������������������������������������������������������������������������������������������������������
952 0 : if ( !ensureConnected( sal_False ) )
953 : { // we have no connection so what else should we do
954 0 : m_bGraphicalDesign = sal_False;
955 0 : if ( editingView() )
956 : {
957 0 : connectionLostMessage();
958 0 : throw SQLException();
959 : }
960 : }
961 :
962 : // check the view capabilities
963 0 : if ( isConnected() && editingView() )
964 : {
965 0 : Reference< XViewsSupplier > xViewsSup( getConnection(), UNO_QUERY );
966 0 : Reference< XNameAccess > xViews;
967 0 : if ( xViewsSup.is() )
968 0 : xViews = xViewsSup->getViews();
969 :
970 0 : if ( !xViews.is() )
971 : { // we can't create views so we ask if the user wants to create a query instead
972 0 : m_nCommandType = CommandType::QUERY;
973 0 : sal_Bool bClose = sal_False;
974 : {
975 0 : String aTitle( ModuleRes( STR_QUERYDESIGN_NO_VIEW_SUPPORT ) );
976 0 : String aMessage( ModuleRes( STR_QUERYDESIGN_NO_VIEW_ASK ) );
977 0 : ODataView* pWindow = getView();
978 0 : OSQLMessageBox aDlg( pWindow, aTitle, aMessage, WB_YES_NO | WB_DEF_YES, OSQLMessageBox::Query );
979 0 : bClose = aDlg.Execute() == RET_NO;
980 : }
981 0 : if ( bClose )
982 0 : throw VetoException();
983 : }
984 :
985 : // now if we are to edit an existing view, check whether this is possible
986 0 : if ( !m_sName.isEmpty() )
987 : {
988 0 : Any aView( xViews->getByName( m_sName ) );
989 : // will throw if there is no such view
990 0 : if ( !( aView >>= m_xAlterView ) )
991 : {
992 : throw IllegalArgumentException(
993 : ::rtl::OUString( String( ModuleRes( STR_NO_ALTER_VIEW_SUPPORT ) ) ),
994 : *this,
995 : 1
996 0 : );
997 0 : }
998 0 : }
999 : }
1000 :
1001 : OSL_ENSURE(getDataSource().is(),"OQueryController::impl_initialize: need a datasource!");
1002 :
1003 : try
1004 : {
1005 0 : getContainer()->initialize();
1006 0 : impl_reset( bForceInitialDesign );
1007 :
1008 0 : SQLExceptionInfo aError;
1009 0 : const bool bAttemptedGraphicalDesign = m_bGraphicalDesign;
1010 :
1011 0 : if ( bForceInitialDesign )
1012 : {
1013 0 : getContainer()->forceInitialView();
1014 : }
1015 : else
1016 : {
1017 0 : impl_setViewMode( &aError );
1018 : }
1019 :
1020 0 : if ( aError.isValid() && bAttemptedGraphicalDesign && !m_bGraphicalDesign )
1021 : {
1022 : // we tried initializing the graphical view, this failed, and we were automatically switched to SQL
1023 : // view => tell this to the user
1024 0 : if ( !editingView() )
1025 : {
1026 0 : impl_showAutoSQLViewError( aError.get() );
1027 : }
1028 : }
1029 :
1030 0 : ClearUndoManager();
1031 :
1032 0 : if ( ( m_bGraphicalDesign )
1033 0 : && ( ( m_sName.isEmpty() && !editingCommand() )
1034 0 : || ( m_sStatement.isEmpty() && editingCommand() )
1035 : )
1036 : )
1037 : {
1038 0 : Application::PostUserEvent( LINK( this, OQueryController, OnExecuteAddTable ) );
1039 : }
1040 :
1041 0 : setModified(sal_False);
1042 : }
1043 0 : catch(const SQLException& e)
1044 : {
1045 : DBG_UNHANDLED_EXCEPTION();
1046 : // we caught an exception so we switch to text only mode
1047 : {
1048 0 : m_bGraphicalDesign = sal_False;
1049 0 : getContainer()->initialize();
1050 0 : ODataView* pWindow = getView();
1051 0 : OSQLMessageBox(pWindow,e).Execute();
1052 : }
1053 0 : throw;
1054 0 : }
1055 0 : }
1056 :
1057 : // -----------------------------------------------------------------------------
1058 0 : void OQueryController::onLoadedMenu(const Reference< ::com::sun::star::frame::XLayoutManager >& /*_xLayoutManager*/)
1059 : {
1060 0 : ensureToolbars( *this, m_bGraphicalDesign );
1061 0 : }
1062 :
1063 : // -----------------------------------------------------------------------------
1064 0 : ::rtl::OUString OQueryController::getPrivateTitle( ) const
1065 : {
1066 0 : ::rtl::OUString sName = m_sName;
1067 0 : if ( sName.isEmpty() )
1068 : {
1069 0 : if ( !editingCommand() )
1070 : {
1071 0 : SolarMutexGuard aSolarGuard;
1072 0 : ::osl::MutexGuard aGuard( getMutex() );
1073 0 : String aDefaultName = String( ModuleRes( editingView() ? STR_VIEW_TITLE : STR_QRY_TITLE ) );
1074 0 : sName = aDefaultName.GetToken(0,' ');
1075 0 : sName += ::rtl::OUString::valueOf(getCurrentStartNumber());
1076 : }
1077 : }
1078 0 : return sName;
1079 : }
1080 : // -----------------------------------------------------------------------------
1081 0 : void OQueryController::setQueryComposer()
1082 : {
1083 0 : if(isConnected())
1084 : {
1085 0 : Reference< XSQLQueryComposerFactory > xFactory(getConnection(), UNO_QUERY);
1086 : OSL_ENSURE(xFactory.is(),"Connection doesn't support a querycomposer");
1087 0 : if ( xFactory.is() && getContainer() )
1088 : {
1089 : try
1090 : {
1091 0 : m_xComposer = xFactory->createQueryComposer();
1092 0 : getContainer()->setStatement(m_sStatement);
1093 : }
1094 0 : catch(const Exception&)
1095 : {
1096 0 : m_xComposer = NULL;
1097 : }
1098 : OSL_ENSURE(m_xComposer.is(),"No querycomposer available!");
1099 0 : Reference<XTablesSupplier> xTablesSup(getConnection(), UNO_QUERY);
1100 0 : deleteIterator();
1101 0 : m_pSqlIterator = new ::connectivity::OSQLParseTreeIterator( getConnection(), xTablesSup->getTables(), m_aSqlParser, NULL );
1102 0 : }
1103 : }
1104 0 : }
1105 : // -----------------------------------------------------------------------------
1106 0 : sal_Bool OQueryController::Construct(Window* pParent)
1107 : {
1108 : // TODO: we have to check if we should create the text- or the design- view
1109 :
1110 0 : setView( * new OQueryContainerWindow( pParent, *this, comphelper::getComponentContext(getORB()) ) );
1111 :
1112 0 : return OJoinController::Construct(pParent);
1113 : }
1114 :
1115 : // -----------------------------------------------------------------------------
1116 0 : OJoinDesignView* OQueryController::getJoinView()
1117 : {
1118 0 : return getContainer()->getDesignView();
1119 : }
1120 : // -----------------------------------------------------------------------------
1121 0 : void OQueryController::describeSupportedFeatures()
1122 : {
1123 0 : OJoinController::describeSupportedFeatures();
1124 0 : implDescribeSupportedFeature( ".uno:SaveAs", ID_BROWSER_SAVEASDOC, CommandGroup::DOCUMENT );
1125 0 : implDescribeSupportedFeature( ".uno:SbaNativeSql", ID_BROWSER_ESACPEPROCESSING,CommandGroup::FORMAT );
1126 0 : implDescribeSupportedFeature( ".uno:DBViewFunctions", SID_QUERY_VIEW_FUNCTIONS, CommandGroup::VIEW );
1127 0 : implDescribeSupportedFeature( ".uno:DBViewTableNames", SID_QUERY_VIEW_TABLES, CommandGroup::VIEW );
1128 0 : implDescribeSupportedFeature( ".uno:DBViewAliases", SID_QUERY_VIEW_ALIASES, CommandGroup::VIEW );
1129 0 : implDescribeSupportedFeature( ".uno:DBDistinctValues", SID_QUERY_DISTINCT_VALUES, CommandGroup::FORMAT );
1130 0 : implDescribeSupportedFeature( ".uno:DBChangeDesignMode",ID_BROWSER_SQL, CommandGroup::VIEW );
1131 0 : implDescribeSupportedFeature( ".uno:DBClearQuery", SID_BROWSER_CLEAR_QUERY, CommandGroup::EDIT );
1132 0 : implDescribeSupportedFeature( ".uno:SbaExecuteSql", ID_BROWSER_QUERY_EXECUTE, CommandGroup::VIEW );
1133 0 : implDescribeSupportedFeature( ".uno:DBAddRelation", SID_RELATION_ADD_RELATION, CommandGroup::EDIT );
1134 0 : implDescribeSupportedFeature( ".uno:DBQueryPreview", SID_DB_QUERY_PREVIEW, CommandGroup::VIEW );
1135 :
1136 : #if OSL_DEBUG_LEVEL > 1
1137 : implDescribeSupportedFeature( ".uno:DBShowParseTree", ID_EDIT_QUERY_SQL );
1138 : implDescribeSupportedFeature( ".uno:DBMakeDisjunct", ID_EDIT_QUERY_DESIGN );
1139 : #endif
1140 0 : }
1141 : // -----------------------------------------------------------------------------
1142 0 : void OQueryController::impl_onModifyChanged()
1143 : {
1144 0 : OJoinController::impl_onModifyChanged();
1145 0 : InvalidateFeature(SID_BROWSER_CLEAR_QUERY);
1146 0 : InvalidateFeature(ID_BROWSER_SAVEASDOC);
1147 0 : InvalidateFeature(ID_BROWSER_QUERY_EXECUTE);
1148 0 : }
1149 : // -----------------------------------------------------------------------------
1150 0 : void SAL_CALL OQueryController::disposing( const EventObject& Source ) throw(RuntimeException)
1151 : {
1152 0 : SolarMutexGuard aGuard;
1153 :
1154 0 : if ( getContainer() && Source.Source.is() )
1155 : {
1156 0 : if ( Source.Source == m_aCurrentFrame.getFrame() )
1157 : { // our frame is being disposed -> close the preview window (if we have one)
1158 0 : Reference< XFrame > xPreviewFrame( getContainer()->getPreviewFrame() );
1159 0 : ::comphelper::disposeComponent( xPreviewFrame );
1160 : }
1161 0 : else if ( Source.Source == getContainer()->getPreviewFrame() )
1162 : {
1163 0 : getContainer()->disposingPreview();
1164 : }
1165 : }
1166 :
1167 0 : OJoinController::disposing(Source);
1168 0 : }
1169 : // -----------------------------------------------------------------------------
1170 0 : void OQueryController::reconnect(sal_Bool _bUI)
1171 : {
1172 0 : deleteIterator();
1173 0 : ::comphelper::disposeComponent(m_xComposer);
1174 :
1175 0 : OJoinController::reconnect( _bUI );
1176 :
1177 0 : if (isConnected())
1178 : {
1179 0 : setQueryComposer();
1180 : }
1181 : else
1182 : {
1183 0 : if(m_bGraphicalDesign)
1184 : {
1185 0 : m_bGraphicalDesign = sal_False;
1186 : // don't call Execute(SQL) because this changes the sql statement
1187 0 : impl_setViewMode( NULL );
1188 : }
1189 0 : InvalidateAll();
1190 : }
1191 0 : }
1192 :
1193 : // -----------------------------------------------------------------------------
1194 0 : void OQueryController::saveViewSettings( ::comphelper::NamedValueCollection& o_rViewSettings, const bool i_includingCriteria ) const
1195 : {
1196 0 : saveTableWindows( o_rViewSettings );
1197 :
1198 0 : OTableFields::const_iterator field = m_vTableFieldDesc.begin();
1199 0 : OTableFields::const_iterator fieldEnd = m_vTableFieldDesc.end();
1200 :
1201 0 : ::comphelper::NamedValueCollection aAllFieldsData;
1202 0 : ::comphelper::NamedValueCollection aFieldData;
1203 0 : for ( sal_Int32 i = 1; field != fieldEnd; ++field, ++i )
1204 : {
1205 0 : if ( !(*field)->IsEmpty() )
1206 : {
1207 0 : aFieldData.clear();
1208 0 : (*field)->Save( aFieldData, i_includingCriteria );
1209 :
1210 0 : const ::rtl::OUString sFieldSettingName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Field" ) ) + ::rtl::OUString::valueOf( i );
1211 0 : aAllFieldsData.put( sFieldSettingName, aFieldData.getPropertyValues() );
1212 : }
1213 : }
1214 :
1215 0 : o_rViewSettings.put( "Fields", aAllFieldsData.getPropertyValues() );
1216 0 : o_rViewSettings.put( "SplitterPosition", m_nSplitPos );
1217 0 : o_rViewSettings.put( "VisibleRows", m_nVisibleRows );
1218 0 : }
1219 : // -----------------------------------------------------------------------------
1220 0 : void OQueryController::loadViewSettings( const ::comphelper::NamedValueCollection& o_rViewSettings )
1221 : {
1222 0 : loadTableWindows( o_rViewSettings );
1223 :
1224 0 : m_nSplitPos = o_rViewSettings.getOrDefault( "SplitterPosition", m_nSplitPos );
1225 0 : m_nVisibleRows = o_rViewSettings.getOrDefault( "VisibleRows", m_nVisibleRows );
1226 0 : m_aFieldInformation = o_rViewSettings.getOrDefault( "Fields", m_aFieldInformation );
1227 0 : }
1228 : // -----------------------------------------------------------------------------
1229 0 : sal_Int32 OQueryController::getColWidth(sal_uInt16 _nColPos) const
1230 : {
1231 0 : if ( _nColPos < m_aFieldInformation.getLength() )
1232 : {
1233 0 : ::std::auto_ptr<OTableFieldDesc> pField( new OTableFieldDesc());
1234 0 : pField->Load( m_aFieldInformation[ _nColPos ], false );
1235 0 : return pField->GetColWidth();
1236 : }
1237 0 : return 0;
1238 : }
1239 : // -----------------------------------------------------------------------------
1240 0 : Reference<XNameAccess> OQueryController::getObjectContainer() const
1241 : {
1242 0 : Reference< XNameAccess > xElements;
1243 0 : if ( editingView() )
1244 : {
1245 0 : Reference< XViewsSupplier > xViewsSupp( getConnection(), UNO_QUERY );
1246 0 : if ( xViewsSupp.is() )
1247 0 : xElements = xViewsSupp->getViews();
1248 : }
1249 : else
1250 : {
1251 0 : Reference< XQueriesSupplier > xQueriesSupp( getConnection(), UNO_QUERY );
1252 0 : if ( xQueriesSupp.is() )
1253 0 : xElements = xQueriesSupp->getQueries();
1254 : else
1255 : {
1256 0 : Reference< XQueryDefinitionsSupplier > xQueryDefsSupp( getDataSource(), UNO_QUERY );
1257 0 : if ( xQueryDefsSupp.is() )
1258 0 : xElements = xQueryDefsSupp->getQueryDefinitions();
1259 0 : }
1260 : }
1261 :
1262 : OSL_ENSURE( xElements.is(), "OQueryController::getObjectContainer: unable to obtain the container!" );
1263 0 : return xElements;
1264 : }
1265 :
1266 : // -----------------------------------------------------------------------------
1267 0 : void OQueryController::executeQuery()
1268 : {
1269 : // we don't need to check the connection here because we already check the composer
1270 : // which can't live without his connection
1271 0 : ::rtl::OUString sTranslatedStmt = translateStatement( false );
1272 :
1273 0 : ::rtl::OUString sDataSourceName = getDataSourceName();
1274 0 : if ( !(sDataSourceName.isEmpty() || sTranslatedStmt.isEmpty()) )
1275 : {
1276 : try
1277 : {
1278 0 : getContainer()->showPreview( getFrame() );
1279 0 : InvalidateFeature(SID_DB_QUERY_PREVIEW);
1280 :
1281 0 : URL aWantToDispatch;
1282 0 : aWantToDispatch.Complete = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".component:DB/DataSourceBrowser"));
1283 :
1284 0 : ::rtl::OUString sFrameName( FRAME_NAME_QUERY_PREVIEW );
1285 0 : sal_Int32 nSearchFlags = FrameSearchFlag::CHILDREN;
1286 :
1287 0 : Reference< XDispatch> xDisp;
1288 0 : Reference< XDispatchProvider> xProv( getFrame()->findFrame( sFrameName, nSearchFlags ), UNO_QUERY );
1289 0 : if(!xProv.is())
1290 : {
1291 0 : xProv.set( getFrame(), UNO_QUERY );
1292 0 : if (xProv.is())
1293 0 : xDisp = xProv->queryDispatch(aWantToDispatch, sFrameName, nSearchFlags);
1294 : }
1295 : else
1296 : {
1297 0 : xDisp = xProv->queryDispatch(aWantToDispatch, sFrameName, FrameSearchFlag::SELF);
1298 : }
1299 0 : if (xDisp.is())
1300 : {
1301 0 : Sequence< PropertyValue> aProps(9);
1302 0 : aProps[0].Name = PROPERTY_DATASOURCENAME;
1303 0 : aProps[0].Value <<= sDataSourceName;
1304 :
1305 0 : aProps[1].Name = PROPERTY_COMMAND_TYPE;
1306 0 : aProps[1].Value <<= CommandType::COMMAND;
1307 :
1308 0 : aProps[2].Name = PROPERTY_COMMAND;
1309 0 : aProps[2].Value <<= sTranslatedStmt;
1310 :
1311 0 : aProps[3].Name = PROPERTY_ENABLE_BROWSER;
1312 0 : aProps[3].Value = ::cppu::bool2any(sal_False);
1313 :
1314 0 : aProps[4].Name = PROPERTY_ACTIVE_CONNECTION;
1315 0 : aProps[4].Value <<= getConnection();
1316 :
1317 0 : aProps[5].Name = PROPERTY_UPDATE_CATALOGNAME;
1318 0 : aProps[5].Value <<= m_sUpdateCatalogName;
1319 :
1320 0 : aProps[6].Name = PROPERTY_UPDATE_SCHEMANAME;
1321 0 : aProps[6].Value <<= m_sUpdateSchemaName;
1322 :
1323 0 : aProps[7].Name = PROPERTY_UPDATE_TABLENAME;
1324 0 : aProps[7].Value <<= m_sUpdateTableName;
1325 :
1326 0 : aProps[8].Name = PROPERTY_ESCAPE_PROCESSING;
1327 0 : aProps[8].Value = ::cppu::bool2any(m_bEscapeProcessing);
1328 :
1329 0 : xDisp->dispatch(aWantToDispatch, aProps);
1330 : // check the state of the beamer
1331 : // be notified when the beamer frame is closed
1332 0 : Reference< XComponent > xComponent( getFrame()->findFrame( sFrameName, nSearchFlags ), UNO_QUERY );
1333 0 : if (xComponent.is())
1334 : {
1335 : OSL_ENSURE(Reference< XFrame >(xComponent, UNO_QUERY).get() == getContainer()->getPreviewFrame().get(),
1336 : "OQueryController::executeQuery: oops ... which window do I have here?");
1337 0 : Reference< XEventListener> xEvtL((::cppu::OWeakObject*)this,UNO_QUERY);
1338 0 : xComponent->addEventListener(xEvtL);
1339 0 : }
1340 : }
1341 : else
1342 : {
1343 : OSL_FAIL("Couldn't create a beamer window!");
1344 0 : }
1345 : }
1346 0 : catch(const Exception&)
1347 : {
1348 : OSL_FAIL("Couldn't create a beamer window!");
1349 : }
1350 0 : }
1351 0 : }
1352 : // -----------------------------------------------------------------------------
1353 0 : sal_Bool OQueryController::askForNewName(const Reference<XNameAccess>& _xElements,sal_Bool _bSaveAs)
1354 : {
1355 : OSL_ENSURE( !editingCommand(), "OQueryController::askForNewName: not to be called when designing an independent statement!" );
1356 0 : if ( editingCommand() )
1357 0 : return sal_False;
1358 :
1359 : OSL_PRECOND( _xElements.is(), "OQueryController::askForNewName: invalid container!" );
1360 0 : if ( !_xElements.is() )
1361 0 : return sal_False;
1362 :
1363 0 : sal_Bool bRet = sal_True;
1364 0 : sal_Bool bNew = _bSaveAs || !_xElements->hasByName( m_sName );
1365 0 : if(bNew)
1366 : {
1367 0 : String aDefaultName;
1368 0 : if ( ( _bSaveAs && !bNew ) || ( bNew && !m_sName.isEmpty() ) )
1369 0 : aDefaultName = String( m_sName );
1370 : else
1371 : {
1372 0 : String sName = String( ModuleRes( editingView() ? STR_VIEW_TITLE : STR_QRY_TITLE ) );
1373 0 : aDefaultName = sName.GetToken(0,' ');
1374 0 : aDefaultName = ::dbtools::createUniqueName(_xElements,aDefaultName);
1375 : }
1376 :
1377 0 : DynamicTableOrQueryNameCheck aNameChecker( getConnection(), CommandType::QUERY );
1378 : OSaveAsDlg aDlg(
1379 0 : getView(),
1380 : m_nCommandType,
1381 : comphelper::getComponentContext(getORB()),
1382 0 : getConnection(),
1383 : aDefaultName,
1384 : aNameChecker,
1385 0 : SAD_DEFAULT );
1386 :
1387 0 : bRet = ( aDlg.Execute() == RET_OK );
1388 0 : if ( bRet )
1389 : {
1390 0 : m_sName = aDlg.getName();
1391 0 : if ( editingView() )
1392 : {
1393 0 : m_sUpdateCatalogName = aDlg.getCatalog();
1394 0 : m_sUpdateSchemaName = aDlg.getSchema();
1395 : }
1396 0 : }
1397 : }
1398 0 : return bRet;
1399 : }
1400 : // -----------------------------------------------------------------------------
1401 0 : bool OQueryController::doSaveAsDoc(sal_Bool _bSaveAs)
1402 : {
1403 : OSL_ENSURE(isEditable(),"Slot ID_BROWSER_SAVEDOC should not be enabled!");
1404 0 : if ( !editingCommand() && !haveDataSource() )
1405 : {
1406 0 : String aMessage(ModuleRes(STR_DATASOURCE_DELETED));
1407 0 : OSQLWarningBox( getView(), aMessage ).Execute();
1408 0 : return false;
1409 : }
1410 :
1411 0 : Reference< XNameAccess > xElements = getObjectContainer();
1412 0 : if ( !xElements.is() )
1413 0 : return false;
1414 :
1415 0 : if ( !getContainer()->checkStatement() )
1416 0 : return false;
1417 :
1418 0 : ::rtl::OUString sTranslatedStmt = translateStatement();
1419 0 : if ( editingCommand() )
1420 : {
1421 0 : setModified( sal_False );
1422 : // this is all we need to do here. translateStatement implicitly set our m_sStatement, and
1423 : // notified it, and that's all
1424 0 : return true;
1425 : }
1426 :
1427 0 : if ( sTranslatedStmt.isEmpty() )
1428 0 : return false;
1429 :
1430 : // first we need a name for our query so ask the user
1431 : // did we get a name
1432 0 : ::rtl::OUString sOriginalName( m_sName );
1433 0 : if ( !askForNewName( xElements, _bSaveAs ) || m_sName.isEmpty() )
1434 0 : return false;
1435 :
1436 0 : SQLExceptionInfo aInfo;
1437 0 : bool bSuccess = false;
1438 0 : bool bNew = false;
1439 : try
1440 : {
1441 : bNew = ( _bSaveAs )
1442 0 : || ( !xElements->hasByName( m_sName ) );
1443 :
1444 0 : Reference<XPropertySet> xQuery;
1445 0 : if ( bNew ) // just to make sure the query already exists
1446 : {
1447 : // drop the query, in case it already exists
1448 0 : if ( xElements->hasByName( m_sName ) )
1449 : {
1450 0 : Reference< XDrop > xNameCont( xElements, UNO_QUERY );
1451 0 : if ( xNameCont.is() )
1452 0 : xNameCont->dropByName( m_sName );
1453 : else
1454 : {
1455 0 : Reference< XNameContainer > xCont( xElements, UNO_QUERY );
1456 0 : if ( xCont.is() )
1457 0 : xCont->removeByName( m_sName );
1458 0 : }
1459 : }
1460 :
1461 : // create a new (empty, uninitialized) query resp. view
1462 0 : Reference< XDataDescriptorFactory > xFact( xElements, UNO_QUERY );
1463 0 : if ( xFact.is() )
1464 : {
1465 0 : xQuery = xFact->createDataDescriptor();
1466 : // to set the name is only allowed when the query is new
1467 0 : xQuery->setPropertyValue( PROPERTY_NAME, makeAny( m_sName ) );
1468 : }
1469 : else
1470 : {
1471 0 : Reference< XSingleServiceFactory > xSingleFac( xElements, UNO_QUERY );
1472 0 : if ( xSingleFac.is() )
1473 0 : xQuery = xQuery.query( xSingleFac->createInstance() );
1474 0 : }
1475 : }
1476 : else
1477 : {
1478 0 : xElements->getByName( m_sName ) >>= xQuery;
1479 : }
1480 0 : if ( !xQuery.is() )
1481 0 : throw RuntimeException();
1482 :
1483 : // the new commands
1484 0 : if ( editingView() && !bNew )
1485 : {
1486 : OSL_ENSURE( xQuery == m_xAlterView, "OQueryController::doSaveAsDoc: already have another alterable view ...!?" );
1487 0 : m_xAlterView.set( xQuery, UNO_QUERY_THROW );
1488 0 : m_xAlterView->alterCommand( sTranslatedStmt );
1489 : }
1490 : else
1491 : { // we're creating a query, or a *new* view
1492 0 : xQuery->setPropertyValue( PROPERTY_COMMAND, makeAny( sTranslatedStmt ) );
1493 :
1494 0 : if ( editingView() )
1495 : {
1496 0 : xQuery->setPropertyValue( PROPERTY_CATALOGNAME, makeAny( m_sUpdateCatalogName ) );
1497 0 : xQuery->setPropertyValue( PROPERTY_SCHEMANAME, makeAny( m_sUpdateSchemaName ) );
1498 : }
1499 :
1500 0 : if ( editingQuery() )
1501 : {
1502 0 : xQuery->setPropertyValue( PROPERTY_UPDATE_TABLENAME, makeAny( m_sUpdateTableName ) );
1503 0 : xQuery->setPropertyValue( PROPERTY_ESCAPE_PROCESSING,::cppu::bool2any( m_bEscapeProcessing ) );
1504 :
1505 0 : xQuery->setPropertyValue( PROPERTY_LAYOUTINFORMATION, getViewData() );
1506 : }
1507 : }
1508 :
1509 0 : if ( bNew )
1510 : {
1511 0 : Reference< XAppend > xAppend( xElements, UNO_QUERY );
1512 0 : if ( xAppend.is() )
1513 : {
1514 0 : xAppend->appendByDescriptor( xQuery );
1515 : }
1516 : else
1517 : {
1518 0 : Reference< XNameContainer > xCont( xElements, UNO_QUERY );
1519 0 : if ( xCont.is() )
1520 0 : xCont->insertByName( m_sName, makeAny( xQuery ) );
1521 : }
1522 :
1523 0 : if ( editingView() )
1524 : {
1525 0 : Reference< XPropertySet > xViewProps;
1526 0 : if ( xElements->hasByName( m_sName ) )
1527 0 : xViewProps.set( xElements->getByName( m_sName ), UNO_QUERY );
1528 :
1529 0 : if ( !xViewProps.is() ) // correct name and try again
1530 0 : m_sName = ::dbtools::composeTableName( getMetaData(), xQuery, ::dbtools::eInDataManipulation, false, false, false );
1531 :
1532 : OSL_ENSURE( xElements->hasByName( m_sName ), "OQueryController::doSaveAsDoc: newly creaed view does not exist!" );
1533 :
1534 0 : if ( xElements->hasByName( m_sName ) )
1535 0 : m_xAlterView.set( xElements->getByName( m_sName ), UNO_QUERY );
1536 :
1537 : // now check if our datasource has set a tablefilter and if so, append the new table name to it
1538 0 : ::dbaui::appendToFilter( getConnection(), m_sName, comphelper::getComponentContext(getORB()), getView() );
1539 : }
1540 0 : Reference< XTitleChangeListener> xEventListener(impl_getTitleHelper_throw(),UNO_QUERY);
1541 0 : if ( xEventListener.is() )
1542 : {
1543 0 : TitleChangedEvent aEvent;
1544 0 : xEventListener->titleChanged(aEvent);
1545 : }
1546 0 : releaseNumberForComponent();
1547 : }
1548 :
1549 0 : setModified( sal_False );
1550 0 : bSuccess = true;
1551 :
1552 : }
1553 0 : catch(const SQLException&)
1554 : {
1555 0 : if ( !bNew )
1556 0 : m_sName = sOriginalName;
1557 0 : aInfo = SQLExceptionInfo( ::cppu::getCaughtException() );
1558 : }
1559 0 : catch(const Exception&)
1560 : {
1561 0 : if ( !bNew )
1562 0 : m_sName = sOriginalName;
1563 : DBG_UNHANDLED_EXCEPTION();
1564 : }
1565 :
1566 0 : showError( aInfo );
1567 :
1568 : // update the title of our window
1569 : //updateTitle();
1570 :
1571 : // if we successfully saved a view we were creating, then close the designer
1572 0 : if ( bSuccess && editingView() && !m_xAlterView.is() )
1573 : {
1574 0 : closeTask();
1575 : }
1576 :
1577 0 : if ( bSuccess && editingView() )
1578 0 : InvalidateFeature( ID_BROWSER_EDITDOC );
1579 :
1580 0 : return bSuccess;
1581 : }
1582 : //-----------------------------------------------------------------------------
1583 :
1584 : namespace {
1585 0 : struct CommentStrip
1586 : {
1587 : ::rtl::OUString maComment;
1588 : bool mbLastOnLine;
1589 0 : CommentStrip( const ::rtl::OUString& rComment, bool bLastOnLine )
1590 0 : : maComment( rComment), mbLastOnLine( bLastOnLine) {}
1591 : };
1592 : }
1593 :
1594 : /** Obtain all comments in a query.
1595 :
1596 : See also delComment() implementation for OSQLParser::parseTree().
1597 : */
1598 0 : static ::std::vector< CommentStrip > getComment( const ::rtl::OUString& rQuery )
1599 : {
1600 0 : ::std::vector< CommentStrip > aRet;
1601 : // First a quick search if there is any "--" or "//" or "/*", if not then
1602 : // the whole copying loop is pointless.
1603 0 : if (rQuery.indexOfAsciiL( "--", 2, 0) < 0 && rQuery.indexOfAsciiL( "//", 2, 0) < 0 &&
1604 0 : rQuery.indexOfAsciiL( "/*", 2, 0) < 0)
1605 : return aRet;
1606 :
1607 0 : const sal_Unicode* pCopy = rQuery.getStr();
1608 0 : const sal_Int32 nQueryLen = rQuery.getLength();
1609 0 : bool bIsText1 = false; // "text"
1610 0 : bool bIsText2 = false; // 'text'
1611 0 : bool bComment2 = false; // /* comment */
1612 0 : bool bComment = false; // -- or // comment
1613 0 : ::rtl::OUStringBuffer aBuf;
1614 0 : for (sal_Int32 i=0; i < nQueryLen; ++i)
1615 : {
1616 0 : if (bComment2)
1617 : {
1618 0 : aBuf.append( &pCopy[i], 1);
1619 0 : if ((i+1) < nQueryLen)
1620 : {
1621 0 : if (pCopy[i]=='*' && pCopy[i+1]=='/')
1622 : {
1623 0 : bComment2 = false;
1624 0 : aBuf.append( &pCopy[++i], 1);
1625 0 : aRet.push_back( CommentStrip( aBuf.makeStringAndClear(), false));
1626 : }
1627 : }
1628 : else
1629 : {
1630 : // comment can't close anymore, actually an error, but..
1631 0 : aRet.push_back( CommentStrip( aBuf.makeStringAndClear(), false));
1632 : }
1633 0 : continue;
1634 : }
1635 0 : if (pCopy[i] == '\n' || i == nQueryLen-1)
1636 : {
1637 0 : if (bComment)
1638 : {
1639 0 : if (i == nQueryLen-1 && pCopy[i] != '\n')
1640 0 : aBuf.append( &pCopy[i], 1);
1641 0 : aRet.push_back( CommentStrip( aBuf.makeStringAndClear(), true));
1642 0 : bComment = false;
1643 : }
1644 0 : else if (!aRet.empty())
1645 0 : aRet.back().mbLastOnLine = true;
1646 : }
1647 0 : else if (!bComment)
1648 : {
1649 0 : if (pCopy[i] == '\"' && !bIsText2)
1650 0 : bIsText1 = !bIsText1;
1651 0 : else if (pCopy[i] == '\'' && !bIsText1)
1652 0 : bIsText2 = !bIsText2;
1653 0 : if (!bIsText1 && !bIsText2 && (i+1) < nQueryLen)
1654 : {
1655 0 : if ((pCopy[i]=='-' && pCopy[i+1]=='-') || (pCopy[i]=='/' && pCopy[i+1]=='/'))
1656 0 : bComment = true;
1657 0 : else if ((pCopy[i]=='/' && pCopy[i+1]=='*'))
1658 0 : bComment2 = true;
1659 : }
1660 : }
1661 0 : if (bComment || bComment2)
1662 0 : aBuf.append( &pCopy[i], 1);
1663 : }
1664 0 : return aRet;
1665 : }
1666 : //------------------------------------------------------------------------------
1667 :
1668 : /** Concat/insert comments that were previously obtained with getComment().
1669 :
1670 : NOTE: The current parser implementation does not preserve newlines, so all
1671 : comments are always appended to the entire query, also inline comments
1672 : that would need positioning anyway that can't be obtained after
1673 : recomposition. This is ugly but at least allows commented queries while
1674 : preserving the comments _somehow_.
1675 : */
1676 0 : static ::rtl::OUString concatComment( const ::rtl::OUString& rQuery, const ::std::vector< CommentStrip >& rComments )
1677 : {
1678 : // No comments => return query.
1679 0 : if (rComments.empty())
1680 0 : return rQuery;
1681 :
1682 0 : const sal_Unicode* pBeg = rQuery.getStr();
1683 0 : const sal_Int32 nLen = rQuery.getLength();
1684 0 : const size_t nComments = rComments.size();
1685 : // Obtaining the needed size once should be faster than reallocating.
1686 : // Also add a blank or linefeed for each comment.
1687 0 : sal_Int32 nBufSize = nLen + nComments;
1688 0 : for (::std::vector< CommentStrip >::const_iterator it( rComments.begin()); it != rComments.end(); ++it)
1689 0 : nBufSize += (*it).maComment.getLength();
1690 0 : ::rtl::OUStringBuffer aBuf( nBufSize );
1691 0 : sal_Int32 nIndBeg = 0;
1692 0 : sal_Int32 nIndLF = rQuery.indexOf('\n');
1693 0 : size_t i = 0;
1694 0 : while (nIndLF >= 0 && i < nComments)
1695 : {
1696 0 : aBuf.append( pBeg + nIndBeg, nIndLF - nIndBeg);
1697 0 : do
1698 : {
1699 0 : aBuf.append( rComments[i].maComment);
1700 0 : } while (!rComments[i++].mbLastOnLine && i < nComments);
1701 0 : aBuf.append( pBeg + nIndLF, 1); // the LF
1702 0 : nIndBeg = nIndLF + 1;
1703 0 : nIndLF = (nIndBeg < nLen ? rQuery.indexOf( '\n', nIndBeg) : -1);
1704 : }
1705 : // Append remainder of query.
1706 0 : if (nIndBeg < nLen)
1707 0 : aBuf.append( pBeg + nIndBeg, nLen - nIndBeg);
1708 : // Append all remaining comments, preserve lines.
1709 0 : bool bNewLine = false;
1710 0 : for ( ; i < nComments; ++i)
1711 : {
1712 0 : if (!bNewLine)
1713 0 : aBuf.append( sal_Unicode(' '));
1714 0 : aBuf.append( rComments[i].maComment);
1715 0 : if (rComments[i].mbLastOnLine)
1716 : {
1717 0 : aBuf.append( sal_Unicode('\n'));
1718 0 : bNewLine = true;
1719 : }
1720 : else
1721 0 : bNewLine = false;
1722 : }
1723 0 : return aBuf.makeStringAndClear();
1724 : }
1725 : // -----------------------------------------------------------------------------
1726 0 : ::rtl::OUString OQueryController::translateStatement( bool _bFireStatementChange )
1727 : {
1728 : // now set the properties
1729 0 : setStatement_fireEvent( getContainer()->getStatement(), _bFireStatementChange );
1730 0 : ::rtl::OUString sTranslatedStmt;
1731 0 : if(!m_sStatement.isEmpty() && m_xComposer.is() && m_bEscapeProcessing)
1732 : {
1733 : try
1734 : {
1735 0 : ::rtl::OUString aErrorMsg;
1736 :
1737 0 : ::std::vector< CommentStrip > aComments = getComment( m_sStatement);
1738 :
1739 0 : ::connectivity::OSQLParseNode* pNode = m_aSqlParser.parseTree( aErrorMsg, m_sStatement, m_bGraphicalDesign );
1740 0 : if(pNode)
1741 : {
1742 0 : pNode->parseNodeToStr( sTranslatedStmt, getConnection() );
1743 0 : delete pNode;
1744 : }
1745 :
1746 0 : m_xComposer->setQuery(sTranslatedStmt);
1747 0 : sTranslatedStmt = m_xComposer->getComposedQuery();
1748 0 : sTranslatedStmt = concatComment( sTranslatedStmt, aComments);
1749 : }
1750 0 : catch(const SQLException& e)
1751 : {
1752 0 : ::dbtools::SQLExceptionInfo aInfo(e);
1753 0 : showError(aInfo);
1754 : // an error occurred so we clear the statement
1755 0 : sTranslatedStmt = ::rtl::OUString();
1756 : }
1757 : }
1758 0 : else if(m_sStatement.isEmpty())
1759 : {
1760 0 : ModuleRes aModuleRes(STR_QRY_NOSELECT);
1761 0 : String sTmpStr(aModuleRes);
1762 0 : ::rtl::OUString sError(sTmpStr);
1763 0 : showError(SQLException(sError,NULL,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000") ),1000,Any()));
1764 : }
1765 : else
1766 0 : sTranslatedStmt = m_sStatement;
1767 :
1768 0 : return sTranslatedStmt;
1769 : }
1770 : // -----------------------------------------------------------------------------
1771 0 : short OQueryController::saveModified()
1772 : {
1773 0 : SolarMutexGuard aSolarGuard;
1774 0 : ::osl::MutexGuard aGuard( getMutex() );
1775 0 : short nRet = RET_YES;
1776 0 : if ( !isConnected() || !isModified() )
1777 0 : return nRet;
1778 :
1779 0 : if ( !m_bGraphicalDesign
1780 0 : || ( !m_vTableFieldDesc.empty()
1781 0 : && !m_vTableData.empty()
1782 : )
1783 : )
1784 : {
1785 0 : String sMessageText( lcl_getObjectResourceString( STR_QUERY_SAVEMODIFIED, m_nCommandType ) );
1786 0 : QueryBox aQry( getView(), WB_YES_NO_CANCEL | WB_DEF_YES, sMessageText );
1787 :
1788 0 : nRet = aQry.Execute();
1789 0 : if ( ( nRet == RET_YES )
1790 0 : && !doSaveAsDoc( sal_False )
1791 : )
1792 : {
1793 0 : nRet = RET_CANCEL;
1794 0 : }
1795 : }
1796 0 : return nRet;
1797 : }
1798 : // -----------------------------------------------------------------------------
1799 0 : void OQueryController::impl_reset( const bool i_bForceCurrentControllerSettings )
1800 : {
1801 0 : bool bValid = false;
1802 :
1803 0 : Sequence< PropertyValue > aLayoutInformation;
1804 : // get command from the query if a query name was supplied
1805 0 : if ( !i_bForceCurrentControllerSettings && !editingCommand() )
1806 : {
1807 0 : if ( !m_sName.isEmpty() )
1808 : {
1809 0 : Reference< XNameAccess > xQueries = getObjectContainer();
1810 0 : if ( xQueries.is() )
1811 : {
1812 0 : Reference< XPropertySet > xProp;
1813 0 : if( xQueries->hasByName( m_sName ) && ( xQueries->getByName( m_sName ) >>= xProp ) && xProp.is() )
1814 : {
1815 0 : ::rtl::OUString sNewStatement;
1816 0 : xProp->getPropertyValue( PROPERTY_COMMAND ) >>= sNewStatement;
1817 0 : setStatement_fireEvent( sNewStatement );
1818 :
1819 0 : sal_Bool bNewEscapeProcessing( sal_True );
1820 0 : if ( editingQuery() )
1821 : {
1822 0 : xProp->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bNewEscapeProcessing;
1823 0 : setEscapeProcessing_fireEvent( bNewEscapeProcessing );
1824 : }
1825 :
1826 0 : m_bGraphicalDesign = m_bGraphicalDesign && m_bEscapeProcessing;
1827 0 : bValid = true;
1828 :
1829 : try
1830 : {
1831 0 : if ( editingQuery() )
1832 0 : xProp->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) >>= aLayoutInformation;
1833 : }
1834 0 : catch( const Exception& )
1835 : {
1836 : OSL_FAIL( "OQueryController::impl_reset: could not retrieve the layout information from the query!" );
1837 0 : }
1838 0 : }
1839 0 : }
1840 : }
1841 : }
1842 : else
1843 : {
1844 0 : bValid = true;
1845 : // assume that we got all necessary information during initialization
1846 : }
1847 :
1848 0 : if ( bValid )
1849 : {
1850 : // load the layoutInformation
1851 0 : if ( aLayoutInformation.getLength() )
1852 : {
1853 : try
1854 : {
1855 0 : loadViewSettings( aLayoutInformation );
1856 : }
1857 0 : catch( const Exception& )
1858 : {
1859 : DBG_UNHANDLED_EXCEPTION();
1860 : }
1861 : }
1862 :
1863 0 : if ( !m_sStatement.isEmpty() )
1864 : {
1865 0 : setQueryComposer();
1866 :
1867 0 : bool bError( false );
1868 :
1869 0 : if ( !m_pSqlIterator )
1870 : {
1871 0 : bError = true;
1872 : }
1873 0 : else if ( m_bEscapeProcessing )
1874 : {
1875 0 : ::rtl::OUString aErrorMsg;
1876 : ::std::auto_ptr< ::connectivity::OSQLParseNode > pNode(
1877 0 : m_aSqlParser.parseTree( aErrorMsg, m_sStatement, m_bGraphicalDesign ) );
1878 :
1879 0 : if ( pNode.get() )
1880 : {
1881 0 : delete m_pSqlIterator->getParseTree();
1882 0 : m_pSqlIterator->setParseTree( pNode.release() );
1883 0 : m_pSqlIterator->traverseAll();
1884 0 : if ( m_pSqlIterator->hasErrors() )
1885 : {
1886 0 : if ( !i_bForceCurrentControllerSettings && m_bGraphicalDesign && !editingView() )
1887 : {
1888 0 : impl_showAutoSQLViewError( makeAny( m_pSqlIterator->getErrors() ) );
1889 : }
1890 0 : bError = true;
1891 : }
1892 : }
1893 : else
1894 : {
1895 0 : if ( !i_bForceCurrentControllerSettings && !editingView() )
1896 : {
1897 0 : String aTitle(ModuleRes(STR_SVT_SQL_SYNTAX_ERROR));
1898 0 : OSQLMessageBox aDlg(getView(),aTitle,aErrorMsg);
1899 0 : aDlg.Execute();
1900 : }
1901 0 : bError = true;
1902 0 : }
1903 : }
1904 :
1905 0 : if ( bError )
1906 : {
1907 0 : m_bGraphicalDesign = sal_False;
1908 0 : if ( editingView() )
1909 : // if we're editing a view whose statement could not be parsed, default to "no escape processing"
1910 0 : setEscapeProcessing_fireEvent( sal_False );
1911 : }
1912 : }
1913 : }
1914 :
1915 0 : if(!m_pSqlIterator)
1916 0 : setQueryComposer();
1917 : OSL_ENSURE(m_pSqlIterator,"No SQLIterator set!");
1918 :
1919 0 : getContainer()->setNoneVisbleRow(m_nVisibleRows);
1920 0 : }
1921 :
1922 : // -----------------------------------------------------------------------------
1923 0 : void OQueryController::reset()
1924 : {
1925 0 : impl_reset();
1926 0 : getContainer()->reset( NULL );
1927 0 : ClearUndoManager();
1928 0 : }
1929 :
1930 : // -----------------------------------------------------------------------------
1931 0 : void OQueryController::setStatement_fireEvent( const ::rtl::OUString& _rNewStatement, bool _bFireStatementChange )
1932 : {
1933 0 : Any aOldValue = makeAny( m_sStatement );
1934 0 : m_sStatement = _rNewStatement;
1935 0 : Any aNewValue = makeAny( m_sStatement );
1936 :
1937 0 : sal_Int32 nHandle = PROPERTY_ID_ACTIVECOMMAND;
1938 0 : if ( _bFireStatementChange )
1939 0 : fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False );
1940 0 : }
1941 :
1942 : // -----------------------------------------------------------------------------
1943 0 : void OQueryController::setEscapeProcessing_fireEvent( const sal_Bool _bEscapeProcessing )
1944 : {
1945 0 : if ( _bEscapeProcessing == m_bEscapeProcessing )
1946 0 : return;
1947 :
1948 0 : Any aOldValue = makeAny( m_bEscapeProcessing );
1949 0 : m_bEscapeProcessing = _bEscapeProcessing;
1950 0 : Any aNewValue = makeAny( m_bEscapeProcessing );
1951 :
1952 0 : sal_Int32 nHandle = PROPERTY_ID_ESCAPE_PROCESSING;
1953 0 : fire( &nHandle, &aNewValue, &aOldValue, 1, sal_False );
1954 : }
1955 :
1956 : // -----------------------------------------------------------------------------
1957 0 : IMPL_LINK( OQueryController, OnExecuteAddTable, void*, /*pNotInterestedIn*/ )
1958 : {
1959 0 : Execute( ID_BROWSER_ADDTABLE,Sequence<PropertyValue>() );
1960 0 : return 0L;
1961 : }
1962 :
1963 : // -----------------------------------------------------------------------------
1964 0 : bool OQueryController::allowViews() const
1965 : {
1966 0 : return true;
1967 : }
1968 :
1969 : // -----------------------------------------------------------------------------
1970 0 : bool OQueryController::allowQueries() const
1971 : {
1972 : OSL_ENSURE( getSdbMetaData().isConnected(), "OQueryController::allowQueries: illegal call!" );
1973 0 : if ( !getSdbMetaData().supportsSubqueriesInFrom() )
1974 0 : return false;
1975 :
1976 0 : const NamedValueCollection& rArguments( getInitParams() );
1977 0 : sal_Int32 nCommandType = rArguments.getOrDefault( (::rtl::OUString)PROPERTY_COMMAND_TYPE, (sal_Int32)CommandType::QUERY );
1978 0 : sal_Bool bCreatingView = ( nCommandType == CommandType::TABLE );
1979 0 : return !bCreatingView;
1980 : }
1981 :
1982 : // -----------------------------------------------------------------------------
1983 0 : Any SAL_CALL OQueryController::getViewData() throw( RuntimeException )
1984 : {
1985 0 : ::osl::MutexGuard aGuard( getMutex() );
1986 :
1987 0 : getContainer()->SaveUIConfig();
1988 :
1989 0 : ::comphelper::NamedValueCollection aViewSettings;
1990 0 : saveViewSettings( aViewSettings, false );
1991 :
1992 0 : return makeAny( aViewSettings.getPropertyValues() );
1993 : }
1994 : // -----------------------------------------------------------------------------
1995 0 : void SAL_CALL OQueryController::restoreViewData(const Any& /*Data*/) throw( RuntimeException )
1996 : {
1997 : // TODO
1998 0 : }
1999 :
2000 : // -----------------------------------------------------------------------------
2001 : } // namespace dbaui
2002 : // -----------------------------------------------------------------------------
2003 :
2004 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|