1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26 #ifndef DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
27 #include "SelectionBrowseBox.hxx"
28 #endif
29 #ifndef _COM_SUN_STAR_SDBC_XDATABASEMETADATA_HPP_
30 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
31 #endif
32 #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_
33 #include <com/sun/star/sdbc/DataType.hpp>
34 #endif
35 #ifndef DBAUI_QUERYDESIGNVIEW_HXX
36 #include "QueryDesignView.hxx"
37 #endif
38 #ifndef DBAUI_QUERYCONTROLLER_HXX
39 #include "querycontroller.hxx"
40 #endif
41 #ifndef DBAUI_QUERYTABLEVIEW_HXX
42 #include "QueryTableView.hxx"
43 #endif
44 #ifndef DBACCESS_UI_BROWSER_ID_HXX
45 #include "browserids.hxx"
46 #endif
47 #ifndef _COMPHELPER_TYPES_HXX_
48 #include <comphelper/types.hxx>
49 #endif
50 #ifndef DBAUI_TABLEFIELDINFO_HXX
51 #include "TableFieldInfo.hxx"
52 #endif
53 #ifndef _DBU_QRY_HRC_
54 #include "dbu_qry.hrc"
55 #endif
56 #ifndef _DBA_DBACCESS_HELPID_HRC_
57 #include "dbaccess_helpid.hrc"
58 #endif
59 #ifndef _TOOLS_DEBUG_HXX
60 #include <tools/debug.hxx>
61 #endif
62 #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
63 #include <com/sun/star/container/XNameAccess.hpp>
64 #endif
65 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
66 #include "dbustrings.hrc"
67 #endif
68 #ifndef DBAUI_QUERY_TABLEWINDOW_HXX
69 #include "QTableWindow.hxx"
70 #endif
71 #ifndef DBAUI_QUERYTABLEVIEW_HXX
72 #include "QueryTableView.hxx"
73 #endif
74 #ifndef _SV_MSGBOX_HXX
75 #include <vcl/msgbox.hxx>
76 #endif
77 #ifndef DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
78 #include "QueryDesignFieldUndoAct.hxx"
79 #endif
80 #ifndef _SVX_DBEXCH_HRC
81 #include <svx/dbexch.hrc>
82 #endif
83 #ifndef _COMPHELPER_STLTYPES_HXX_
84 #include <comphelper/stl_types.hxx>
85 #endif
86 #ifndef _COMPHELPER_EXTRACT_HXX_
87 #include <comphelper/extract.hxx>
88 #endif
89 #ifndef _DBAUI_SQLMESSAGE_HXX_
90 #include "sqlmessage.hxx"
91 #endif
92 #ifndef DBAUI_TOOLS_HXX
93 #include "UITools.hxx"
94 #endif
95 
96 using namespace ::svt;
97 using namespace ::dbaui;
98 using namespace ::connectivity;
99 using namespace ::com::sun::star::uno;
100 using namespace ::com::sun::star::sdbc;
101 using namespace ::com::sun::star::beans;
102 using namespace ::com::sun::star::container;
103 using namespace ::com::sun::star::util;
104 using namespace ::com::sun::star::accessibility;
105 
106 const String g_strOne = String::CreateFromAscii("1");
107 const String g_strZero = String::CreateFromAscii("0");
108 
109 #define DEFAULT_QUERY_COLS	20
110 #define DEFAULT_SIZE		GetTextWidth(g_strZero) * 30
111 #define CHECKBOX_SIZE		10
112 #define HANDLE_ID			 0
113 #define HANDLE_COLUMN_WITDH	70
114 
115 #define SQL_ISRULEOR2(pParseNode, e1,e2) 	((pParseNode)->isRule() && (\
116 											(pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \
117 											(pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2)))
118 
119 
120 // -----------------------------------------------------------------------------
121 namespace
122 {
isFieldNameAsterix(const::rtl::OUString & _sFieldName)123 	sal_Bool isFieldNameAsterix(const ::rtl::OUString& _sFieldName )
124 	{
125 		sal_Bool bAsterix = !(_sFieldName.getLength() && _sFieldName.toChar() != '*');
126 		if ( !bAsterix )
127 		{
128 			String sName = _sFieldName;
129 			xub_StrLen nTokenCount = sName.GetTokenCount('.');
130 			if (	(nTokenCount == 2 && sName.GetToken(1,'.').GetChar(0) == '*' )
131 				||	(nTokenCount == 3 && sName.GetToken(2,'.').GetChar(0) == '*' ) )
132 			{
133 				bAsterix = sal_True;
134 			}
135 		}
136 		return bAsterix;
137 	}
138 	// -----------------------------------------------------------------------------
lcl_SupportsCoreSQLGrammar(const Reference<XConnection> & _xConnection)139 	sal_Bool lcl_SupportsCoreSQLGrammar(const Reference< XConnection>& _xConnection)
140 	{
141 		sal_Bool bSupportsCoreGrammar = sal_False;
142 		if ( _xConnection.is() )
143 		{
144 			try
145 			{
146 				Reference< XDatabaseMetaData >  xMetaData = _xConnection->getMetaData();
147 				bSupportsCoreGrammar = xMetaData.is() && xMetaData->supportsCoreSQLGrammar();
148 			}
149 			catch(Exception&)
150 			{
151 			}
152 		}
153 		return bSupportsCoreGrammar;
154 	}
155 }
156 
DBG_NAME(OSelectionBrowseBox)157 DBG_NAME(OSelectionBrowseBox)
158 //------------------------------------------------------------------------------
159 OSelectionBrowseBox::OSelectionBrowseBox( Window* pParent )
160 				   :EditBrowseBox( pParent,EBBF_NOROWPICTURE, WB_3DLOOK, BROWSER_COLUMNSELECTION | BROWSER_KEEPSELECTION |  BROWSER_HIDESELECT |
161 								  BROWSER_HIDECURSOR | BROWSER_HLINESFULL | BROWSER_VLINESFULL )
162 				   ,m_aFunctionStrings(ModuleRes(STR_QUERY_FUNCTIONS))
163 				   ,m_nVisibleCount(0)
164 				   ,m_bOrderByUnRelated(sal_True)
165 				   ,m_bGroupByUnRelated(sal_True)
166 				   ,m_bStopTimer(sal_False)
167 				   ,m_bWasEditing(sal_False)
168 				   ,m_bDisableErrorBox(sal_False)
169 				   ,m_bInUndoMode(sal_False)
170 {
171 	DBG_CTOR(OSelectionBrowseBox,NULL);
172 	SetHelpId(HID_CTL_QRYDGNCRIT);
173 
174 	m_nMode =		BROWSER_COLUMNSELECTION | BROWSER_HIDESELECT
175 				|	BROWSER_KEEPSELECTION	| BROWSER_HIDECURSOR
176 				|	BROWSER_HLINESFULL		| BROWSER_VLINESFULL
177 				|	BROWSER_HEADERBAR_NEW	;
178 
179 	m_pTextCell		= new Edit(&GetDataWindow(), 0);
180 	//	m_pTextCell->EnableSpecialCheck(sal_False);
181 	m_pVisibleCell	= new CheckBoxControl(&GetDataWindow());
182 	m_pTableCell	= new ListBoxControl(&GetDataWindow());     m_pTableCell->SetDropDownLineCount( 20 );
183 	m_pFieldCell	= new ComboBoxControl(&GetDataWindow());    m_pFieldCell->SetDropDownLineCount( 20 );
184 	m_pOrderCell	= new ListBoxControl(&GetDataWindow());
185 	m_pFunctionCell	= new ListBoxControl(&GetDataWindow());     m_pFunctionCell->SetDropDownLineCount( 20 );
186 
187 	m_pVisibleCell->SetHelpId(HID_QRYDGN_ROW_VISIBLE);
188 	m_pTableCell->SetHelpId(HID_QRYDGN_ROW_TABLE);
189 	m_pFieldCell->SetHelpId(HID_QRYDGN_ROW_FIELD);
190 	m_pOrderCell->SetHelpId(HID_QRYDGN_ROW_ORDER);
191 	m_pFunctionCell->SetHelpId(HID_QRYDGN_ROW_FUNCTION);
192 
193 	//////////////////////////////////////////////////////////////////////
194 	// TriState der ::com::sun::star::form::CheckBox abschalten
195 	m_pVisibleCell->GetBox().EnableTriState( sal_False );
196 
197 //	m_pEmptyEntry = new OTableFieldDesc();
198 //	m_pEmptyEntry->SetColWidth(DEFAULT_SIZE);
199 
200 	Font aTitleFont = OutputDevice::GetDefaultFont( DEFAULTFONT_SANS_UNICODE,Window::GetSettings().GetLanguage(),DEFAULTFONT_FLAGS_ONLYONE);
201 	aTitleFont.SetSize(Size(0, 6));
202 	SetTitleFont(aTitleFont);
203 
204 	String aTxt(ModuleRes(STR_QUERY_SORTTEXT));
205 	xub_StrLen nCount = aTxt.GetTokenCount();
206 	xub_StrLen nIdx = 0;
207 	for (; nIdx < nCount; nIdx++)
208 		m_pOrderCell->InsertEntry(aTxt.GetToken(nIdx));
209 
210 	for(long i=0;i < BROW_ROW_CNT;i++)
211 		m_bVisibleRow.push_back(sal_True);
212 
213 	m_bVisibleRow[BROW_FUNCTION_ROW] = sal_False;   // zuerst ausblenden
214 
215 	m_timerInvalidate.SetTimeout(200);
216 	m_timerInvalidate.SetTimeoutHdl(LINK(this, OSelectionBrowseBox, OnInvalidateTimer));
217 	m_timerInvalidate.Start();
218 }
219 
220 //------------------------------------------------------------------------------
~OSelectionBrowseBox()221 OSelectionBrowseBox::~OSelectionBrowseBox()
222 {
223 	DBG_DTOR(OSelectionBrowseBox,NULL);
224 
225 	delete m_pTextCell;
226 	delete m_pVisibleCell;
227 	delete m_pFieldCell;
228 	delete m_pTableCell;
229 	delete m_pOrderCell;
230 	delete m_pFunctionCell;
231 }
232 // -----------------------------------------------------------------------------
initialize()233 void OSelectionBrowseBox::initialize()
234 {
235 	Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
236 	if(xConnection.is())
237 	{
238 		const IParseContext& rContext = static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext();
239 		IParseContext::InternationalKeyCode eFunctions[] = { IParseContext::KEY_AVG,IParseContext::KEY_COUNT,IParseContext::KEY_MAX
240             ,IParseContext::KEY_MIN,IParseContext::KEY_SUM
241             ,IParseContext::KEY_EVERY
242             ,IParseContext::KEY_ANY
243             ,IParseContext::KEY_SOME
244             ,IParseContext::KEY_STDDEV_POP
245             ,IParseContext::KEY_STDDEV_SAMP
246             ,IParseContext::KEY_VAR_SAMP
247             ,IParseContext::KEY_VAR_POP
248             ,IParseContext::KEY_COLLECT
249             ,IParseContext::KEY_FUSION
250             ,IParseContext::KEY_INTERSECTION
251         };
252 
253 		String sGroup = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount() - 1);
254 		m_aFunctionStrings = m_aFunctionStrings.GetToken(0);
255 
256 		for (size_t i = 0; i < sizeof(eFunctions)/sizeof(eFunctions[0]) ; ++i)
257 		{
258 			m_aFunctionStrings += String(RTL_CONSTASCII_USTRINGPARAM(";"));
259 			m_aFunctionStrings += String(ByteString(rContext.getIntlKeywordAscii(eFunctions[i])),RTL_TEXTENCODING_UTF8);
260 
261 		} // for (sal_Int32 i = 0; i < sizeof(eFunctions)/sizeof(eFunctions[0]) ; ++i)
262 		m_aFunctionStrings += String(RTL_CONSTASCII_USTRINGPARAM(";"));
263 		m_aFunctionStrings += sGroup;
264 
265 		// Diese Funktionen stehen nur unter CORE zur Verf�gung
266 		if ( lcl_SupportsCoreSQLGrammar(xConnection) )
267 		{
268 			xub_StrLen nCount	= m_aFunctionStrings.GetTokenCount();
269 			for (xub_StrLen nIdx = 0; nIdx < nCount; nIdx++)
270 				m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(nIdx));
271 		}
272 		else // sonst nur COUNT(*)
273 		{
274 			m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(0));
275 			m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(2)); // 2 -> COUNT
276 		}
277 		try
278 		{
279 			Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
280 			if ( xMetaData.is() )
281 			{
282 				m_bOrderByUnRelated = xMetaData->supportsOrderByUnrelated();
283 				m_bGroupByUnRelated = xMetaData->supportsGroupByUnrelated();
284 			}
285 		}
286 		catch(Exception&)
287 		{
288 		}
289 	}
290 
291 	Init();
292 }
293 //==============================================================================
getDesignView()294 OQueryDesignView* OSelectionBrowseBox::getDesignView()
295 {
296 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
297 	OSL_ENSURE(static_cast<const OQueryDesignView*>(GetParent()),"Parent isn't an OQueryDesignView!");
298 	return static_cast<OQueryDesignView*>(GetParent());
299 }
300 // -----------------------------------------------------------------------------
getDesignView() const301 OQueryDesignView* OSelectionBrowseBox::getDesignView() const
302 {
303 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
304 	OSL_ENSURE(static_cast<const OQueryDesignView*>(GetParent()),"Parent isn't an OQueryDesignView!");
305 	return static_cast<OQueryDesignView*>(GetParent());
306 }
307 namespace
308 {
309 	class OSelectionBrwBoxHeader : public ::svt::EditBrowserHeader
310 	{
311 		OSelectionBrowseBox* m_pBrowseBox;
312 	protected:
313 		virtual void Select();
314 	public:
315 		OSelectionBrwBoxHeader(OSelectionBrowseBox* pParent);
316 	};
OSelectionBrwBoxHeader(OSelectionBrowseBox * pParent)317 	OSelectionBrwBoxHeader::OSelectionBrwBoxHeader(OSelectionBrowseBox* pParent)
318 		: ::svt::EditBrowserHeader(pParent,WB_BUTTONSTYLE|WB_DRAG)
319 		,m_pBrowseBox(pParent)
320 	{
321 	}
322 
Select()323 	void OSelectionBrwBoxHeader::Select()
324 	{
325 		EditBrowserHeader::Select();
326 		m_pBrowseBox->GrabFocus();
327 
328 		BrowserMode nMode = m_pBrowseBox->GetMode();
329 		if ( 0 == m_pBrowseBox->GetSelectColumnCount() )
330 		{
331 			m_pBrowseBox->DeactivateCell();
332 			// wenn es schon eine selektierte Spalte gibt, bin ich schon im richtigen Modus
333 			if ( BROWSER_HIDESELECT == ( nMode & BROWSER_HIDESELECT ) )
334 			{
335 				nMode &= ~BROWSER_HIDESELECT;
336 				nMode |= BROWSER_MULTISELECTION;
337 				m_pBrowseBox->SetMode( nMode );
338 			}
339 		}
340 		m_pBrowseBox->SelectColumnId( GetCurItemId() );
341 		m_pBrowseBox->DeactivateCell();
342 	}
343 }
344 
345 // -----------------------------------------------------------------------------
imp_CreateHeaderBar(BrowseBox *)346 BrowserHeader* OSelectionBrowseBox::imp_CreateHeaderBar(BrowseBox* /*pParent*/)
347 {
348 	return new OSelectionBrwBoxHeader(this);
349 }
350 // -----------------------------------------------------------------------------
ColumnMoved(sal_uInt16 nColId,sal_Bool _bCreateUndo)351 void OSelectionBrowseBox::ColumnMoved( sal_uInt16 nColId,sal_Bool _bCreateUndo )
352 {
353 	EditBrowseBox::ColumnMoved( nColId );
354 	// swap the two columns
355 	sal_uInt16 nNewPos = GetColumnPos( nColId );
356 	OTableFields& rFields = getFields();
357 	if ( rFields.size() > sal_uInt16(nNewPos-1) )
358 	{
359 		sal_uInt16 nOldPos = 0;
360 		OTableFields::iterator aEnd = rFields.end();
361 		OTableFields::iterator aIter = rFields.begin();
362 		for (; aIter != aEnd && ( (*aIter)->GetColumnId() != nColId ); ++aIter,++nOldPos)
363 			;
364 
365 		OSL_ENSURE( (nNewPos-1) != nOldPos && nOldPos < rFields.size(),"Old and new position are equal!");
366 		if ( aIter != aEnd )
367 		{
368 			OTableFieldDescRef pOldEntry = rFields[nOldPos];
369 			rFields.erase(rFields.begin() + nOldPos);
370 			rFields.insert(rFields.begin() + nNewPos - 1,pOldEntry);
371 
372 			// create the undo action
373 			if ( !m_bInUndoMode && _bCreateUndo )
374 			{
375 				OTabFieldMovedUndoAct* pUndoAct = new OTabFieldMovedUndoAct(this);
376 				pUndoAct->SetColumnPosition( nOldPos + 1);
377 				pUndoAct->SetTabFieldDescr(pOldEntry);
378 
379 				getDesignView()->getController().addUndoActionAndInvalidate(pUndoAct);
380 			} // if ( !m_bInUndoMode && _bCreateUndo )
381 		}
382 	}
383 	else
384 		OSL_ENSURE(0,"Invalid column id!");
385 }
386 //------------------------------------------------------------------------------
Init()387 void OSelectionBrowseBox::Init()
388 {
389 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
390 
391 	EditBrowseBox::Init();
392 
393 	// set the header bar
394 	BrowserHeader* pNewHeaderBar = CreateHeaderBar(this);
395 	pNewHeaderBar->SetMouseTransparent(sal_False);
396 
397 	SetHeaderBar(pNewHeaderBar);
398 	SetMode(m_nMode);
399 
400 	Font	aFont( GetDataWindow().GetFont() );
401 	aFont.SetWeight( WEIGHT_NORMAL );
402 	GetDataWindow().SetFont( aFont );
403 
404     Size aHeight;
405     const Control* pControls[] = { m_pTextCell,m_pVisibleCell,m_pTableCell,m_pFieldCell };
406     for(sal_Size i= 0; i < sizeof(pControls)/sizeof(pControls[0]);++i)
407     {
408         const Size aTemp( pControls[i]->GetOptimalSize(WINDOWSIZE_PREFERRED) );
409         if ( aTemp.Height() > aHeight.Height() )
410             aHeight.Height() = aTemp.Height();
411     } // for(int i= 0; i < sizeof(pControls)/sizeof(pControls[0]);++i
412     SetDataRowHeight(aHeight.Height());
413 	SetTitleLines(1);
414 	// Anzahl der sichtbaren Zeilen ermitteln
415 	for(long i=0;i<BROW_ROW_CNT;i++)
416 	{
417 		if(m_bVisibleRow[i])
418 			m_nVisibleCount++;
419 	}
420 	RowInserted(0, m_nVisibleCount, sal_False);
421 	try
422 	{
423 		Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
424 		if(xConnection.is())
425 		{
426 			Reference< XDatabaseMetaData >  xMetaData = xConnection->getMetaData();
427 			m_nMaxColumns = xMetaData.is() ? xMetaData->getMaxColumnsInSelect() : 0;
428 
429 		}
430 		else
431 			m_nMaxColumns = 0;
432 	}
433 	catch(const SQLException&)
434 	{
435 		OSL_ENSURE(0,"Catched Exception when asking for database metadata options!");
436 		m_nMaxColumns = 0;
437 	}
438 }
439 
440 //------------------------------------------------------------------------------
PreFill()441 void OSelectionBrowseBox::PreFill()
442 {
443 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
444 	SetUpdateMode(sal_False);
445 
446 	if (GetCurRow() != 0)
447 		GoToRow(0);
448 
449 
450 	static_cast< OQueryController& >( getDesignView()->getController() ).clearFields();
451 
452 	DeactivateCell();
453 
454 	RemoveColumns();
455 	InsertHandleColumn( HANDLE_COLUMN_WITDH );
456 	SetUpdateMode(sal_True);
457 }
458 //------------------------------------------------------------------------------
ClearAll()459 void OSelectionBrowseBox::ClearAll()
460 {
461 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
462 	SetUpdateMode(sal_False);
463 
464 	OTableFields::reverse_iterator aIter = getFields().rbegin();
465 	for ( ;aIter != getFields().rend(); ++aIter )
466 	{
467 		if ( !(*aIter)->IsEmpty() )
468         {
469 			RemoveField( (*aIter)->GetColumnId() );
470             aIter = getFields().rbegin();
471         }
472 	}
473 	SetUpdateMode(sal_True);
474 }
475 //------------------------------------------------------------------------------
SetReadOnly(sal_Bool bRO)476 void OSelectionBrowseBox::SetReadOnly(sal_Bool bRO)
477 {
478 	if (bRO)
479 	{
480 		DeactivateCell();
481 		m_nMode &= ~BROWSER_HIDECURSOR;
482 		SetMode(m_nMode);
483 	}
484 	else
485 	{
486 		m_nMode |= BROWSER_HIDECURSOR;
487 		SetMode(m_nMode);
488 		ActivateCell();
489 	}
490 }
491 
492 //------------------------------------------------------------------------------
GetController(long nRow,sal_uInt16 nColId)493 CellController* OSelectionBrowseBox::GetController(long nRow, sal_uInt16 nColId)
494 {
495 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
496     if ( nColId > getFields().size() )
497         return NULL;
498 	OTableFieldDescRef pEntry = getFields()[nColId-1];
499 	DBG_ASSERT(pEntry.isValid(), "OSelectionBrowseBox::GetController : keine FieldDescription !");
500 
501 	if (!pEntry.isValid())
502 		return NULL;
503 
504 	if (static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
505 		return NULL;
506 
507 	long nCellIndex = GetRealRow(nRow);
508 	switch (nCellIndex)
509 	{
510 		case BROW_FIELD_ROW:
511 			return new ComboBoxCellController(m_pFieldCell);
512 		case BROW_TABLE_ROW:
513 			return new ListBoxCellController(m_pTableCell);
514 		case BROW_VIS_ROW:
515 			return new CheckBoxCellController(m_pVisibleCell);
516 		case BROW_ORDER_ROW:
517 			return new ListBoxCellController(m_pOrderCell);
518 		case BROW_FUNCTION_ROW:
519 			return new ListBoxCellController(m_pFunctionCell);
520 		default:
521 			return new EditCellController(m_pTextCell);
522 	}
523 }
524 
525 //------------------------------------------------------------------------------
InitController(CellControllerRef &,long nRow,sal_uInt16 nColId)526 void OSelectionBrowseBox::InitController(CellControllerRef& /*rController*/, long nRow, sal_uInt16 nColId)
527 {
528 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
529 	OSL_ENSURE(nColId != BROWSER_INVALIDID,"An Invalid Id was set!");
530 	if ( nColId == BROWSER_INVALIDID )
531 		return;
532 	sal_uInt16 nPos = GetColumnPos(nColId);
533 	if ( nPos == 0 || nPos == BROWSER_INVALIDID || nPos > getFields().size() )
534 		return;
535 	OTableFieldDescRef pEntry = getFields()[nPos-1];
536 	DBG_ASSERT(pEntry.isValid(), "OSelectionBrowseBox::InitController : keine FieldDescription !");
537 	long nCellIndex = GetRealRow(nRow);
538 
539 	switch (nCellIndex)
540 	{
541 		case BROW_FIELD_ROW:
542 		{
543 			m_pFieldCell->Clear();
544 			m_pFieldCell->SetText(String());
545 
546 			String aField(pEntry->GetField());
547 			String aTable(pEntry->GetAlias());
548 
549 			getDesignView()->fillValidFields(aTable, m_pFieldCell);
550 
551 			// * durch alias.* ersetzen
552 			if ((aField.GetChar(0) == '*') && aTable.Len())
553 			{
554 				aField = aTable;
555 				aField.AppendAscii(".*");
556 			}
557 			m_pFieldCell->SetText(aField);
558 		}	break;
559 		case BROW_TABLE_ROW:
560 		{
561 			m_pTableCell->Clear();
562 			enableControl(pEntry,m_pTableCell);
563 			if ( !pEntry->isCondition() )
564 			{
565 				OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
566 				if (pTabWinList)
567 				{
568 					OJoinTableView::OTableWindowMap::iterator aIter = pTabWinList->begin();
569                     OJoinTableView::OTableWindowMap::iterator aEnd = pTabWinList->end();
570 
571 					for(;aIter != aEnd;++aIter)
572 						m_pTableCell->InsertEntry(static_cast<OQueryTableWindow*>(aIter->second)->GetAliasName());
573 
574 					m_pTableCell->InsertEntry(String(ModuleRes(STR_QUERY_NOTABLE)), 0);
575 					if (pEntry->GetAlias().getLength())
576 						m_pTableCell->SelectEntry(pEntry->GetAlias());
577 					else
578 						m_pTableCell->SelectEntry(String(ModuleRes(STR_QUERY_NOTABLE)));
579 				}
580 			}
581 		}	break;
582 		case BROW_VIS_ROW:
583 		{
584 			m_pVisibleCell->GetBox().Check(pEntry->IsVisible());
585 			m_pVisibleCell->GetBox().SaveValue();
586 
587 			enableControl(pEntry,m_pTextCell);
588 
589 			if(!pEntry->IsVisible() && pEntry->GetOrderDir() != ORDER_NONE && !m_bOrderByUnRelated)
590 			{
591 				// Spalte muss sichtbar sein, um im ORDER BY aufzutauchen
592 				pEntry->SetVisible(sal_True);
593 				m_pVisibleCell->GetBox().Check(pEntry->IsVisible());
594 				m_pVisibleCell->GetBox().SaveValue();
595 				m_pVisibleCell->GetBox().Disable();
596 				m_pVisibleCell->GetBox().EnableInput(sal_False);
597 				String aMessage(ModuleRes(STR_QRY_ORDERBY_UNRELATED));
598 				OQueryDesignView* paDView = getDesignView();
599 				InfoBox(paDView, aMessage).Execute();
600 			}
601 		}	break;
602 		case BROW_ORDER_ROW:
603 			m_pOrderCell->SelectEntryPos(
604                 sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()));
605 			enableControl(pEntry,m_pOrderCell);
606 			break;
607 		case BROW_COLUMNALIAS_ROW:
608 			setTextCellContext(pEntry,pEntry->GetFieldAlias(),HID_QRYDGN_ROW_ALIAS);
609 			break;
610 		case BROW_FUNCTION_ROW:
611 			setFunctionCell(pEntry);
612 			break;
613 		default:
614 		{
615 			sal_uInt16	nIdx = sal_uInt16(nCellIndex - BROW_CRIT1_ROW);
616 			setTextCellContext(pEntry,pEntry->GetCriteria( nIdx ),HID_QRYDGN_ROW_CRIT);
617 		}
618 	}
619 	Controller()->ClearModified();
620 }
621 // -----------------------------------------------------------------------------
notifyTableFieldChanged(const String & _sOldAlias,const String & _sAlias,sal_Bool & _bListAction,sal_uInt16 _nColumnId)622 void OSelectionBrowseBox::notifyTableFieldChanged(const String& _sOldAlias,const String& _sAlias,sal_Bool& _bListAction,sal_uInt16 _nColumnId)
623 {
624 	appendUndoAction(_sOldAlias,_sAlias,BROW_TABLE_ROW,_bListAction);
625 	if ( m_bVisibleRow[BROW_TABLE_ROW] )
626 		RowModified(GetBrowseRow(BROW_TABLE_ROW), _nColumnId);
627 }
628 // -----------------------------------------------------------------------------
notifyFunctionFieldChanged(const String & _sOldFunctionName,const String & _sFunctionName,sal_Bool & _bListAction,sal_uInt16 _nColumnId)629 void OSelectionBrowseBox::notifyFunctionFieldChanged(const String& _sOldFunctionName,const String& _sFunctionName,sal_Bool& _bListAction,sal_uInt16 _nColumnId)
630 {
631 	appendUndoAction(_sOldFunctionName,_sFunctionName,BROW_FUNCTION_ROW,_bListAction);
632 	if ( !m_bVisibleRow[BROW_FUNCTION_ROW] )
633 		SetRowVisible(BROW_FUNCTION_ROW, sal_True);
634 	RowModified(GetBrowseRow(BROW_FUNCTION_ROW), _nColumnId);
635 }
636 // -----------------------------------------------------------------------------
clearEntryFunctionField(const String & _sFieldName,OTableFieldDescRef & _pEntry,sal_Bool & _bListAction,sal_uInt16 _nColumnId)637 void OSelectionBrowseBox::clearEntryFunctionField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction,sal_uInt16 _nColumnId)
638 {
639 	if ( isFieldNameAsterix( _sFieldName ) && (!_pEntry->isNoneFunction() || _pEntry->IsGroupBy()) )
640 	{
641 		String sFunctionName;
642 		GetFunctionName(SQL_TOKEN_COUNT,sFunctionName);
643 		String sOldLocalizedFunctionName = _pEntry->GetFunction();
644 		if ( !sOldLocalizedFunctionName.Equals(sFunctionName) || _pEntry->IsGroupBy() )
645 		{
646 			// append undo action for the function field
647 			_pEntry->SetFunctionType(FKT_NONE);
648 			_pEntry->SetFunction(::rtl::OUString());
649 			_pEntry->SetGroupBy(sal_False);
650 			notifyFunctionFieldChanged(sOldLocalizedFunctionName,_pEntry->GetFunction(),_bListAction,_nColumnId);
651 		}
652 	}
653 }
654 // -----------------------------------------------------------------------------
fillColumnRef(const OSQLParseNode * _pColumnRef,const Reference<XConnection> & _rxConnection,OTableFieldDescRef & _pEntry,sal_Bool & _bListAction)655 sal_Bool OSelectionBrowseBox::fillColumnRef(const OSQLParseNode* _pColumnRef, const Reference< XConnection >& _rxConnection, OTableFieldDescRef& _pEntry, sal_Bool& _bListAction )
656 {
657 	OSL_ENSURE(_pColumnRef,"No valid parsenode!");
658 	::rtl::OUString sColumnName,sTableRange;
659 	OSQLParseTreeIterator::getColumnRange(_pColumnRef,_rxConnection,sColumnName,sTableRange);
660 	return fillColumnRef(sColumnName,sTableRange,_rxConnection->getMetaData(),_pEntry,_bListAction);
661 }
662 // -----------------------------------------------------------------------------
fillColumnRef(const::rtl::OUString & _sColumnName,const::rtl::OUString & _sTableRange,const Reference<XDatabaseMetaData> & _xMetaData,OTableFieldDescRef & _pEntry,sal_Bool & _bListAction)663 sal_Bool OSelectionBrowseBox::fillColumnRef(const ::rtl::OUString& _sColumnName,const ::rtl::OUString& _sTableRange,const Reference<XDatabaseMetaData>& _xMetaData,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction)
664 {
665 	sal_Bool bError = sal_False;
666 	::comphelper::UStringMixEqual bCase(_xMetaData->supportsMixedCaseQuotedIdentifiers());
667 	// check if the table name is the same
668 	if ( _sTableRange.getLength() && (bCase(_pEntry->GetTable(),_sTableRange) || bCase(_pEntry->GetAlias(),_sTableRange)) )
669 	{ // a table was already inserted and the tables contains that column name
670 
671 		if ( !_pEntry->GetTabWindow() )
672 		{ // fill tab window
673 			::rtl::OUString sOldAlias = _pEntry->GetAlias();
674 			if ( !fillEntryTable(_pEntry,_pEntry->GetTable()) )
675 				fillEntryTable(_pEntry,_pEntry->GetAlias()); // only when the first failed
676 			if ( !bCase(sOldAlias,_pEntry->GetAlias()) )
677 				notifyTableFieldChanged(sOldAlias,_pEntry->GetAlias(),_bListAction,GetCurColumnId());
678 		}
679 	}
680 	// check if the table window
681 	OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(_pEntry->GetTabWindow());
682 	if ( !pEntryTab ) // no table found with this name so we have to travel through all tables
683 	{
684 		OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
685 		if ( pTabWinList )
686 		{
687 			sal_uInt16 nTabCount = 0;
688 			if ( !static_cast<OQueryTableView*>(getDesignView()->getTableView())->FindTableFromField(_sColumnName,_pEntry,nTabCount) ) // error occured: column not in table window
689 			{
690 				String sErrorMsg(ModuleRes(RID_STR_FIELD_DOESNT_EXIST));
691 				sErrorMsg.SearchAndReplaceAscii("$name$",_sColumnName);
692 				OSQLWarningBox( this, sErrorMsg ).Execute();
693 				bError = sal_True;
694 			}
695 			else
696 			{
697 				pEntryTab = static_cast<OQueryTableWindow*>(_pEntry->GetTabWindow());
698 				notifyTableFieldChanged(String(),_pEntry->GetAlias(),_bListAction,GetCurColumnId());
699 			}
700 		}
701 	}
702 	if ( pEntryTab ) // here we got a valid table
703 		_pEntry->SetField(_sColumnName);
704 
705 	return bError;
706 }
707 // -----------------------------------------------------------------------------
saveField(const String & _sFieldName,OTableFieldDescRef & _pEntry,sal_Bool & _bListAction)708 sal_Bool OSelectionBrowseBox::saveField(const String& _sFieldName,OTableFieldDescRef& _pEntry,sal_Bool& _bListAction)
709 {
710 	sal_Bool bError = sal_False;
711 
712 	OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
713 
714 	// first look if the name can be found in our tables
715 	sal_uInt16 nTabCount = 0;
716 	String sOldAlias = _pEntry->GetAlias();
717 	if ( static_cast<OQueryTableView*>(getDesignView()->getTableView())->FindTableFromField(_sFieldName,_pEntry,nTabCount) )
718 	{
719 		// append undo action for the alias name
720 		_pEntry->SetField(_sFieldName);
721 		notifyTableFieldChanged(sOldAlias,_pEntry->GetAlias(),_bListAction,GetCurColumnId());
722 		clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
723 		return bError;
724 	}
725 
726 	Reference<XConnection> xConnection( rController.getConnection() );
727 	Reference< XDatabaseMetaData > xMetaData;
728 	if ( xConnection.is() )
729         xMetaData = xConnection->getMetaData();
730     OSL_ENSURE( xMetaData.is(), "OSelectionBrowseBox::saveField: invalid connection/meta data!" );
731     if ( !xMetaData.is() )
732 		return sal_True;
733 
734 	::rtl::OUString sErrorMsg;
735 	// second test if the name can be set as select columns in a pseudo statement
736 	// we have to look which entries  we should quote
737 
738     const ::rtl::OUString sFieldAlias = _pEntry->GetFieldAlias();
739     size_t nPass = 4;
740     ::connectivity::OSQLParser& rParser( rController.getParser() );
741     OSQLParseNode* pParseNode = NULL;
742     // 4 passes in trying to interprete the field name
743     // - don't quote the field name, parse internationally
744     // - don't quote the field name, parse en-US
745     // - quote the field name, parse internationally
746     // - quote the field name, parse en-US
747     do
748     {
749         bool bQuote = ( nPass <= 2 );
750         bool bInternational = ( nPass % 2 ) == 0;
751 
752         ::rtl::OUString sSql;
753         if ( bQuote )
754             sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName );
755         else
756             sSql += _sFieldName;
757 
758         if  ( _pEntry->isAggreateFunction() )
759 		{
760 			DBG_ASSERT(_pEntry->GetFunction().getLength(),"Functionname darf hier nicht leer sein! ;-(");
761 			::rtl::OUStringBuffer aTmpStr2( _pEntry->GetFunction());
762 			aTmpStr2.appendAscii("(");
763 			aTmpStr2.append(sSql);
764 			aTmpStr2.appendAscii(")");
765 			sSql = aTmpStr2.makeStringAndClear();
766 		}
767 
768         sSql = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT ")) + sSql;
769         if ( sFieldAlias.getLength() )
770         { // always quote the alias name there canbe no function in it
771             sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" "));
772             sSql += ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), sFieldAlias );
773         }
774         sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x"));
775 
776         pParseNode = rParser.parseTree( sErrorMsg, sSql, bInternational );
777     }
778     while ( ( pParseNode == NULL ) && ( --nPass > 0 ) );
779 
780     if ( pParseNode == NULL )
781     {
782         // something different which we have to check (may be a select statement)
783         String sErrorMessage( ModuleRes( STR_QRY_COLUMN_NOT_FOUND ) );
784         sErrorMessage.SearchAndReplaceAscii("$name$",_sFieldName);
785         OSQLWarningBox( this, sErrorMessage ).Execute();
786         return sal_True;
787     }
788 
789     // we got a valid select column
790     // find what type of column has be inserted
791     ::connectivity::OSQLParseNode* pSelection = pParseNode->getChild(2);
792     if ( SQL_ISRULE(pSelection,selection) ) // we found the asterix
793     {
794         _pEntry->SetField(_sFieldName);
795         clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
796     } // travel through the select column parse node
797     else
798     {
799         ::comphelper::UStringMixEqual bCase(xMetaData->supportsMixedCaseQuotedIdentifiers());
800 
801         OTableFieldDescRef aSelEntry = _pEntry;
802         sal_uInt16 nColumnId = aSelEntry->GetColumnId();
803 
804         sal_uInt32 nCount = pSelection->count();
805         for (sal_uInt32 i = 0; i < nCount; ++i)
806         {
807             if ( i > 0 ) // may we have to append more than one field
808             {
809                 sal_uInt16 nColumnPostion;
810                 aSelEntry = FindFirstFreeCol(nColumnPostion);
811                 if ( !aSelEntry.isValid() )
812                 {
813                     AppendNewCol(1);
814                     aSelEntry = FindFirstFreeCol(nColumnPostion);
815                 }
816                 ++nColumnPostion;
817                 nColumnId = GetColumnId(nColumnPostion);
818             }
819 
820             ::connectivity::OSQLParseNode* pChild = pSelection->getChild( i );
821             OSL_ENSURE(SQL_ISRULE(pChild,derived_column), "No derived column found!");
822             // get the column alias
823             ::rtl::OUString sColumnAlias = OSQLParseTreeIterator::getColumnAlias(pChild);
824             if ( sColumnAlias.getLength() ) // we found an as clause
825             {
826                 String aSelectionAlias = aSelEntry->GetFieldAlias();
827                 aSelEntry->SetFieldAlias( sColumnAlias );
828                 // append undo
829                 appendUndoAction(aSelectionAlias,aSelEntry->GetFieldAlias(),BROW_COLUMNALIAS_ROW,_bListAction);
830                 if ( m_bVisibleRow[BROW_COLUMNALIAS_ROW] )
831                     RowModified(GetBrowseRow(BROW_COLUMNALIAS_ROW), nColumnId);
832             }
833 
834             ::connectivity::OSQLParseNode* pColumnRef = pChild->getChild(0);
835             if (
836                     pColumnRef->count() == 3 &&
837                     SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
838                     SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
839                 )
840                 pColumnRef = pColumnRef->getChild(1);
841 
842             if ( SQL_ISRULE(pColumnRef,column_ref) ) // we found a valid column name or more column names
843             {
844                 // look if we can find the corresponding table
845                 bError = fillColumnRef( pColumnRef, xConnection, aSelEntry, _bListAction );
846 
847                 // we found a simple column so we must clear the function fields but only when the column name is '*'
848                 // and the function is different to count
849                 clearEntryFunctionField(_sFieldName,aSelEntry,_bListAction,nColumnId);
850             }
851             else
852             {
853                 // first check if we have a aggregate function and only a function
854                 if ( SQL_ISRULE(pColumnRef,general_set_fct) )
855                 {
856                     String sLocalizedFunctionName;
857                     if ( GetFunctionName(pColumnRef->getChild(0)->getTokenID(),sLocalizedFunctionName) )
858                     {
859                         String sOldLocalizedFunctionName = aSelEntry->GetFunction();
860                         aSelEntry->SetFunction(sLocalizedFunctionName);
861                         sal_uInt32 nFunCount = pColumnRef->count() - 1;
862                         sal_Int32 nFunctionType = FKT_AGGREGATE;
863                         sal_Bool bQuote = sal_False;
864                         // may be there exists only one parameter which is a column, fill all information into our fields
865                         if ( nFunCount == 4 && SQL_ISRULE(pColumnRef->getChild(3),column_ref) )
866                             bError = fillColumnRef( pColumnRef->getChild(3), xConnection, aSelEntry, _bListAction );
867                         else if ( nFunCount == 3 ) // we have a COUNT(*) here, so take the first table
868                             bError = fillColumnRef( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), ::rtl::OUString(), xMetaData, aSelEntry, _bListAction );
869                         else
870                         {
871                             nFunctionType |= FKT_NUMERIC;
872                             bQuote = sal_True;
873                             aSelEntry->SetDataType(DataType::DOUBLE);
874                             aSelEntry->SetFieldType(TAB_NORMAL_FIELD);
875                         }
876 
877                         // now parse the parameters
878                         ::rtl::OUString sParameters;
879                         for(sal_uInt32 function = 2; function < nFunCount; ++function) // we only want to parse the parameters of the function
880                             pColumnRef->getChild(function)->parseNodeToStr( sParameters, xConnection, &rParser.getContext(), sal_True, bQuote );
881 
882                         aSelEntry->SetFunctionType(nFunctionType);
883                         aSelEntry->SetField(sParameters);
884                         if ( aSelEntry->IsGroupBy() )
885                         {
886                             sOldLocalizedFunctionName = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
887                             aSelEntry->SetGroupBy(sal_False);
888                         }
889 
890                         // append undo action
891                         notifyFunctionFieldChanged(sOldLocalizedFunctionName,sLocalizedFunctionName,_bListAction, nColumnId);
892                     }
893                     else
894                         OSL_ENSURE(0,"Unsupported function inserted!");
895 
896                 }
897                 else
898                 {
899                     // so we first clear the function field
900                     clearEntryFunctionField(_sFieldName,aSelEntry,_bListAction,nColumnId);
901                     ::rtl::OUString sFunction;
902 					pColumnRef->parseNodeToStr(	sFunction,
903 												xConnection,
904 												&rController.getParser().getContext(),
905 												sal_True,
906 												sal_True); // quote is to true because we need quoted elements inside the function
907 
908                     getDesignView()->fillFunctionInfo(pColumnRef,sFunction,aSelEntry);
909 
910                     if( SQL_ISRULEOR2(pColumnRef,position_exp,extract_exp) ||
911                         SQL_ISRULEOR2(pColumnRef,fold,char_substring_fct)  ||
912                         SQL_ISRULEOR2(pColumnRef,length_exp,char_value_fct) )
913                             // a calculation has been found ( can be calc and function )
914                     {
915                         // now parse the whole statement
916                         sal_uInt32 nFunCount = pColumnRef->count();
917                         ::rtl::OUString sParameters;
918                         for(sal_uInt32 function = 0; function < nFunCount; ++function)
919                             pColumnRef->getChild(function)->parseNodeToStr( sParameters, xConnection, &rParser.getContext(), sal_True, sal_True );
920 
921                         sOldAlias = aSelEntry->GetAlias();
922                         sal_Int32 nNewFunctionType = aSelEntry->GetFunctionType() | FKT_NUMERIC | FKT_OTHER;
923                         aSelEntry->SetFunctionType(nNewFunctionType);
924                         aSelEntry->SetField(sParameters);
925                     }
926                     else
927                     {
928                         aSelEntry->SetFieldAlias(sColumnAlias);
929                         if ( SQL_ISRULE(pColumnRef,set_fct_spec) )
930                             aSelEntry->SetFunctionType(/*FKT_NUMERIC | */FKT_OTHER);
931                         else
932                         {
933                             if ( SQL_ISRULEOR2(pColumnRef,num_value_exp,term) || SQL_ISRULE(pColumnRef,factor) )
934                                 aSelEntry->SetDataType(DataType::DOUBLE);
935                             else if ( SQL_ISRULE(pColumnRef,value_exp) )
936                                 aSelEntry->SetDataType(DataType::TIMESTAMP);
937                             else
938                                 aSelEntry->SetDataType(DataType::VARCHAR);
939                             aSelEntry->SetFunctionType(FKT_NUMERIC | FKT_OTHER);
940                         }
941                     }
942 
943                     aSelEntry->SetAlias(::rtl::OUString());
944                     notifyTableFieldChanged(sOldAlias,aSelEntry->GetAlias(),_bListAction, nColumnId);
945                 }
946 
947             }
948             if ( i > 0 && InsertField(aSelEntry,BROWSER_INVALIDID,sal_True,sal_False).isEmpty() ) // may we have to append more than one field
949             { // the field could not be isnerted
950                 String sErrorMessage( ModuleRes( RID_STR_FIELD_DOESNT_EXIST ) );
951                 sErrorMessage.SearchAndReplaceAscii("$name$",aSelEntry->GetField());
952                 OSQLWarningBox( this, sErrorMessage ).Execute();
953                 bError = sal_True;
954             }
955         }
956     }
957     delete pParseNode;
958 
959     return bError;
960 }
961 //------------------------------------------------------------------------------
SaveModified()962 sal_Bool OSelectionBrowseBox::SaveModified()
963 {
964 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
965     OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
966     OTableFieldDescRef pEntry = NULL;
967 	sal_uInt16 nCurrentColumnPos = GetColumnPos(GetCurColumnId());
968 	if(getFields().size() > static_cast<sal_uInt16>(nCurrentColumnPos - 1))
969 		pEntry = getEntry(nCurrentColumnPos - 1);
970 
971 	sal_Bool bWasEmpty = pEntry.isValid() ? pEntry->IsEmpty() : sal_False;
972 	sal_Bool bError			= sal_False;
973 	sal_Bool bListAction	= sal_False;
974 
975 	if (pEntry.isValid() && Controller().Is() && Controller()->IsModified())
976 	{
977 		// fuer die Undo-Action
978 		String strOldCellContents,sNewValue;
979 		long nRow = GetRealRow(GetCurRow());
980 		sal_Bool bAppendRow = sal_False;
981 		switch (nRow)
982 		{
983 			case BROW_VIS_ROW:
984 				{
985 					sal_Bool bOldValue = m_pVisibleCell->GetBox().GetSavedValue() != STATE_NOCHECK;
986 					strOldCellContents = bOldValue ? g_strOne : g_strZero;
987 					sNewValue		   = !bOldValue ? g_strOne : g_strZero;
988 				}
989 				if((m_bOrderByUnRelated || pEntry->GetOrderDir() == ORDER_NONE) &&
990 				   (m_bGroupByUnRelated || !pEntry->IsGroupBy()))
991 				{
992 					pEntry->SetVisible(m_pVisibleCell->GetBox().IsChecked());
993 				}
994 				else
995 				{
996 					pEntry->SetVisible(sal_True);
997 					m_pVisibleCell->GetBox().Check();
998 				}
999 				break;
1000 
1001 			case BROW_FIELD_ROW:
1002 			{
1003 				String aFieldName(m_pFieldCell->GetText());
1004 				try
1005 				{
1006 					if (!aFieldName.Len())
1007 					{
1008 						OTableFieldDescRef pNewEntry = new OTableFieldDesc();
1009 						pNewEntry->SetColumnId( pEntry->GetColumnId() );
1010 						::std::replace(getFields().begin(),getFields().end(),pEntry,pNewEntry);
1011 						sal_uInt16 nCol = GetCurColumnId();
1012 						for (int i = 0; i < m_nVisibleCount; i++)	// Spalte neu zeichnen
1013 							RowModified(i,nCol);
1014 					}
1015 					else
1016 					{
1017 						strOldCellContents = pEntry->GetField();
1018 						bListAction = sal_True;
1019 						if ( !m_bInUndoMode )
1020 							rController.GetUndoManager().EnterListAction(String(),String());
1021 
1022 						sal_uInt16 nPos = m_pFieldCell->GetEntryPos(aFieldName);
1023                         String aAliasName = pEntry->GetAlias();
1024 						if ( nPos != COMBOBOX_ENTRY_NOTFOUND && !aAliasName.Len() && aFieldName.GetTokenCount('.') > 1 )
1025 						{ // special case, we have a table field so we must cut the table name
1026 							String sTableAlias = aFieldName.GetToken(0,'.');
1027 							pEntry->SetAlias(sTableAlias);
1028                             String sColumnName = aFieldName.Copy(sTableAlias.Len()+1,aFieldName.Len() - sTableAlias.Len() -1);
1029 							Reference<XConnection> xConnection = rController.getConnection();
1030 							if ( !xConnection.is() )
1031 								return sal_False;
1032 							bError = fillColumnRef( sColumnName, sTableAlias, xConnection->getMetaData(), pEntry, bListAction );
1033 						}
1034 						else
1035 							bError = sal_True;
1036 
1037 						if ( bError )
1038 							bError = saveField(aFieldName,pEntry,bListAction);
1039 					}
1040 				}
1041 				catch(Exception&)
1042 				{
1043 					bError = sal_True;
1044 				}
1045 				if ( bError )
1046 				{
1047 					sNewValue = aFieldName;
1048 					if ( !m_bInUndoMode )
1049 						static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
1050 					bListAction = sal_False;
1051 				}
1052 				else
1053 					sNewValue = pEntry->GetField();
1054 				rController.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
1055 			}
1056 			break;
1057 
1058 			case BROW_TABLE_ROW:
1059 			{
1060 				String aAliasName = m_pTableCell->GetSelectEntry();
1061 				strOldCellContents = pEntry->GetAlias();
1062 				if ( m_pTableCell->GetSelectEntryPos() != 0 )
1063 				{
1064 					pEntry->SetAlias(aAliasName);
1065 					// we have to set the table name as well as the table window
1066 					OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
1067 					if (pTabWinList)
1068 					{
1069 						OJoinTableView::OTableWindowMapIterator aIter = pTabWinList->find(aAliasName);
1070 						if(aIter != pTabWinList->end())
1071 						{
1072 							OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(aIter->second);
1073 							if (pEntryTab)
1074 							{
1075 								pEntry->SetTable(pEntryTab->GetTableName());
1076 								pEntry->SetTabWindow(pEntryTab);
1077 							}
1078 						}
1079 					}
1080 				}
1081 				else
1082 				{
1083 					pEntry->SetAlias(::rtl::OUString());
1084 					pEntry->SetTable(::rtl::OUString());
1085 					pEntry->SetTabWindow(NULL);
1086 				}
1087 				sNewValue = pEntry->GetAlias();
1088 
1089 			}	break;
1090 
1091 			case BROW_ORDER_ROW:
1092 			{
1093 				strOldCellContents = String::CreateFromInt32((sal_uInt16)pEntry->GetOrderDir());
1094 				sal_uInt16 nIdx = m_pOrderCell->GetSelectEntryPos();
1095 				if (nIdx == sal_uInt16(-1))
1096 					nIdx = 0;
1097 				pEntry->SetOrderDir(EOrderDir(nIdx));
1098 				if(!m_bOrderByUnRelated)
1099 				{
1100 					pEntry->SetVisible(sal_True);
1101 					m_pVisibleCell->GetBox().Check();
1102 					RowModified(GetBrowseRow(BROW_VIS_ROW), GetCurColumnId());
1103 				}
1104 				sNewValue = String::CreateFromInt32((sal_uInt16)pEntry->GetOrderDir());
1105 			}	break;
1106 
1107 			case BROW_COLUMNALIAS_ROW:
1108 				strOldCellContents = pEntry->GetFieldAlias();
1109 				pEntry->SetFieldAlias(m_pTextCell->GetText());
1110 				sNewValue = pEntry->GetFieldAlias();
1111 				break;
1112 			case BROW_FUNCTION_ROW:
1113 				{
1114 					strOldCellContents = pEntry->GetFunction();
1115 					sal_uInt16 nPos = m_pFunctionCell->GetSelectEntryPos();
1116 					// Diese Funktionen stehen nur unter CORE zur Verf�gung
1117 					String sFunctionName		= m_pFunctionCell->GetEntry(nPos);
1118 					String sGroupFunctionName	= m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
1119 					sal_Bool bGroupBy = sal_False;
1120 					if ( sGroupFunctionName.Equals(sFunctionName) ) // check if the function name is GROUP
1121 					{
1122 						bGroupBy = sal_True;
1123 
1124 						if ( !m_bGroupByUnRelated && !pEntry->IsVisible() )
1125 						{
1126 							// we have to change the visblie flag, so we must append also an undo action
1127 							pEntry->SetVisible(sal_True);
1128 							m_pVisibleCell->GetBox().Check();
1129 							appendUndoAction(g_strZero,g_strOne,BROW_VIS_ROW,bListAction);
1130 							RowModified(GetBrowseRow(BROW_VIS_ROW), GetCurColumnId());
1131 						}
1132 
1133 						pEntry->SetFunction(String());
1134 						pEntry->SetFunctionType(pEntry->GetFunctionType() & ~FKT_AGGREGATE );
1135 					}
1136 					else if ( nPos ) // we found an aggregate function
1137 					{
1138 						pEntry->SetFunctionType(pEntry->GetFunctionType() | FKT_AGGREGATE );
1139 						pEntry->SetFunction(sFunctionName);
1140 					}
1141 					else
1142 					{
1143 						sFunctionName = String();
1144 						pEntry->SetFunction(String());
1145 						pEntry->SetFunctionType(pEntry->GetFunctionType() & ~FKT_AGGREGATE );
1146 					}
1147 
1148 					pEntry->SetGroupBy(bGroupBy);
1149 
1150 					sNewValue = sFunctionName;
1151 				}
1152 				break;
1153 			default:
1154 			{
1155 				Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
1156 				if(!xConnection.is())
1157 					break;
1158 
1159 				sal_uInt16	nIdx = sal_uInt16(nRow - BROW_CRIT1_ROW);
1160 				String aText = m_pTextCell->GetText();
1161 
1162 				aText.EraseLeadingChars();
1163 				::rtl::OUString aCrit;
1164 				if(aText.Len())
1165 				{
1166 					::rtl::OUString aErrorMsg;
1167 					Reference<XPropertySet> xColumn;
1168 					OSQLParseNode* pParseNode = getDesignView()->getPredicateTreeFromEntry(pEntry,aText,aErrorMsg,xColumn);
1169 
1170 					if (pParseNode)
1171 					{
1172 						pParseNode->parseNodeToPredicateStr(aCrit,
1173 															xConnection,
1174 															static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
1175 															xColumn,
1176 															getDesignView()->getLocale(),
1177 															static_cast<sal_Char>(getDesignView()->getDecimalSeparator().toChar()),
1178 															&(static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext()));
1179 						delete pParseNode;
1180 					}
1181 					else
1182 					{
1183 						if(xColumn.is())
1184 						{
1185 							sal_Int32 nType = 0;
1186 							xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType;
1187 							switch(nType)
1188 							{
1189 								case DataType::CHAR:
1190 								case DataType::VARCHAR:
1191 								case DataType::LONGVARCHAR:
1192 								case DataType::CLOB:
1193 									if(aText.GetChar(0) != '\'' || aText.GetChar(aText.Len() -1) != '\'')
1194 									{
1195 										aText.SearchAndReplaceAll(String::CreateFromAscii("'"),String::CreateFromAscii("''"));
1196 										String aTmp(String::CreateFromAscii("'"));
1197 										(aTmp += aText) += String::CreateFromAscii("'");
1198 										aText = aTmp;
1199 									}
1200 									break;
1201 								default:
1202 									;
1203 							}
1204 							::connectivity::OSQLParser& rParser = static_cast<OQueryController&>(getDesignView()->getController()).getParser();
1205 							pParseNode = rParser.predicateTree(aErrorMsg,
1206 																aText,
1207 																static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
1208 																xColumn);
1209 							if (pParseNode)
1210 							{
1211 								pParseNode->parseNodeToPredicateStr(aCrit,
1212 																	xConnection,
1213 																	static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
1214 																	xColumn,
1215 																	getDesignView()->getLocale(),
1216 																	static_cast<sal_Char>(getDesignView()->getDecimalSeparator().toChar()),
1217 																	&(static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext()));
1218 								delete pParseNode;
1219 							}
1220 							else
1221 							{
1222 								if ( !m_bDisableErrorBox )
1223 								{
1224 									OSQLWarningBox( this, aErrorMsg ).Execute();
1225 								}
1226 								bError = sal_True;
1227 							}
1228 						}
1229 						else
1230 						{
1231 							if ( !m_bDisableErrorBox )
1232 							{
1233 								OSQLWarningBox( this, aErrorMsg ).Execute();
1234 							}
1235 							bError = sal_True;
1236 						}
1237 					}
1238 					//	}
1239 				}
1240 				strOldCellContents = pEntry->GetCriteria(nIdx);
1241 				pEntry->SetCriteria(nIdx, aCrit);
1242 				sNewValue = pEntry->GetCriteria(nIdx);
1243 				if(aCrit.getLength() && nRow >= (GetRowCount()-1))
1244 					bAppendRow = sal_True;
1245 			}
1246 		}
1247 		if(!bError && Controller())
1248 			Controller()->ClearModified();
1249 
1250 		RowModified(GetCurRow(), GetCurColumnId());
1251 
1252 		if ( bAppendRow )
1253 		{
1254 			RowInserted( GetRowCount()-1, 1, sal_True );
1255 			m_bVisibleRow.push_back(sal_True);
1256 			++m_nVisibleCount;
1257 		}
1258 
1259 		if(!bError)
1260 		{
1261 			// und noch die Undo-Action fuer das Ganze
1262 			appendUndoAction(strOldCellContents,sNewValue,nRow);
1263 
1264 		}
1265 	}
1266 
1267 	// habe ich Daten in einer FieldDescription gespeichert, die vorher leer war und es nach den Aenderungen nicht mehr ist ?
1268 	if ( pEntry.isValid() && bWasEmpty && !pEntry->IsEmpty() && !bError )
1269 	{
1270 		// Default auf sichtbar
1271 		pEntry->SetVisible(sal_True);
1272 		appendUndoAction(g_strZero,g_strOne,BROW_VIS_ROW,bListAction);
1273 		RowModified(BROW_VIS_ROW, GetCurColumnId());
1274 
1275 		// wenn noetig neue freie Spalten anlegen
1276 		sal_uInt16 nDummy;
1277 		CheckFreeColumns(nDummy);
1278 	}
1279 
1280 	if ( bListAction && !m_bInUndoMode )
1281 		static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
1282 
1283 	return pEntry != NULL && !bError;
1284 }
1285 
1286 //------------------------------------------------------------------------------
SeekRow(long nRow)1287 sal_Bool OSelectionBrowseBox::SeekRow(long nRow)
1288 {
1289 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1290 	sal_Bool bRet = sal_False;
1291 
1292 	m_nSeekRow = nRow;
1293 	if (nRow < m_nVisibleCount )
1294 		bRet = sal_True;
1295 
1296 	return bRet;
1297 }
1298 
1299 //------------------------------------------------------------------------------
PaintCell(OutputDevice & rDev,const Rectangle & rRect,sal_uInt16 nColumnId) const1300 void OSelectionBrowseBox::PaintCell(OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId) const
1301 {
1302 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1303 	rDev.SetClipRegion( rRect );
1304 
1305 	OTableFieldDescRef pEntry = NULL;
1306 	sal_uInt16 nPos = GetColumnPos(nColumnId);
1307 	if(getFields().size() > sal_uInt16(nPos - 1))
1308 		pEntry = getFields()[nPos - 1];
1309 
1310 	if (!pEntry.isValid())
1311 		return;
1312 
1313 	long nRow = GetRealRow(m_nSeekRow);
1314 	if (nRow == BROW_VIS_ROW)
1315 		PaintTristate(rDev, rRect, pEntry->IsVisible() ? STATE_CHECK : STATE_NOCHECK);
1316 	else
1317 		rDev.DrawText(rRect, GetCellText(nRow, nColumnId),TEXT_DRAW_VCENTER);
1318 
1319 	rDev.SetClipRegion( );
1320 }
1321 
1322 //------------------------------------------------------------------------------
PaintStatusCell(OutputDevice & rDev,const Rectangle & rRect) const1323 void OSelectionBrowseBox::PaintStatusCell(OutputDevice& rDev, const Rectangle& rRect) const
1324 {
1325 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1326     Rectangle aRect(rRect);
1327     aRect.TopLeft().Y() -= 2;
1328 	String	aLabel(ModuleRes(STR_QUERY_HANDLETEXT));
1329 
1330 	// ab BROW_CRIT2_ROW werden alle Zeilen mit "oder" angegeben
1331 	xub_StrLen nToken = (xub_StrLen) (m_nSeekRow >= GetBrowseRow(BROW_CRIT2_ROW))
1332 								?
1333 			xub_StrLen(BROW_CRIT2_ROW) : xub_StrLen(GetRealRow(m_nSeekRow));
1334 	rDev.DrawText(aRect, aLabel.GetToken(nToken),TEXT_DRAW_VCENTER);
1335 }
1336 
1337 //------------------------------------------------------------------------------
RemoveColumn(sal_uInt16 _nColumnId)1338 void OSelectionBrowseBox::RemoveColumn(sal_uInt16 _nColumnId)
1339 {
1340 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1341 	OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
1342 
1343 	sal_uInt16 nPos = GetColumnPos(_nColumnId);
1344 		// das Control sollte immer genau eine Spalte mehr haben, naemlich die HandleColumn
1345 	DBG_ASSERT((nPos == 0) || (nPos <= getFields().size()), "OSelectionBrowseBox::RemoveColumn : invalid parameter nColId");
1346 		// ColId ist bei mir gleichbedeutend mit Position, und da sollte die Bedingung natuerlich zutreffen
1347 
1348 	sal_uInt16 nCurCol = GetCurColumnId();
1349 	long nCurrentRow = GetCurRow();
1350 
1351 	DeactivateCell();
1352 
1353 	getFields().erase( getFields().begin() + (nPos - 1) );
1354 	OTableFieldDescRef pEntry = new OTableFieldDesc();
1355 	pEntry->SetColumnId(_nColumnId);
1356 	getFields().push_back(pEntry);
1357 
1358 	EditBrowseBox::RemoveColumn( _nColumnId );
1359 	InsertDataColumn( _nColumnId , String(), DEFAULT_SIZE, HIB_STDSTYLE, HEADERBAR_APPEND);
1360 
1361 	// Neuzeichnen
1362 	Rectangle aInvalidRect = GetInvalidRect( _nColumnId );
1363 	Invalidate( aInvalidRect );
1364 
1365 	ActivateCell( nCurrentRow, nCurCol );
1366 
1367 	rController.setModified( sal_True );
1368 
1369 	invalidateUndoRedo();
1370 }
1371 
1372 //------------------------------------------------------------------------------
RemoveField(sal_uInt16 nColumnId)1373 void OSelectionBrowseBox::RemoveField(sal_uInt16 nColumnId )
1374 {
1375 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1376 	OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
1377 
1378 	sal_uInt16 nPos = GetColumnPos(nColumnId);
1379 	OSL_ENSURE(getFields().size() > sal_uInt16(nPos-1),"ID is to great!");
1380 
1381 	OTableFieldDescRef pDesc = getEntry((sal_uInt32)(nPos - 1)) ;
1382 	pDesc->SetColWidth( (sal_uInt16)GetColumnWidth(nColumnId) );	// hat er sich vorher leider nicht gemerkt
1383 
1384 	// UndoAction erzeugen
1385 	if ( !m_bInUndoMode )
1386 	{
1387 		OTabFieldDelUndoAct* pUndoAction = new OTabFieldDelUndoAct( this );
1388 		pUndoAction->SetTabFieldDescr(pDesc);
1389 		pUndoAction->SetColumnPosition(nPos);
1390 		rController.addUndoActionAndInvalidate( pUndoAction );
1391 	}
1392 
1393 	RemoveColumn(nColumnId);
1394 
1395 	invalidateUndoRedo();
1396 }
1397 
1398 //------------------------------------------------------------------------------
adjustSelectionMode(sal_Bool _bClickedOntoHeader,sal_Bool _bClickedOntoHandleCol)1399 void OSelectionBrowseBox::adjustSelectionMode( sal_Bool _bClickedOntoHeader, sal_Bool _bClickedOntoHandleCol )
1400 {
1401 	// wenn ein Header selectiert wird, mu� die selection angezeigt werden, sonst nicht)
1402 	if ( _bClickedOntoHeader )
1403 	{
1404 		if (0 == GetSelectColumnCount() )
1405 			// wenn es schon eine selektierte Spalte gibt, bin ich schon im richtigen Modus
1406 			if ( BROWSER_HIDESELECT == ( m_nMode & BROWSER_HIDESELECT ) )
1407 			{
1408 				m_nMode &= ~BROWSER_HIDESELECT;
1409 				m_nMode |= BROWSER_MULTISELECTION;
1410 				SetMode( m_nMode );
1411 			}
1412 	}
1413 	else if ( BROWSER_HIDESELECT != ( m_nMode & BROWSER_HIDESELECT ) )
1414 	{
1415 		if ( GetSelectColumnCount() != 0 )
1416 			SetNoSelection();
1417 
1418 		if ( _bClickedOntoHandleCol )
1419 		{
1420 			m_nMode |= BROWSER_HIDESELECT;
1421 			m_nMode &= ~BROWSER_MULTISELECTION;
1422 			SetMode( m_nMode );
1423 		}
1424 	}
1425 }
1426 
1427 //------------------------------------------------------------------------------
MouseButtonDown(const BrowserMouseEvent & rEvt)1428 void OSelectionBrowseBox::MouseButtonDown(const BrowserMouseEvent& rEvt)
1429 {
1430 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1431 	if( rEvt.IsLeft() )
1432 	{
1433 		sal_Bool bOnHandle = HANDLE_ID == rEvt.GetColumnId();
1434 		sal_Bool bOnHeader = ( rEvt.GetRow() < 0 ) && !bOnHandle;
1435 		adjustSelectionMode( bOnHeader, bOnHandle );
1436 	}
1437 	EditBrowseBox::MouseButtonDown(rEvt);
1438 }
1439 
1440 //------------------------------------------------------------------------------
MouseButtonUp(const BrowserMouseEvent & rEvt)1441 void OSelectionBrowseBox::MouseButtonUp(const BrowserMouseEvent& rEvt)
1442 {
1443 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1444 	EditBrowseBox::MouseButtonUp( rEvt );
1445 	static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
1446 }
1447 
1448 //------------------------------------------------------------------------------
KeyInput(const KeyEvent & rEvt)1449 void OSelectionBrowseBox::KeyInput( const KeyEvent& rEvt )
1450 {
1451 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1452 	if (IsColumnSelected(GetCurColumnId()))
1453 	{
1454 		if (rEvt.GetKeyCode().GetCode() == KEY_DELETE &&	// Delete rows
1455 			!rEvt.GetKeyCode().IsShift() &&
1456 			!rEvt.GetKeyCode().IsMod1())
1457 		{
1458 			RemoveField(GetCurColumnId());
1459 			return;
1460 		}
1461 	}
1462 	EditBrowseBox::KeyInput(rEvt);
1463 }
1464 
1465 
1466 //------------------------------------------------------------------------------
AcceptDrop(const BrowserAcceptDropEvent & rEvt)1467 sal_Int8 OSelectionBrowseBox::AcceptDrop( const BrowserAcceptDropEvent& rEvt )
1468 {
1469 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1470 	sal_Int8 nDropAction = DND_ACTION_NONE;
1471 	if	( rEvt.GetRow() >= -1 )
1472 	{
1473 		if ( IsEditing() )
1474 		{
1475 			// #100271# OJ allow the asterix again
1476 			m_bDisableErrorBox = sal_True;
1477 			SaveModified();
1478 			m_bDisableErrorBox = sal_False;
1479 			DeactivateCell();
1480 		}
1481 		// check if the format is already supported, if not deactivate the current cell and try again
1482 		if ( OJoinExchObj::isFormatAvailable(GetDataFlavors()) )
1483 			nDropAction = DND_ACTION_LINK;
1484 	}
1485 
1486 	return nDropAction;
1487 }
1488 
1489 //------------------------------------------------------------------------------
ExecuteDrop(const BrowserExecuteDropEvent & _rEvt)1490 sal_Int8 OSelectionBrowseBox::ExecuteDrop( const BrowserExecuteDropEvent& _rEvt )
1491 {
1492 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1493 
1494 	TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
1495 	if (!OJoinExchObj::isFormatAvailable(aDropped.GetDataFlavorExVector()))
1496 	{
1497 		DBG_ERROR("OSelectionBrowseBox::ExecuteDrop: this should never have passed AcceptDrop!");
1498 		return DND_ACTION_NONE;
1499 	}
1500 
1501 	OTableFieldDesc aInfo;
1502 	// Einfuegen des Feldes an der gewuenschten Position
1503 	OJoinExchangeData jxdSource = OJoinExchObj::GetSourceDescription(_rEvt.maDropEvent.Transferable);
1504 	InsertField(jxdSource);
1505 
1506 	return DND_ACTION_LINK;
1507 }
1508 
1509 //------------------------------------------------------------------------------
AppendNewCol(sal_uInt16 nCnt)1510 OTableFieldDescRef OSelectionBrowseBox::AppendNewCol( sal_uInt16 nCnt)
1511 {
1512 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1513 	// es koennen mehrere angelegt werden, aber der Erste
1514 	// wird returnt
1515 	sal_uInt32 nCount = getFields().size();
1516 	for (sal_uInt16 i=0 ; i<nCnt ; i++)
1517 	{
1518 		OTableFieldDescRef pEmptyEntry = new OTableFieldDesc();
1519 		getFields().push_back(pEmptyEntry);
1520 		sal_uInt16 nColumnId = sal::static_int_cast< sal_uInt16 >(getFields().size());
1521 		pEmptyEntry->SetColumnId( nColumnId );
1522 
1523 		InsertDataColumn( nColumnId , String(), DEFAULT_SIZE, HIB_STDSTYLE, HEADERBAR_APPEND);
1524 	}
1525 
1526 	return getFields()[nCount];
1527 }
1528 
1529 //------------------------------------------------------------------------------
DeleteFields(const String & rAliasName)1530 void OSelectionBrowseBox::DeleteFields(const String& rAliasName)
1531 {
1532 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1533 	if (!getFields().empty())
1534 	{
1535 		sal_uInt16 nColId = GetCurColumnId();
1536 		sal_uInt32 nRow = GetCurRow();
1537 
1538 		sal_Bool bWasEditing = IsEditing();
1539 		if (bWasEditing)
1540 			DeactivateCell();
1541 
1542 		OTableFields::reverse_iterator aIter = getFields().rbegin();
1543 		OTableFieldDescRef pEntry = NULL;
1544 		for(sal_uInt16 nPos=sal::static_int_cast< sal_uInt16 >(getFields().size());aIter != getFields().rend();++aIter,--nPos)
1545 		{
1546 			pEntry = *aIter;
1547             if ( pEntry->GetAlias().equals( rAliasName ) )
1548             {
1549 				RemoveField( GetColumnId( nPos ) );
1550                 break;
1551             }
1552 		}
1553 
1554 		if (bWasEditing)
1555 			ActivateCell(nRow , nColId);
1556 	}
1557 }
1558 
1559 //------------------------------------------------------------------------------
SetColWidth(sal_uInt16 nColId,long nNewWidth)1560 void OSelectionBrowseBox::SetColWidth(sal_uInt16 nColId, long nNewWidth)
1561 {
1562 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1563 	sal_Bool bWasEditing = IsEditing();
1564 	if (bWasEditing)
1565 		DeactivateCell();
1566 
1567 	// die Basisklasse machen lassen
1568 	SetColumnWidth(nColId, nNewWidth);
1569 
1570 	// der FieldDescription Bescheid sagen
1571 	OTableFieldDescRef pEntry = getEntry(GetColumnPos(nColId) - 1);
1572 	if (pEntry.isValid())
1573 		pEntry->SetColWidth(sal_uInt16(GetColumnWidth(nColId)));
1574 
1575 	if (bWasEditing)
1576 		ActivateCell(GetCurRow(), GetCurColumnId());
1577 }
1578 
1579 //------------------------------------------------------------------------------
GetInvalidRect(sal_uInt16 nColId)1580 Rectangle OSelectionBrowseBox::GetInvalidRect( sal_uInt16 nColId )
1581 {
1582 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1583 	//////////////////////////////////////////////////////////////////////
1584 	// Rechteck ist erst einmal der gesamte Outputbereich des Fensters
1585 	Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() );
1586 
1587 	//////////////////////////////////////////////////////////////////////
1588 	// Dann wird die linke Seite angepasst
1589 	Rectangle aFieldRect(GetCellRect( 0, nColId ));	// used instead of GetFieldRectPixel
1590 	aInvalidRect.Left() = aFieldRect.Left();
1591 
1592 	return aInvalidRect;
1593 }
1594 
1595 //------------------------------------------------------------------------------
InsertColumn(OTableFieldDescRef pEntry,sal_uInt16 & _nColumnPostion)1596 void OSelectionBrowseBox::InsertColumn(OTableFieldDescRef pEntry, sal_uInt16& _nColumnPostion)
1597 {
1598 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1599 		// das Control sollte immer genau eine Spalte mehr haben, naemlich die HandleColumn
1600 	DBG_ASSERT(_nColumnPostion == BROWSER_INVALIDID || (_nColumnPostion <= (long)getFields().size()), "OSelectionBrowseBox::InsertColumn : invalid parameter nColId.");
1601 		// -1 heisst ganz hinten, Count heisst ganz hinten, der Rest bezeichnet eine richtige Position
1602 
1603 	sal_uInt16 nCurCol = GetCurColumnId();
1604 	long nCurrentRow = GetCurRow();
1605 
1606 	DeactivateCell();
1607 
1608 	// remember the column id of the current positon
1609 	sal_uInt16 nColumnId = GetColumnId(_nColumnPostion);
1610 	// Wenn zu klein oder zu gross, auf Ende der Liste setzen
1611 	if ((_nColumnPostion == BROWSER_INVALIDID) || (_nColumnPostion >= getFields().size()))	 // Anhaengen des Feldes
1612 	{
1613 		if (FindFirstFreeCol(_nColumnPostion) == NULL)	// keine freie Column mehr
1614 		{
1615 			AppendNewCol(1);
1616 			_nColumnPostion = sal::static_int_cast< sal_uInt16 >(
1617                 getFields().size());
1618 		}
1619 		else
1620 			++_nColumnPostion; // innerhalb der vorgegebenen Liste
1621 		nColumnId = GetColumnId(_nColumnPostion);
1622 		pEntry->SetColumnId( nColumnId );
1623 		getFields()[ _nColumnPostion - 1] = pEntry;
1624 	}
1625 
1626 	// check if the column ids are identical, if not we have to move
1627 	if ( pEntry->GetColumnId() != nColumnId )
1628 	{
1629 		sal_uInt16 nOldPosition = GetColumnPos(pEntry->GetColumnId());
1630 		OSL_ENSURE( nOldPosition != 0,"Old position was 0. Not possible!");
1631 		SetColumnPos(pEntry->GetColumnId(),_nColumnPostion);
1632 		// we have to delete an empty field for the fields list, because the columns must have equal length
1633 		if ( nOldPosition > 0 && nOldPosition <= getFields().size() )
1634 			getFields()[nOldPosition - 1] = pEntry;
1635 
1636 		ColumnMoved(pEntry->GetColumnId(),sal_False);
1637 	} // if ( pEntry->GetColumnId() != nColumnId )
1638 
1639     if ( pEntry->GetFunctionType() & (FKT_AGGREGATE) )
1640     {
1641         String sFunctionName = pEntry->GetFunction();
1642         if ( GetFunctionName(sal_uInt32(-1),sFunctionName) )
1643             pEntry->SetFunction(sFunctionName);
1644     }
1645 
1646     nColumnId = pEntry->GetColumnId();
1647 
1648     SetColWidth(nColumnId,getDesignView()->getColWidth(GetColumnPos(nColumnId)-1));
1649 	// Neuzeichnen
1650 	Rectangle aInvalidRect = GetInvalidRect( nColumnId );
1651 	Invalidate( aInvalidRect );
1652 
1653 	ActivateCell( nCurrentRow, nCurCol );
1654 	static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
1655 
1656 	invalidateUndoRedo();
1657 }
1658 
1659 //------------------------------------------------------------------------------
InsertField(const OJoinExchangeData & jxdSource,sal_uInt16 _nColumnPostion,sal_Bool bVis,sal_Bool bActivate)1660 OTableFieldDescRef OSelectionBrowseBox::InsertField(const OJoinExchangeData& jxdSource, sal_uInt16 _nColumnPostion, sal_Bool bVis, sal_Bool bActivate)
1661 {
1662 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1663 	OQueryTableWindow* pSourceWin = static_cast<OQueryTableWindow*>(jxdSource.pListBox->GetTabWin());
1664 	if (!pSourceWin)
1665 		return NULL;
1666 
1667 	// Namen/Position des selektierten Feldes
1668 	String aFieldName = jxdSource.pListBox->GetEntryText(jxdSource.pEntry);
1669 	sal_uInt32 nFieldIndex = jxdSource.pListBox->GetModel()->GetAbsPos(jxdSource.pEntry);
1670 	OTableFieldInfo* pInf = static_cast<OTableFieldInfo*>(jxdSource.pEntry->GetUserData());
1671 
1672 	// eine DragInfo aufbauen, damit ich mich auf das andere InsertField zurueckziehen kann
1673 	OTableFieldDescRef aInfo = new OTableFieldDesc(pSourceWin->GetTableName(),aFieldName);
1674 	aInfo->SetTabWindow(pSourceWin);
1675 	aInfo->SetFieldIndex(nFieldIndex);
1676 	aInfo->SetFieldType(pInf->GetKeyType());
1677 	aInfo->SetAlias(pSourceWin->GetAliasName());
1678 
1679 	aInfo->SetDataType(pInf->GetDataType());
1680 	aInfo->SetVisible(bVis);
1681 
1682 	return InsertField(aInfo, _nColumnPostion, bVis, bActivate);
1683 }
1684 
1685 //------------------------------------------------------------------------------
InsertField(const OTableFieldDescRef & _rInfo,sal_uInt16 _nColumnPostion,sal_Bool bVis,sal_Bool bActivate)1686 OTableFieldDescRef OSelectionBrowseBox::InsertField(const OTableFieldDescRef& _rInfo, sal_uInt16 _nColumnPostion, sal_Bool bVis, sal_Bool bActivate)
1687 {
1688 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1689 
1690 	if(m_nMaxColumns && m_nMaxColumns <= FieldsCount())
1691 		return NULL;
1692 	if (bActivate)
1693 		SaveModified();
1694 
1695 	// Neue Spaltenbeschreibung
1696 	OTableFieldDescRef pEntry = _rInfo;
1697 	pEntry->SetVisible(bVis);
1698 
1699 	// Spalte einfuegen
1700 	InsertColumn( pEntry, _nColumnPostion );
1701 
1702 	if ( !m_bInUndoMode )
1703 	{
1704 		// UndoAction erzeugen
1705 		OTabFieldCreateUndoAct* pUndoAction = new OTabFieldCreateUndoAct( this );
1706 		pUndoAction->SetTabFieldDescr( pEntry );
1707 		pUndoAction->SetColumnPosition(_nColumnPostion);
1708 		getDesignView()->getController().addUndoActionAndInvalidate( pUndoAction );
1709 	}
1710 
1711 	return pEntry;
1712 }
1713 
1714 //------------------------------------------------------------------------------
FieldsCount()1715 sal_uInt16 OSelectionBrowseBox::FieldsCount()
1716 {
1717 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1718 	OTableFields::iterator aIter = getFields().begin();
1719 	sal_uInt16 nCount = 0;
1720 
1721 	while (aIter != getFields().end())
1722 	{
1723 		if ((*aIter).isValid() && !(*aIter)->IsEmpty())
1724 			++nCount;
1725 		++aIter;
1726 	}
1727 
1728 	return nCount;
1729 }
1730 
1731 //------------------------------------------------------------------------------
FindFirstFreeCol(sal_uInt16 & _rColumnPosition)1732 OTableFieldDescRef OSelectionBrowseBox::FindFirstFreeCol(sal_uInt16& _rColumnPosition )
1733 {
1734 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1735 	OTableFields::iterator aIter = getFields().begin();
1736 	OTableFields::iterator aEnd  = getFields().end();
1737 
1738 	_rColumnPosition = BROWSER_INVALIDID;
1739 
1740 	while ( aIter != aEnd )
1741 	{
1742 		++_rColumnPosition;
1743 		OTableFieldDescRef pEntry = (*aIter);
1744 		if ( pEntry.isValid() && pEntry->IsEmpty() )
1745 			return pEntry;
1746 		++aIter;
1747 	}
1748 
1749 	return NULL;
1750 }
1751 
1752 //------------------------------------------------------------------------------
CheckFreeColumns(sal_uInt16 & _rColumnPosition)1753 void OSelectionBrowseBox::CheckFreeColumns(sal_uInt16& _rColumnPosition)
1754 {
1755 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1756 	if (FindFirstFreeCol(_rColumnPosition) == NULL)
1757 	{
1758 		// es ist voll, also einen Packen Spalten anhaengen
1759 		AppendNewCol(DEFAULT_QUERY_COLS);
1760 		OSL_VERIFY(FindFirstFreeCol(_rColumnPosition).isValid());
1761 	}
1762 }
1763 //------------------------------------------------------------------------------
AddGroupBy(const OTableFieldDescRef & rInfo,sal_uInt32)1764 void OSelectionBrowseBox::AddGroupBy( const OTableFieldDescRef& rInfo , sal_uInt32 /*_nCurrentPos*/)
1765 {
1766 	Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
1767 	if(!xConnection.is())
1768 		return;
1769 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1770 	DBG_ASSERT(!rInfo->IsEmpty(),"AddGroupBy:: OTableFieldDescRef sollte nicht Empty sein!");
1771 	OTableFieldDescRef pEntry;
1772 	const Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
1773 	const ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
1774     //sal_Bool bAppend = sal_False;
1775 
1776     OTableFields& rFields = getFields();
1777     OTableFields::iterator aIter = rFields.begin();
1778     OTableFields::iterator aEnd = rFields.end();
1779 	for(;aIter != aEnd;++aIter)
1780 	{
1781 		pEntry = *aIter;
1782 		OSL_ENSURE(pEntry.isValid(),"OTableFieldDescRef was null!");
1783 
1784 		const ::rtl::OUString	aField = pEntry->GetField();
1785 		const ::rtl::OUString	aAlias = pEntry->GetAlias();
1786 
1787 		if (bCase(aField,rInfo->GetField()) &&
1788 			bCase(aAlias,rInfo->GetAlias()) &&
1789 			pEntry->GetFunctionType() == rInfo->GetFunctionType() &&
1790             pEntry->GetFunction() == rInfo->GetFunction())
1791 		{
1792 		    if ( pEntry->isNumericOrAggreateFunction() && rInfo->IsGroupBy() )
1793             {
1794 			    pEntry->SetGroupBy(sal_False);
1795                 aIter = rFields.end();
1796                 break;
1797             }
1798 		    else
1799 		    {
1800                 if ( !pEntry->IsGroupBy() && !pEntry->HasCriteria() ) // here we have a where condition which is no having clause
1801                 {
1802                     pEntry->SetGroupBy(rInfo->IsGroupBy());
1803 			        if(!m_bGroupByUnRelated && pEntry->IsGroupBy())
1804 				        pEntry->SetVisible(sal_True);
1805                     break;
1806                 }
1807 		    }
1808 
1809 		}
1810 	}
1811 
1812 	if (aIter == rFields.end())
1813 	{
1814 		OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, sal_False, sal_False );
1815 		if ( (pTmp->isNumericOrAggreateFunction() && rInfo->IsGroupBy()) ) // das GroupBy wird bereits von rInfo "ubernommen
1816 			pTmp->SetGroupBy(sal_False);
1817 	}
1818 }
1819 //------------------------------------------------------------------------------
DuplicateConditionLevel(const sal_uInt16 nLevel)1820 void OSelectionBrowseBox::DuplicateConditionLevel( const sal_uInt16 nLevel)
1821 {
1822 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1823 	const sal_uInt16 nNewLevel = nLevel +1;
1824 	OTableFields& rFields = getFields();
1825     OTableFields::iterator aIter = rFields.begin();
1826     OTableFields::iterator aEnd = rFields.end();
1827 	for(;aIter != aEnd;++aIter)
1828 	{
1829 		OTableFieldDescRef pEntry = *aIter;
1830 
1831 		::rtl::OUString sValue = pEntry->GetCriteria(nLevel);
1832 		if ( sValue.getLength() )
1833 		{
1834 			pEntry->SetCriteria( nNewLevel, sValue);
1835 			if ( nNewLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1) )
1836 			{
1837 				RowInserted( GetRowCount()-1, 1, sal_True );
1838 				m_bVisibleRow.push_back(sal_True);
1839 				++m_nVisibleCount;
1840 			}
1841             m_bVisibleRow[BROW_CRIT1_ROW + nNewLevel] = sal_True;
1842 		} // if (!pEntry->GetCriteria(nLevel).getLength() )
1843 	} // for(;aIter != getFields().end();++aIter)
1844 }
1845 //------------------------------------------------------------------------------
AddCondition(const OTableFieldDescRef & rInfo,const String & rValue,const sal_uInt16 nLevel,bool _bAddOrOnOneLine)1846 void OSelectionBrowseBox::AddCondition( const OTableFieldDescRef& rInfo, const String& rValue, const sal_uInt16 nLevel,bool _bAddOrOnOneLine )
1847 {
1848 	Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
1849 	if(!xConnection.is())
1850 		return;
1851 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1852 	DBG_ASSERT(rInfo.isValid() && !rInfo->IsEmpty(),"AddCondition:: OTableFieldDescRef sollte nicht Empty sein!");
1853 
1854     OTableFieldDescRef pLastEntry;
1855 	Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
1856 	::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
1857 
1858 	OTableFields& rFields = getFields();
1859     OTableFields::iterator aIter = rFields.begin();
1860     OTableFields::iterator aEnd = rFields.end();
1861 	for(;aIter != aEnd;++aIter)
1862 	{
1863 		OTableFieldDescRef pEntry = *aIter;
1864 		const ::rtl::OUString	aField = pEntry->GetField();
1865 		const ::rtl::OUString	aAlias = pEntry->GetAlias();
1866 
1867 		if (bCase(aField,rInfo->GetField()) &&
1868 			bCase(aAlias,rInfo->GetAlias()) &&
1869 			pEntry->GetFunctionType() == rInfo->GetFunctionType() &&
1870             pEntry->GetFunction() == rInfo->GetFunction() &&
1871             pEntry->IsGroupBy() == rInfo->IsGroupBy() )
1872 		{
1873 			if ( pEntry->isNumericOrAggreateFunction() && rInfo->IsGroupBy() )
1874 				pEntry->SetGroupBy(sal_False);
1875 			else
1876 			{
1877 //				pEntry->SetGroupBy(rInfo->IsGroupBy());
1878 				if(!m_bGroupByUnRelated && pEntry->IsGroupBy())
1879 					pEntry->SetVisible(sal_True);
1880 			}
1881 			if (!pEntry->GetCriteria(nLevel).getLength() )
1882 			{
1883 				pEntry->SetCriteria( nLevel, rValue);
1884 				if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
1885 				{
1886 					RowInserted( GetRowCount()-1, 1, sal_True );
1887 					m_bVisibleRow.push_back(sal_True);
1888 					++m_nVisibleCount;
1889 				}
1890                 m_bVisibleRow[BROW_CRIT1_ROW + nLevel] = sal_True;
1891 				break;
1892 			} // if (!pEntry->GetCriteria(nLevel).getLength() )
1893             if ( _bAddOrOnOneLine )
1894             {
1895                 pLastEntry = pEntry;
1896             }
1897 		}
1898 	} // for(;aIter != getFields().end();++aIter)
1899     if ( pLastEntry.isValid() )
1900     {
1901         String sCriteria = rValue;
1902         String sOldCriteria = pLastEntry->GetCriteria( nLevel );
1903         if ( sOldCriteria.Len() )
1904         {
1905             sCriteria = String(RTL_CONSTASCII_USTRINGPARAM("( "));
1906             sCriteria += sOldCriteria;
1907             sCriteria += String(RTL_CONSTASCII_USTRINGPARAM(" OR "));
1908             sCriteria += rValue;
1909             sCriteria += String(RTL_CONSTASCII_USTRINGPARAM(" )"));
1910         }
1911         pLastEntry->SetCriteria( nLevel, sCriteria);
1912 		if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
1913 		{
1914 			RowInserted( GetRowCount()-1, 1, sal_True );
1915 			m_bVisibleRow.push_back(sal_True);
1916 			++m_nVisibleCount;
1917 		}
1918         m_bVisibleRow[BROW_CRIT1_ROW + nLevel] = sal_True;
1919     }
1920 
1921 	else if (aIter == getFields().end())
1922 	{
1923 		OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, sal_False, sal_False );
1924 		if ( pTmp->isNumericOrAggreateFunction() && rInfo->IsGroupBy() ) // das GroupBy wird bereits von rInfo "ubernommen
1925 			pTmp->SetGroupBy(sal_False);
1926 		if ( pTmp.isValid() )
1927 		{
1928 			pTmp->SetCriteria( nLevel, rValue);
1929 			if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
1930 			{
1931 				RowInserted( GetRowCount()-1, 1, sal_True );
1932 				m_bVisibleRow.push_back(sal_True);
1933 				++m_nVisibleCount;
1934 			}
1935 		}
1936 	}
1937 }
1938 
1939 //------------------------------------------------------------------------------
AddOrder(const OTableFieldDescRef & rInfo,const EOrderDir eDir,sal_uInt32 _nCurrentPos)1940 void OSelectionBrowseBox::AddOrder( const OTableFieldDescRef& rInfo, const EOrderDir eDir, sal_uInt32 _nCurrentPos)
1941 {
1942 	Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
1943 	if(!xConnection.is())
1944 		return;
1945 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1946 	DBG_ASSERT(!rInfo->IsEmpty(),"AddOrder:: OTableFieldDescRef sollte nicht Empty sein!");
1947 	OTableFieldDescRef pEntry;
1948 	Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
1949 	::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
1950 
1951     sal_Bool bAppend = sal_False;
1952     OTableFields& rFields = getFields();
1953     OTableFields::iterator aIter = rFields.begin();
1954     OTableFields::iterator aEnd = rFields.end();
1955 	for(;aIter != aEnd;++aIter)
1956 	{
1957 		pEntry = *aIter;
1958 		::rtl::OUString	aField = pEntry->GetField();
1959 		::rtl::OUString	aAlias = pEntry->GetAlias();
1960 
1961 		if (bCase(aField,rInfo->GetField()) &&
1962 			bCase(aAlias,rInfo->GetAlias()))
1963 		{
1964             sal_uInt32 nPos = aIter - rFields.begin();
1965             bAppend = _nCurrentPos > nPos;
1966             if ( bAppend )
1967                 aIter = rFields.end();
1968             else
1969             {
1970 			    if ( !m_bOrderByUnRelated )
1971 				    pEntry->SetVisible(sal_True);
1972 			    pEntry->SetOrderDir( eDir );
1973             }
1974 			break;
1975 		}
1976 	}
1977 
1978 	if (aIter == rFields.end())
1979 	{
1980 		OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, sal_False, sal_False );
1981 		if(pTmp.isValid())
1982 		{
1983 			if ( !m_bOrderByUnRelated && !bAppend )
1984 				pTmp->SetVisible(sal_True);
1985 			pTmp->SetOrderDir( eDir );
1986 		}
1987 	}
1988 }
1989 
1990 //------------------------------------------------------------------------------
ArrangeControls(sal_uInt16 & nX,sal_uInt16 nY)1991 void OSelectionBrowseBox::ArrangeControls(sal_uInt16& nX, sal_uInt16 nY)
1992 {
1993 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
1994 	EditBrowseBox::ArrangeControls(nX, nY);
1995 }
1996 
1997 //------------------------------------------------------------------------------
Save()1998 sal_Bool OSelectionBrowseBox::Save()
1999 {
2000 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2001 	sal_Bool bRet = sal_True;
2002 	if (IsModified())
2003 		bRet = SaveModified();
2004 	return bRet;
2005 }
2006 
2007 //------------------------------------------------------------------------------
CellModified()2008 void OSelectionBrowseBox::CellModified()
2009 {
2010 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2011 	long nRow = GetRealRow(GetCurRow());
2012 	switch (nRow)
2013 	{
2014 		case BROW_VIS_ROW:
2015 			{
2016 				OTableFieldDescRef	pEntry = getEntry(GetColumnPos(GetCurColumnId()) - 1);
2017 
2018 				sal_uInt16 nIdx = m_pOrderCell->GetSelectEntryPos();
2019 				if(!m_bOrderByUnRelated && nIdx > 0 &&
2020 					nIdx != sal_uInt16(-1)			&&
2021 					!pEntry->IsEmpty()				&&
2022 					pEntry->GetOrderDir() != ORDER_NONE)
2023 				{
2024 					m_pVisibleCell->GetBox().Check();
2025 					pEntry->SetVisible(sal_True);
2026 				}
2027 				else
2028 					pEntry->SetVisible(m_pVisibleCell->GetBox().IsChecked());
2029 			}
2030 			break;
2031 	}
2032 	static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
2033 }
2034 
2035 //------------------------------------------------------------------------------
Fill()2036 void OSelectionBrowseBox::Fill()
2037 {
2038 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2039 	DBG_ASSERT(ColCount() >= 1, "OSelectionBrowseBox::Fill : please call only after inserting the handle column !");
2040 
2041 	sal_uInt16 nColCount = ColCount() - 1;
2042 	if (nColCount < DEFAULT_QUERY_COLS)
2043 		AppendNewCol(DEFAULT_QUERY_COLS - nColCount);
2044 }
2045 
2046 //------------------------------------------------------------------------------
CalcOptimalSize(const Size & _rAvailable)2047 Size OSelectionBrowseBox::CalcOptimalSize( const Size& _rAvailable )
2048 {
2049 	Size aReturn( _rAvailable.Width(), GetTitleHeight() );
2050 
2051 	aReturn.Height() += ( m_nVisibleCount ? m_nVisibleCount : 15 ) * GetDataRowHeight();
2052 	aReturn.Height() += 40;	// just some space
2053 
2054 	return aReturn;
2055 }
2056 
2057 //------------------------------------------------------------------------------
Command(const CommandEvent & rEvt)2058 void OSelectionBrowseBox::Command(const CommandEvent& rEvt)
2059 {
2060 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2061 	switch (rEvt.GetCommand())
2062 	{
2063 		case COMMAND_CONTEXTMENU:
2064 		{
2065 			Point aMenuPos( rEvt.GetMousePosPixel() );
2066 
2067 			if (!rEvt.IsMouseEvent())
2068 			{
2069 				if	( 1 == GetSelectColumnCount() )
2070 				{
2071 					sal_uInt16 nSelId = GetColumnId(
2072                         sal::static_int_cast< sal_uInt16 >(
2073                             FirstSelectedColumn() ) );
2074 					::Rectangle aColRect( GetFieldRectPixel( 0, nSelId, sal_False ) );
2075 
2076 					aMenuPos = aColRect.TopCenter();
2077 				}
2078 				else
2079 				{
2080 					EditBrowseBox::Command(rEvt);
2081 					return;
2082 				}
2083 			}
2084 
2085 			sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel( aMenuPos.X() ));
2086 			long   nRow = GetRowAtYPosPixel( aMenuPos.Y() );
2087 
2088 			if (nRow < 0 && nColId > HANDLE_ID )
2089 			{
2090 				if ( !IsColumnSelected( nColId ) )
2091 				{
2092 					adjustSelectionMode( sal_True /* clicked onto a header */ , sal_False /* not onto the handle col */ );
2093 					SelectColumnId( nColId );
2094 				}
2095 
2096 				if (!static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
2097 				{
2098 					PopupMenu aContextMenu( ModuleRes( RID_QUERYCOLPOPUPMENU ) );
2099 					switch (aContextMenu.Execute(this, aMenuPos))
2100 					{
2101 						case SID_DELETE:
2102 							RemoveField(nColId);
2103 							break;
2104 
2105 						case ID_BROWSER_COLWIDTH:
2106 							adjustBrowseBoxColumnWidth( this, nColId );
2107 							break;
2108 					}
2109 				}
2110 			}
2111 			else if(nRow >= 0 && nColId <= HANDLE_ID)
2112 			{
2113 				if (!static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
2114 				{
2115 					PopupMenu aContextMenu(ModuleRes(RID_QUERYFUNCTION_POPUPMENU));
2116 					aContextMenu.CheckItem( ID_QUERY_FUNCTION, m_bVisibleRow[BROW_FUNCTION_ROW]);
2117 					aContextMenu.CheckItem( ID_QUERY_TABLENAME, m_bVisibleRow[BROW_TABLE_ROW]);
2118 					aContextMenu.CheckItem( ID_QUERY_ALIASNAME, m_bVisibleRow[BROW_COLUMNALIAS_ROW]);
2119 					aContextMenu.CheckItem( ID_QUERY_DISTINCT, static_cast<OQueryController&>(getDesignView()->getController()).isDistinct());
2120 
2121 					switch (aContextMenu.Execute(this, aMenuPos))
2122 					{
2123 						case ID_QUERY_FUNCTION:
2124 							SetRowVisible(BROW_FUNCTION_ROW, !IsRowVisible(BROW_FUNCTION_ROW));
2125 							static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_FUNCTIONS );
2126 							break;
2127 						case ID_QUERY_TABLENAME:
2128 							SetRowVisible(BROW_TABLE_ROW, !IsRowVisible(BROW_TABLE_ROW));
2129 							static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_TABLES );
2130 							break;
2131 						case ID_QUERY_ALIASNAME:
2132 							SetRowVisible(BROW_COLUMNALIAS_ROW, !IsRowVisible(BROW_COLUMNALIAS_ROW));
2133 							static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_ALIASES );
2134 							break;
2135 						case ID_QUERY_DISTINCT:
2136 							static_cast<OQueryController&>(getDesignView()->getController()).setDistinct(!static_cast<OQueryController&>(getDesignView()->getController()).isDistinct());
2137 							static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
2138 							static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_DISTINCT_VALUES );
2139 							break;
2140 					}
2141 
2142 					static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
2143 				}
2144 			}
2145 			else
2146 			{
2147 				EditBrowseBox::Command(rEvt);
2148 				return;
2149 			}
2150 		}
2151 		default:
2152 			EditBrowseBox::Command(rEvt);
2153 	}
2154 }
2155 
2156 //------------------------------------------------------------------------------
IsRowVisible(sal_uInt16 _nWhich) const2157 sal_Bool OSelectionBrowseBox::IsRowVisible(sal_uInt16 _nWhich) const
2158 {
2159 	DBG_ASSERT(_nWhich<(m_bVisibleRow.size()), "OSelectionBrowseBox::IsRowVisible : invalid parameter !");
2160 	return m_bVisibleRow[_nWhich];
2161 }
2162 
2163 //------------------------------------------------------------------------------
SetRowVisible(sal_uInt16 _nWhich,sal_Bool _bVis)2164 void OSelectionBrowseBox::SetRowVisible(sal_uInt16 _nWhich, sal_Bool _bVis)
2165 {
2166 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2167 	DBG_ASSERT(_nWhich<m_bVisibleRow.size(), "OSelectionBrowseBox::SetRowVisible : invalid parameter !");
2168 
2169 	sal_Bool bWasEditing = IsEditing();
2170 	if (bWasEditing)
2171 		DeactivateCell();
2172 
2173 	// do this before removing or inserting rows, as this triggers ActivateCell-calls, which rely on m_bVisibleRow
2174 	m_bVisibleRow[_nWhich] = !m_bVisibleRow[_nWhich];
2175 
2176 	long nId = GetBrowseRow(_nWhich);
2177 	if (_bVis)
2178 	{
2179 		RowInserted(nId,1);
2180 		++m_nVisibleCount;
2181 	}
2182 	else
2183 	{
2184 		RowRemoved(nId,1);
2185 		--m_nVisibleCount;
2186 	}
2187 
2188 	if (bWasEditing)
2189 		ActivateCell();
2190 }
2191 
2192 //------------------------------------------------------------------------------
GetBrowseRow(long nRowId) const2193 long OSelectionBrowseBox::GetBrowseRow(long nRowId) const
2194 {
2195 	sal_uInt16 nCount(0);
2196 	for(sal_uInt16 i = 0 ; i < nRowId ; ++i)
2197 	{
2198 		if ( m_bVisibleRow[i] )
2199 			++nCount;
2200 	}
2201 	return nCount;
2202 }
2203 //------------------------------------------------------------------------------
GetRealRow(long nRowId) const2204 long OSelectionBrowseBox::GetRealRow(long nRowId) const
2205 {
2206 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2207 	long nErg=0,i;
2208 	const long nCount = m_bVisibleRow.size();
2209 	for(i=0;i < nCount; ++i)
2210 	{
2211 		if(m_bVisibleRow[i])
2212 		{
2213 			if(nErg++ == nRowId)
2214 				break;
2215 		}
2216 	}
2217 	DBG_ASSERT(nErg <= long(m_bVisibleRow.size()),"nErg kann nicht groesser als BROW_ROW_CNT sein!");
2218 	return i;
2219 }
2220 static long nVisibleRowMask[] =
2221 					{
2222 							0x0001,
2223 							0x0002,
2224 							0x0004,
2225 							0x0008,
2226 							0x0010,
2227 							0x0020,
2228 							0x0040,
2229 							0x0080,
2230 							0x0100,
2231 							0x0200,
2232 							0x0400,
2233 							0x0800
2234 					};
2235 //------------------------------------------------------------------------------
GetNoneVisibleRows() const2236 sal_Int32 OSelectionBrowseBox::GetNoneVisibleRows() const
2237 {
2238 	sal_Int32 nErg(0);
2239 	// only the first 11 row are interesting
2240 	sal_Int32 nSize = sizeof(nVisibleRowMask) / sizeof(nVisibleRowMask[0]);
2241 	for(sal_Int32 i=0;i<nSize;i++)
2242 	{
2243 		if(!m_bVisibleRow[i])
2244 			nErg |= nVisibleRowMask[i];
2245 	}
2246 	return nErg;
2247 }
2248 //------------------------------------------------------------------------------
SetNoneVisbleRow(long nRows)2249 void OSelectionBrowseBox::SetNoneVisbleRow(long nRows)
2250 {
2251 	// only the first 11 row are interesting
2252 	sal_Int32 nSize = sizeof(nVisibleRowMask) / sizeof(nVisibleRowMask[0]);
2253 	for(sal_Int32 i=0;i< nSize;i++)
2254 		m_bVisibleRow[i] = !(nRows & nVisibleRowMask[i]);
2255 }
2256 //------------------------------------------------------------------------------
GetCellText(long nRow,sal_uInt16 nColId) const2257 String OSelectionBrowseBox::GetCellText(long nRow, sal_uInt16 nColId) const
2258 {
2259 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2260 
2261 	sal_uInt16 nPos = GetColumnPos(nColId);
2262 
2263 	OTableFieldDescRef pEntry = getFields()[nPos-1];
2264 	DBG_ASSERT(pEntry != NULL, "OSelectionBrowseBox::GetCellText : invalid column id, prepare for GPF ... ");
2265 	if ( pEntry->IsEmpty() )
2266 		return String();
2267 
2268 	String aText;
2269 	switch (nRow)
2270 	{
2271 		case BROW_TABLE_ROW:
2272 			aText = pEntry->GetAlias();
2273 			break;
2274 		case BROW_FIELD_ROW:
2275 		{
2276 			String aField = pEntry->GetField();
2277 			if (aField.GetChar(0) == '*')					// * durch alias.* ersetzen
2278 			{
2279 				aField = pEntry->GetAlias();
2280 				if(aField.Len())
2281 					aField += '.';
2282 				aField += '*';
2283 			}
2284 			aText = aField;
2285 		}	break;
2286 		case BROW_ORDER_ROW:
2287 			if (pEntry->GetOrderDir() != ORDER_NONE)
2288 				aText = String(ModuleRes(STR_QUERY_SORTTEXT) ).GetToken(sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()));
2289 			break;
2290 		case BROW_VIS_ROW:
2291 			break;
2292 		case BROW_COLUMNALIAS_ROW:
2293 			aText = pEntry->GetFieldAlias();
2294 			break;
2295 		case BROW_FUNCTION_ROW:
2296 			// we always show the group function at first
2297 			if ( pEntry->IsGroupBy() )
2298 				aText = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
2299 			else if ( pEntry->isNumericOrAggreateFunction() )
2300 				aText = pEntry->GetFunction();
2301 			break;
2302 		default:
2303 			aText = pEntry->GetCriteria(sal_uInt16(nRow - BROW_CRIT1_ROW));
2304 	}
2305 	return aText;
2306 }
2307 //------------------------------------------------------------------------------
GetFunctionName(sal_uInt32 _nFunctionTokenId,String & rFkt)2308 sal_Bool OSelectionBrowseBox::GetFunctionName(sal_uInt32 _nFunctionTokenId,String& rFkt)
2309 {
2310 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2311 	sal_Bool bErg=sal_True;
2312 	String aText;
2313 	switch(_nFunctionTokenId)
2314 	{
2315 		case SQL_TOKEN_COUNT:
2316 			rFkt = (m_pFunctionCell->GetEntryCount() < 3) ? m_pFunctionCell->GetEntry(1) : m_pFunctionCell->GetEntry(2);
2317 			break;
2318 		case SQL_TOKEN_AVG:
2319 			rFkt = m_pFunctionCell->GetEntry(1);
2320 			break;
2321 		case SQL_TOKEN_MAX:
2322 			rFkt = m_pFunctionCell->GetEntry(3);
2323 			break;
2324 		case SQL_TOKEN_MIN:
2325 			rFkt = m_pFunctionCell->GetEntry(4);
2326 			break;
2327 		case SQL_TOKEN_SUM:
2328 			rFkt = m_pFunctionCell->GetEntry(5);
2329 			break;
2330         case SQL_TOKEN_EVERY:
2331 			rFkt = m_pFunctionCell->GetEntry(6);
2332 			break;
2333         case SQL_TOKEN_ANY:
2334 			rFkt = m_pFunctionCell->GetEntry(7);
2335 			break;
2336         case SQL_TOKEN_SOME:
2337 			rFkt = m_pFunctionCell->GetEntry(8);
2338 			break;
2339         case SQL_TOKEN_STDDEV_POP:
2340 			rFkt = m_pFunctionCell->GetEntry(9);
2341 			break;
2342         case SQL_TOKEN_STDDEV_SAMP:
2343 			rFkt = m_pFunctionCell->GetEntry(10);
2344 			break;
2345         case SQL_TOKEN_VAR_SAMP:
2346 			rFkt = m_pFunctionCell->GetEntry(11);
2347 			break;
2348         case SQL_TOKEN_VAR_POP:
2349 			rFkt = m_pFunctionCell->GetEntry(12);
2350 			break;
2351         case SQL_TOKEN_COLLECT:
2352 			rFkt = m_pFunctionCell->GetEntry(13);
2353 			break;
2354         case SQL_TOKEN_FUSION:
2355 			rFkt = m_pFunctionCell->GetEntry(14);
2356 			break;
2357         case SQL_TOKEN_INTERSECTION:
2358 			rFkt = m_pFunctionCell->GetEntry(15);
2359 			break;
2360 		default:
2361 			{
2362 				xub_StrLen nCount = m_aFunctionStrings.GetTokenCount();
2363 				xub_StrLen i;
2364 				for ( i = 0; i < nCount-1; i++) // Gruppierung wird nicht mit gez"ahlt
2365 				{
2366 					if(rFkt.EqualsIgnoreCaseAscii(m_aFunctionStrings.GetToken(i)))
2367 					{
2368 						rFkt = m_aFunctionStrings.GetToken(i);
2369 						break;
2370 					}
2371 				}
2372 				if(i == nCount-1)
2373 					bErg = sal_False;
2374 			}
2375 	}
2376 
2377 	return bErg;
2378 }
2379 //------------------------------------------------------------------------------
GetCellContents(sal_Int32 nCellIndex,sal_uInt16 nColId)2380 String OSelectionBrowseBox::GetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId)
2381 {
2382 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2383 	//	DBG_ASSERT(nCellIndex <	(GetRowCount()-1),"CellIndex ist zu gross");
2384 	if ( GetCurColumnId() == nColId && !m_bInUndoMode )
2385 		SaveModified();
2386 
2387 	sal_uInt16 nPos = GetColumnPos(nColId);
2388 	OTableFieldDescRef pEntry = getFields()[nPos - 1];
2389 	DBG_ASSERT(pEntry != NULL, "OSelectionBrowseBox::GetCellContents : invalid column id, prepare for GPF ... ");
2390 
2391 	switch (nCellIndex)
2392 	{
2393 		case BROW_VIS_ROW :
2394 			return pEntry->IsVisible() ? g_strOne : g_strZero;
2395 		case BROW_ORDER_ROW:
2396 		{
2397 			sal_uInt16 nIdx = m_pOrderCell->GetSelectEntryPos();
2398 			if (nIdx == sal_uInt16(-1))
2399 				nIdx = 0;
2400 			return String(nIdx);
2401 		}
2402 		default:
2403 			return GetCellText(nCellIndex, nColId);
2404 	}
2405 }
2406 
2407 //------------------------------------------------------------------------------
SetCellContents(sal_Int32 nRow,sal_uInt16 nColId,const String & strNewText)2408 void OSelectionBrowseBox::SetCellContents(sal_Int32 nRow, sal_uInt16 nColId, const String& strNewText)
2409 {
2410 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2411 	sal_Bool bWasEditing = IsEditing() && (GetCurColumnId() == nColId) && IsRowVisible(static_cast<sal_uInt16>(nRow)) && (GetCurRow() == static_cast<sal_uInt16>(GetBrowseRow(nRow)));
2412 	if (bWasEditing)
2413 		DeactivateCell();
2414 
2415 	sal_uInt16 nPos = GetColumnPos(nColId);
2416 	OTableFieldDescRef pEntry = getEntry(nPos - 1);
2417 	DBG_ASSERT(pEntry != NULL, "OSelectionBrowseBox::SetCellContents : invalid column id, prepare for GPF ... ");
2418 
2419 
2420 	switch (nRow)
2421 	{
2422 		case BROW_VIS_ROW:
2423 			pEntry->SetVisible(strNewText.Equals(g_strOne));
2424 			break;
2425 		case BROW_FIELD_ROW:
2426 			pEntry->SetField(strNewText);
2427 			break;
2428 		case BROW_TABLE_ROW:
2429 			pEntry->SetAlias(strNewText);
2430 			break;
2431 		case BROW_ORDER_ROW:
2432 		{
2433 			sal_uInt16 nIdx = (sal_uInt16)strNewText.ToInt32();
2434 			pEntry->SetOrderDir(EOrderDir(nIdx));
2435 		}	break;
2436 		case BROW_COLUMNALIAS_ROW:
2437 			pEntry->SetFieldAlias(strNewText);
2438 			break;
2439 		case BROW_FUNCTION_ROW:
2440 		{
2441 			String sOldFunctionName   = pEntry->GetFunction();
2442 			String sGroupFunctionName = m_aFunctionStrings.GetToken(m_aFunctionStrings.GetTokenCount()-1);
2443 			pEntry->SetFunction(strNewText);
2444 			// first reset this two member
2445 			sal_Int32 nFunctionType = pEntry->GetFunctionType();
2446 			nFunctionType &= ~FKT_AGGREGATE;
2447 			pEntry->SetFunctionType(nFunctionType);
2448 			if ( pEntry->IsGroupBy() && !sGroupFunctionName.EqualsIgnoreCaseAscii(strNewText) )
2449 				pEntry->SetGroupBy(sal_False);
2450 
2451 
2452 			if ( sGroupFunctionName.EqualsIgnoreCaseAscii(strNewText) )
2453 				pEntry->SetGroupBy(sal_True);
2454 			else if ( strNewText.Len() )
2455 			{
2456 				nFunctionType |= FKT_AGGREGATE;
2457 				pEntry->SetFunctionType(nFunctionType);
2458 			}
2459 		}	break;
2460 		default:
2461 			pEntry->SetCriteria(sal_uInt16(nRow - BROW_CRIT1_ROW), strNewText);
2462 	}
2463 
2464 	long nCellIndex = GetRealRow(nRow);
2465 	if(IsRowVisible(static_cast<sal_uInt16>(nRow)))
2466 		RowModified(nCellIndex, nColId);
2467 
2468 	// die entsprechende Feld-Beschreibung ist jetzt leer -> Visible auf sal_False (damit das konsistent mit normalen leeren Spalten ist)
2469 	if (pEntry->IsEmpty())
2470 		pEntry->SetVisible(sal_False);
2471 
2472 	if (bWasEditing)
2473 		ActivateCell(nCellIndex, nColId);
2474 
2475 	static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
2476 }
2477 //------------------------------------------------------------------------------
GetTotalCellWidth(long nRow,sal_uInt16 nColId) const2478 sal_uInt32 OSelectionBrowseBox::GetTotalCellWidth(long nRow, sal_uInt16 nColId) const
2479 {
2480 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2481 
2482 	long nRowId = GetRealRow(nRow);
2483 	if (nRowId == BROW_VIS_ROW)
2484 		return CHECKBOX_SIZE;
2485 	else
2486 		return  GetDataWindow().GetTextWidth(GetCellText(nRowId, nColId));
2487 }
2488 
2489 //------------------------------------------------------------------------------
ColumnResized(sal_uInt16 nColId)2490 void OSelectionBrowseBox::ColumnResized(sal_uInt16 nColId)
2491 {
2492 	if (static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
2493 		return;
2494 	// The resizing of columns can't be suppressed (BrowseBox doesn't support that) so we have to do this
2495 	// fake. It's not _that_ bad : the user may change column widths while in read-only mode to see all details
2496 	// but the changes aren't permanent ...
2497 
2498 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2499 	sal_uInt16 nPos = GetColumnPos(nColId);
2500 	DBG_ASSERT(nPos <= getFields().size(),"ColumnResized:: nColId sollte nicht groesser als List::count sein!");
2501 	OTableFieldDescRef pEntry = getEntry(nPos-1);
2502 	DBG_ASSERT(pEntry.isValid(), "OSelectionBrowseBox::ColumnResized : keine FieldDescription !");
2503 	static_cast<OQueryController&>(getDesignView()->getController()).setModified( sal_True );
2504 	EditBrowseBox::ColumnResized(nColId);
2505 
2506 	if ( pEntry.isValid())
2507 	{
2508 		if ( !m_bInUndoMode )
2509 		{
2510 			// create the undo action
2511 			OTabFieldSizedUndoAct* pUndo = new OTabFieldSizedUndoAct(this);
2512 			pUndo->SetColumnPosition( nPos );
2513 			pUndo->SetOriginalWidth(pEntry->GetColWidth());
2514 			getDesignView()->getController().addUndoActionAndInvalidate(pUndo);
2515 		}
2516 		pEntry->SetColWidth(sal_uInt16(GetColumnWidth(nColId)));
2517 	}
2518 }
2519 
2520 //------------------------------------------------------------------------------
GetTotalCellWidth(long nRowId,sal_uInt16 nColId)2521 sal_uInt32 OSelectionBrowseBox::GetTotalCellWidth(long nRowId, sal_uInt16 nColId)
2522 {
2523 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2524 	sal_uInt16 nPos = GetColumnPos(nColId);
2525 	DBG_ASSERT((nPos == 0) || (nPos <= getFields().size()), "OSelectionBrowseBox::GetTotalCellWidth : invalid parameter nColId");
2526 
2527 	OTableFieldDescRef pEntry = getFields()[nPos-1];
2528 	DBG_ASSERT(pEntry.isValid(), "OSelectionBrowseBox::GetTotalCellWidth : invalid FieldDescription !");
2529 
2530 	long nRow = GetRealRow(nRowId);
2531 	String strText(GetCellText(nRow, nColId));
2532 	return GetDataWindow().LogicToPixel(Size(GetDataWindow().GetTextWidth(strText),0)).Width();
2533 }
2534 
2535 //------------------------------------------------------------------------------
GetDefaultColumnWidth(const String &) const2536 sal_uInt16 OSelectionBrowseBox::GetDefaultColumnWidth(const String& /*rName*/) const
2537 {
2538 	DBG_CHKTHIS(OSelectionBrowseBox,NULL);
2539 	// die Baissklasse macht das von dem Text abhaengig, ich habe aber keine Spaltenueberschriften, daher haette ich
2540 	// hier gern einen anderen Default-Wert
2541 	return static_cast<sal_uInt16>(DEFAULT_SIZE);
2542 }
2543 //------------------------------------------------------------------------------
isCutAllowed()2544 sal_Bool OSelectionBrowseBox::isCutAllowed()
2545 {
2546 	sal_Bool bCutAllowed = sal_False;
2547 	long nRow = GetRealRow(GetCurRow());
2548 	switch (nRow)
2549 	{
2550 		case BROW_VIS_ROW:
2551 		case BROW_ORDER_ROW:
2552 		case BROW_TABLE_ROW:
2553 		case BROW_FUNCTION_ROW:
2554 			break;
2555 		case BROW_FIELD_ROW:
2556 			bCutAllowed = m_pFieldCell->GetSelected().Len() != 0;
2557 			break;
2558 		default:
2559 			bCutAllowed = m_pTextCell->GetSelected().Len() != 0;
2560 			break;
2561 	}
2562 	return bCutAllowed;
2563 }
2564 // -----------------------------------------------------------------------------
cut()2565 void OSelectionBrowseBox::cut()
2566 {
2567 	String sOldValue = GetCellContents(GetRealRow(GetCurRow()),GetCurColumnId());
2568 	long nRow = GetRealRow(GetCurRow());
2569 	switch (nRow)
2570 	{
2571 		case BROW_FIELD_ROW:
2572 			m_pFieldCell->Cut();
2573 			m_pFieldCell->SetModifyFlag();
2574 			break;
2575 		default:
2576 			m_pTextCell->Cut();
2577 			m_pTextCell->SetModifyFlag();
2578 	}
2579 	SaveModified();
2580 	RowModified(GetBrowseRow(nRow), GetCurColumnId());
2581 
2582 	invalidateUndoRedo();
2583 }
2584 // -----------------------------------------------------------------------------
paste()2585 void OSelectionBrowseBox::paste()
2586 {
2587 	long nRow = GetRealRow(GetCurRow());
2588 	switch (nRow)
2589 	{
2590 		case BROW_FIELD_ROW:
2591 			m_pFieldCell->Paste();
2592 			m_pFieldCell->SetModifyFlag();
2593 			break;
2594 		default:
2595 			m_pTextCell->Paste();
2596 			m_pTextCell->SetModifyFlag();
2597 	}
2598 	RowModified(GetBrowseRow(nRow), GetCurColumnId());
2599 	invalidateUndoRedo();
2600 }
2601 // -----------------------------------------------------------------------------
isPasteAllowed()2602 sal_Bool OSelectionBrowseBox::isPasteAllowed()
2603 {
2604 	sal_Bool bPasteAllowed = sal_True;
2605 	long nRow = GetRealRow(GetCurRow());
2606 	switch (nRow)
2607 	{
2608 		case BROW_VIS_ROW:
2609 		case BROW_ORDER_ROW:
2610 		case BROW_TABLE_ROW:
2611 		case BROW_FUNCTION_ROW:
2612 			bPasteAllowed = sal_False;
2613 			break;
2614 	}
2615 	return bPasteAllowed;
2616 }
2617 // -----------------------------------------------------------------------------
isCopyAllowed()2618 sal_Bool OSelectionBrowseBox::isCopyAllowed()
2619 {
2620 	return isCutAllowed();
2621 }
2622 // -----------------------------------------------------------------------------
copy()2623 void OSelectionBrowseBox::copy()
2624 {
2625 	long nRow = GetRealRow(GetCurRow());
2626 	switch (nRow)
2627 	{
2628 		case BROW_FIELD_ROW:
2629 			m_pFieldCell->Copy();
2630 			break;
2631 		default:
2632 			m_pTextCell->Copy();
2633 	}
2634 }
2635 // -----------------------------------------------------------------------------
appendUndoAction(const String & _rOldValue,const String & _rNewValue,sal_Int32 _nRow,sal_Bool & _bListAction)2636 void OSelectionBrowseBox::appendUndoAction(const String& _rOldValue,const String& _rNewValue,sal_Int32 _nRow,sal_Bool& _bListAction)
2637 {
2638 	if ( !m_bInUndoMode && !_rNewValue.Equals(_rOldValue) )
2639 	{
2640 		if ( !_bListAction )
2641 		{
2642 			_bListAction = sal_True;
2643 			static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().EnterListAction(String(),String());
2644 		}
2645 		appendUndoAction(_rOldValue,_rNewValue,_nRow);
2646 	}
2647 }
2648 // -----------------------------------------------------------------------------
appendUndoAction(const String & _rOldValue,const String & _rNewValue,sal_Int32 _nRow)2649 void OSelectionBrowseBox::appendUndoAction(const String& _rOldValue,const String& _rNewValue,sal_Int32 _nRow)
2650 {
2651 	if ( !m_bInUndoMode && !_rNewValue.Equals(_rOldValue) )
2652 	{
2653 		OTabFieldCellModifiedUndoAct* pUndoAct = new OTabFieldCellModifiedUndoAct(this);
2654 		pUndoAct->SetCellIndex(_nRow);
2655 		OSL_ENSURE(GetColumnPos(GetCurColumnId()) != BROWSER_INVALIDID,"Current position isn't valid!");
2656 		pUndoAct->SetColumnPosition( GetColumnPos(GetCurColumnId()) );
2657 		pUndoAct->SetCellContents(_rOldValue);
2658 		getDesignView()->getController().addUndoActionAndInvalidate(pUndoAct);
2659 	}
2660 }
2661 // -----------------------------------------------------------------------------
IMPL_LINK(OSelectionBrowseBox,OnInvalidateTimer,void *,EMPTYARG)2662 IMPL_LINK(OSelectionBrowseBox, OnInvalidateTimer, void*, EMPTYARG)
2663 {
2664 	static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_CUT);
2665 	static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_COPY);
2666 	static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_PASTE);
2667 	if(!m_bStopTimer)
2668 		m_timerInvalidate.Start();
2669 	return 0L;
2670 }
2671 // -----------------------------------------------------------------------------
stopTimer()2672 void OSelectionBrowseBox::stopTimer()
2673 {
2674 	m_bStopTimer = sal_True;
2675 	if (m_timerInvalidate.IsActive())
2676 		m_timerInvalidate.Stop();
2677 }
2678 // -----------------------------------------------------------------------------
startTimer()2679 void OSelectionBrowseBox::startTimer()
2680 {
2681 	m_bStopTimer = sal_False;
2682 	if (!m_timerInvalidate.IsActive())
2683 		m_timerInvalidate.Start();
2684 }
2685 // -----------------------------------------------------------------------------
getFields() const2686 OTableFields& OSelectionBrowseBox::getFields() const
2687 {
2688 	OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
2689 	return rController.getTableFieldDesc();
2690 }
2691 // -----------------------------------------------------------------------------
enableControl(const OTableFieldDescRef & _rEntry,Window * _pControl)2692 void OSelectionBrowseBox::enableControl(const OTableFieldDescRef& _rEntry,Window* _pControl)
2693 {
2694 	sal_Bool bEnable = !_rEntry->isCondition();
2695 	_pControl->Enable(bEnable);
2696 	_pControl->EnableInput(bEnable);
2697 }
2698 // -----------------------------------------------------------------------------
setTextCellContext(const OTableFieldDescRef & _rEntry,const String & _sText,const rtl::OString & _sHelpId)2699 void OSelectionBrowseBox::setTextCellContext(const OTableFieldDescRef& _rEntry,const String& _sText,const rtl::OString& _sHelpId)
2700 {
2701 	m_pTextCell->SetText(_sText);
2702 	m_pTextCell->ClearModifyFlag();
2703 	if (!m_pTextCell->HasFocus())
2704 		m_pTextCell->GrabFocus();
2705 
2706 	enableControl(_rEntry,m_pTextCell);
2707 
2708 	if (m_pTextCell->GetHelpId() != _sHelpId)
2709 		// da TextCell in verschiedenen Kontexten verwendet wird, muss ich den gecachten HelpText loeschen
2710 		m_pTextCell->SetHelpText(String());
2711 	m_pTextCell->SetHelpId(_sHelpId);
2712 }
2713 // -----------------------------------------------------------------------------
invalidateUndoRedo()2714 void OSelectionBrowseBox::invalidateUndoRedo()
2715 {
2716 	OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
2717 	rController.InvalidateFeature( ID_BROWSER_UNDO );
2718 	rController.InvalidateFeature( ID_BROWSER_REDO );
2719 	rController.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
2720 }
2721 // -----------------------------------------------------------------------------
getEntry(OTableFields::size_type _nPos)2722 OTableFieldDescRef OSelectionBrowseBox::getEntry(OTableFields::size_type _nPos)
2723 {
2724 	// we have to check if we need a new entry at this position
2725 	OTableFields& aFields = getFields();
2726 	OSL_ENSURE(aFields.size() > _nPos,"ColID is to great!");
2727 
2728 	OTableFieldDescRef pEntry = aFields[_nPos];
2729 	OSL_ENSURE(pEntry.isValid(),"Invalid entry!");
2730 	if ( !pEntry.isValid() )
2731 	{
2732 		pEntry = new OTableFieldDesc();
2733 		pEntry->SetColumnId(
2734             GetColumnId(sal::static_int_cast< sal_uInt16 >(_nPos+1)));
2735 		aFields[_nPos] = pEntry;
2736 	}
2737 	return pEntry;
2738 }
2739 // -----------------------------------------------------------------------------
GetFocus()2740 void OSelectionBrowseBox::GetFocus()
2741 {
2742 	if(!IsEditing() && !m_bWasEditing)
2743 		ActivateCell();
2744 	EditBrowseBox::GetFocus();
2745 }
2746 // -----------------------------------------------------------------------------
DeactivateCell(sal_Bool _bUpdate)2747 void OSelectionBrowseBox::DeactivateCell(sal_Bool _bUpdate)
2748 {
2749 	m_bWasEditing = sal_True;
2750 	EditBrowseBox::DeactivateCell(_bUpdate);
2751 	m_bWasEditing = sal_False;
2752 }
2753 // -----------------------------------------------------------------------------
GetRowDescription(sal_Int32 _nRow) const2754 ::rtl::OUString OSelectionBrowseBox::GetRowDescription( sal_Int32 _nRow ) const
2755 {
2756 	String	aLabel(ModuleRes(STR_QUERY_HANDLETEXT));
2757 
2758 	// ab BROW_CRIT2_ROW werden alle Zeilen mit "oder" angegeben
2759 	xub_StrLen nToken = (xub_StrLen) (_nRow >= GetBrowseRow(BROW_CRIT2_ROW))
2760 								?
2761 			xub_StrLen(BROW_CRIT2_ROW) : xub_StrLen(GetRealRow(_nRow));
2762 	return ::rtl::OUString(aLabel.GetToken(nToken));
2763 }
2764 // -----------------------------------------------------------------------------
GetAccessibleObjectName(::svt::AccessibleBrowseBoxObjType _eObjType,sal_Int32 _nPosition) const2765 ::rtl::OUString	OSelectionBrowseBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eObjType,sal_Int32 _nPosition) const
2766 {
2767 	::rtl::OUString sRetText;
2768     switch( _eObjType )
2769     {
2770 		case ::svt::BBTYPE_ROWHEADERCELL:
2771 			sRetText = GetRowDescription(_nPosition);
2772 			break;
2773 		default:
2774 			sRetText = EditBrowseBox::GetAccessibleObjectDescription(_eObjType,_nPosition);
2775     }
2776     return sRetText;
2777 }
2778 // -----------------------------------------------------------------------------
fillEntryTable(OTableFieldDescRef & _pEntry,const::rtl::OUString & _sTableName)2779 sal_Bool OSelectionBrowseBox::fillEntryTable(OTableFieldDescRef& _pEntry,const ::rtl::OUString& _sTableName)
2780 {
2781 	sal_Bool bRet = sal_False;
2782 	OJoinTableView::OTableWindowMap* pTabWinList = getDesignView()->getTableView()->GetTabWinMap();
2783 	if (pTabWinList)
2784 	{
2785 		OJoinTableView::OTableWindowMapIterator aIter = pTabWinList->find(_sTableName);
2786 		if(aIter != pTabWinList->end())
2787 		{
2788 			OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(aIter->second);
2789 			if (pEntryTab)
2790 			{
2791 				_pEntry->SetTable(pEntryTab->GetTableName());
2792 				_pEntry->SetTabWindow(pEntryTab);
2793 				bRet = sal_True;
2794 			}
2795 		}
2796 	}
2797 	return bRet;
2798 }
2799 // -----------------------------------------------------------------------------
setFunctionCell(OTableFieldDescRef & _pEntry)2800 void OSelectionBrowseBox::setFunctionCell(OTableFieldDescRef& _pEntry)
2801 {
2802 	Reference< XConnection> xConnection = static_cast<OQueryController&>(getDesignView()->getController()).getConnection();
2803 	if ( xConnection.is() )
2804 	{
2805 		// Diese Funktionen stehen nur unter CORE zur Verf�gung
2806 		if ( lcl_SupportsCoreSQLGrammar(xConnection) )
2807 		{
2808 			// if we have an asterix, no other function than count is allowed
2809 			m_pFunctionCell->Clear();
2810 			m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(0));
2811 			if ( isFieldNameAsterix(_pEntry->GetField()) )
2812 				m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(2)); // 2 -> COUNT
2813 			else
2814 			{
2815 				xub_StrLen nCount = m_aFunctionStrings.GetTokenCount();
2816 				if ( _pEntry->isNumeric() )
2817 					--nCount;
2818 				for (xub_StrLen nIdx = 1; nIdx < nCount; nIdx++)
2819 					m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(nIdx));
2820 			}
2821 
2822 			if ( _pEntry->IsGroupBy() )
2823 			{
2824 				OSL_ENSURE(!_pEntry->isNumeric(),"Not allowed to combine group by and numeric values!");
2825 				m_pFunctionCell->SelectEntry(m_pFunctionCell->GetEntry(m_pFunctionCell->GetEntryCount() - 1));
2826 			}
2827 			else if ( m_pFunctionCell->GetEntryPos(String(_pEntry->GetFunction())) != COMBOBOX_ENTRY_NOTFOUND )
2828 				m_pFunctionCell->SelectEntry(String(_pEntry->GetFunction()));
2829 			else
2830 				m_pFunctionCell->SelectEntryPos(0);
2831 
2832 			enableControl(_pEntry,m_pFunctionCell);
2833 		}
2834 		else
2835 		{
2836 			// nur COUNT(*) erlaubt
2837 			sal_Bool bCountRemoved = !isFieldNameAsterix(_pEntry->GetField());
2838 			if ( bCountRemoved )
2839 				m_pFunctionCell->RemoveEntry(1);
2840 
2841 			if ( !bCountRemoved && m_pFunctionCell->GetEntryCount() < 2)
2842 				m_pFunctionCell->InsertEntry(m_aFunctionStrings.GetToken(2)); // 2 -> COUNT
2843 
2844 			if(m_pFunctionCell->GetEntryPos(String(_pEntry->GetFunction())) != COMBOBOX_ENTRY_NOTFOUND)
2845 				m_pFunctionCell->SelectEntry(_pEntry->GetFunction());
2846 			else
2847 				m_pFunctionCell->SelectEntryPos(0);
2848 		}
2849 	}
2850 }
2851 // -----------------------------------------------------------------------------
CreateAccessibleCell(sal_Int32 _nRow,sal_uInt16 _nColumnPos)2852 Reference< XAccessible > OSelectionBrowseBox::CreateAccessibleCell( sal_Int32 _nRow, sal_uInt16 _nColumnPos )
2853 {
2854 	OTableFieldDescRef pEntry = NULL;
2855 	if(getFields().size() > sal_uInt16(_nColumnPos - 1))
2856 		pEntry = getFields()[_nColumnPos - 1];
2857 
2858 	if ( _nRow == BROW_VIS_ROW && pEntry.isValid() )
2859 		return EditBrowseBox::CreateAccessibleCheckBoxCell( _nRow, _nColumnPos,pEntry->IsVisible() ? STATE_CHECK : STATE_NOCHECK );
2860 
2861 	return EditBrowseBox::CreateAccessibleCell( _nRow, _nColumnPos );
2862 }
2863 // -----------------------------------------------------------------------------
HasFieldByAliasName(const::rtl::OUString & rFieldName,OTableFieldDescRef & rInfo) const2864 bool OSelectionBrowseBox::HasFieldByAliasName(const ::rtl::OUString& rFieldName, OTableFieldDescRef& rInfo) const
2865 {
2866     OTableFields& aFields = getFields();
2867     OTableFields::iterator aIter = aFields.begin();
2868     OTableFields::iterator aEnd  = aFields.end();
2869 
2870     for(;aIter != aEnd;++aIter)
2871     {
2872         if ( (*aIter)->GetFieldAlias() == rFieldName )
2873         {
2874             rInfo.getBody() = (*aIter).getBody();
2875             break;
2876         }
2877     }
2878     return aIter != aEnd;
2879 }
2880 // -----------------------------------------------------------------------------
2881 
2882