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