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