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