xref: /trunk/main/dbaccess/source/ui/querydesign/SelectionBrowseBox.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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