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