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