1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "SelectionBrowseBox.hxx"
21 #include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
22 #include <com/sun/star/sdbc/DataType.hpp>
23 #include "QueryDesignView.hxx"
24 #include "querycontroller.hxx"
25 #include "sqlbison.hxx"
26 #include "QueryTableView.hxx"
27 #include "browserids.hxx"
28 #include <comphelper/extract.hxx>
29 #include <comphelper/stl_types.hxx>
30 #include <comphelper/string.hxx>
31 #include <comphelper/types.hxx>
32 #include "TableFieldInfo.hxx"
33 #include "dbu_qry.hrc"
34 #include "dbaccess_helpid.hrc"
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include "dbustrings.hrc"
37 #include "QTableWindow.hxx"
38 #include <vcl/msgbox.hxx>
39 #include <vcl/settings.hxx>
40 #include "QueryDesignFieldUndoAct.hxx"
41 #include "sqlmessage.hxx"
42 #include "UITools.hxx"
43 #include <osl/diagnose.h>
44 #include "svtools/treelistentry.hxx"
46 using namespace ::svt
;
47 using namespace ::dbaui
;
48 using namespace ::connectivity
;
49 using namespace ::com::sun::star::uno
;
50 using namespace ::com::sun::star::sdbc
;
51 using namespace ::com::sun::star::beans
;
52 using namespace ::com::sun::star::container
;
53 using namespace ::com::sun::star::util
;
54 using namespace ::com::sun::star::accessibility
;
56 #define DEFAULT_QUERY_COLS 20
57 #define DEFAULT_SIZE GetTextWidth("0") * 30
59 #define HANDLE_COLUMN_WITDH 70
60 #define SORT_COLUMN_NONE 0xFFFFFFFF
64 bool isFieldNameAsterisk(const OUString
& _sFieldName
)
66 bool bAsterisk
= !(!_sFieldName
.isEmpty() && _sFieldName
.toChar() != '*');
69 sal_Int32 nTokenCount
= comphelper::string::getTokenCount(_sFieldName
, '.');
70 if ( (nTokenCount
== 2 && _sFieldName
.getToken(1,'.')[0] == '*' )
71 || (nTokenCount
== 3 && _sFieldName
.getToken(2,'.')[0] == '*' ) )
78 bool lcl_SupportsCoreSQLGrammar(const Reference
< XConnection
>& _xConnection
)
80 bool bSupportsCoreGrammar
= false;
81 if ( _xConnection
.is() )
85 Reference
< XDatabaseMetaData
> xMetaData
= _xConnection
->getMetaData();
86 bSupportsCoreGrammar
= xMetaData
.is() && xMetaData
->supportsCoreSQLGrammar();
92 return bSupportsCoreGrammar
;
96 OSelectionBrowseBox::OSelectionBrowseBox( vcl::Window
* pParent
)
97 :EditBrowseBox( pParent
,EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT
, WB_3DLOOK
, BrowserMode::COLUMNSELECTION
| BrowserMode::KEEPHIGHLIGHT
| BrowserMode::HIDESELECT
|
98 BrowserMode::HIDECURSOR
| BrowserMode::HLINES
| BrowserMode::VLINES
)
101 ,m_aFunctionStrings(ModuleRes(STR_QUERY_FUNCTIONS
))
103 ,m_nLastSortColumn(SORT_COLUMN_NONE
)
104 ,m_bOrderByUnRelated(true)
105 ,m_bGroupByUnRelated(true)
107 ,m_bWasEditing(false)
108 ,m_bDisableErrorBox(false)
109 ,m_bInUndoMode(false)
111 SetHelpId(HID_CTL_QRYDGNCRIT
);
113 m_nMode
= BrowserMode::COLUMNSELECTION
| BrowserMode::HIDESELECT
114 | BrowserMode::KEEPHIGHLIGHT
| BrowserMode::HIDECURSOR
115 | BrowserMode::HLINES
| BrowserMode::VLINES
116 | BrowserMode::HEADERBAR_NEW
;
118 m_pTextCell
= VclPtr
<Edit
>::Create(&GetDataWindow(), 0);
119 m_pVisibleCell
= VclPtr
<CheckBoxControl
>::Create(&GetDataWindow());
120 m_pTableCell
= VclPtr
<ListBoxControl
>::Create(&GetDataWindow()); m_pTableCell
->SetDropDownLineCount( 20 );
121 m_pFieldCell
= VclPtr
<ComboBoxControl
>::Create(&GetDataWindow()); m_pFieldCell
->SetDropDownLineCount( 20 );
122 m_pOrderCell
= VclPtr
<ListBoxControl
>::Create(&GetDataWindow());
123 m_pFunctionCell
= VclPtr
<ListBoxControl
>::Create(&GetDataWindow()); m_pFunctionCell
->SetDropDownLineCount( 20 );
125 m_pVisibleCell
->SetHelpId(HID_QRYDGN_ROW_VISIBLE
);
126 m_pTableCell
->SetHelpId(HID_QRYDGN_ROW_TABLE
);
127 m_pFieldCell
->SetHelpId(HID_QRYDGN_ROW_FIELD
);
128 m_pOrderCell
->SetHelpId(HID_QRYDGN_ROW_ORDER
);
129 m_pFunctionCell
->SetHelpId(HID_QRYDGN_ROW_FUNCTION
);
131 // switch off triState of css::form::CheckBox
132 m_pVisibleCell
->GetBox().EnableTriState( false );
134 vcl::Font aTitleFont
= OutputDevice::GetDefaultFont( DefaultFontType::SANS_UNICODE
,Window::GetSettings().GetLanguageTag().getLanguageType(),GetDefaultFontFlags::OnlyOne
);
135 aTitleFont
.SetFontSize(Size(0, 6));
136 SetTitleFont(aTitleFont
);
138 OUString
aTxt(ModuleRes(STR_QUERY_SORTTEXT
));
139 sal_Int32 nCount
= comphelper::string::getTokenCount(aTxt
, ';');
140 for (sal_Int32 nIdx
= 0; nIdx
< nCount
; nIdx
++)
141 m_pOrderCell
->InsertEntry(aTxt
.getToken(nIdx
, ';'));
143 for(long i
=0;i
< BROW_ROW_CNT
;i
++)
144 m_bVisibleRow
.push_back(true);
146 m_bVisibleRow
[BROW_FUNCTION_ROW
] = false; // first hide
148 m_timerInvalidate
.SetTimeout(200);
149 m_timerInvalidate
.SetTimeoutHdl(LINK(this, OSelectionBrowseBox
, OnInvalidateTimer
));
150 m_timerInvalidate
.Start();
153 OSelectionBrowseBox::~OSelectionBrowseBox()
158 void OSelectionBrowseBox::dispose()
160 m_pTextCell
.disposeAndClear();
161 m_pVisibleCell
.disposeAndClear();
162 m_pFieldCell
.disposeAndClear();
163 m_pTableCell
.disposeAndClear();
164 m_pOrderCell
.disposeAndClear();
165 m_pFunctionCell
.disposeAndClear();
166 ::svt::EditBrowseBox::dispose();
169 void OSelectionBrowseBox::initialize()
171 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
174 const IParseContext
& rContext
= static_cast<OQueryController
&>(getDesignView()->getController()).getParser().getContext();
175 const IParseContext::InternationalKeyCode eFunctions
[] = {
176 IParseContext::InternationalKeyCode::Avg
,IParseContext::InternationalKeyCode::Count
,IParseContext::InternationalKeyCode::Max
177 ,IParseContext::InternationalKeyCode::Min
,IParseContext::InternationalKeyCode::Sum
178 ,IParseContext::InternationalKeyCode::Every
179 ,IParseContext::InternationalKeyCode::Any
180 ,IParseContext::InternationalKeyCode::Some
181 ,IParseContext::InternationalKeyCode::StdDevPop
182 ,IParseContext::InternationalKeyCode::StdDevSamp
183 ,IParseContext::InternationalKeyCode::VarSamp
184 ,IParseContext::InternationalKeyCode::VarPop
185 ,IParseContext::InternationalKeyCode::Collect
186 ,IParseContext::InternationalKeyCode::Fusion
187 ,IParseContext::InternationalKeyCode::Intersection
190 OUString sGroup
= m_aFunctionStrings
.getToken(comphelper::string::getTokenCount(m_aFunctionStrings
, ';') - 1, ';');
191 m_aFunctionStrings
= m_aFunctionStrings
.getToken(0, ';');
193 for (IParseContext::InternationalKeyCode eFunction
: eFunctions
)
195 m_aFunctionStrings
+= ";";
196 m_aFunctionStrings
+= OStringToOUString(rContext
.getIntlKeywordAscii(eFunction
),
197 RTL_TEXTENCODING_UTF8
);
199 m_aFunctionStrings
+= ";";
200 m_aFunctionStrings
+= sGroup
;
202 // Aggregate functions in general available only with Core SQL
203 // We slip in a few optionals one, too.
204 if ( lcl_SupportsCoreSQLGrammar(xConnection
) )
206 sal_Int32 nCount
= comphelper::string::getTokenCount(m_aFunctionStrings
, ';');
207 for( sal_Int32 nIdx
= 0; nIdx
< nCount
; nIdx
++ )
208 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(nIdx
, ';'));
210 else // else only COUNT(*) and COUNT("table".*)
212 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(0, ';'));
213 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(2, ';')); // 2 -> COUNT
217 Reference
< XDatabaseMetaData
> xMetaData
= xConnection
->getMetaData();
218 if ( xMetaData
.is() )
220 m_bOrderByUnRelated
= xMetaData
->supportsOrderByUnrelated();
221 m_bGroupByUnRelated
= xMetaData
->supportsGroupByUnrelated();
232 OQueryDesignView
* OSelectionBrowseBox::getDesignView()
234 OSL_ENSURE(static_cast<const OQueryDesignView
*>(GetParent()),"Parent isn't an OQueryDesignView!");
235 return static_cast<OQueryDesignView
*>(GetParent());
238 OQueryDesignView
* OSelectionBrowseBox::getDesignView() const
240 OSL_ENSURE(static_cast<const OQueryDesignView
*>(GetParent()),"Parent isn't an OQueryDesignView!");
241 return static_cast<OQueryDesignView
*>(GetParent());
246 class OSelectionBrwBoxHeader
: public ::svt::EditBrowserHeader
248 VclPtr
<OSelectionBrowseBox
> m_pBrowseBox
;
250 virtual void Select() override
;
252 explicit OSelectionBrwBoxHeader(OSelectionBrowseBox
* pParent
);
253 virtual ~OSelectionBrwBoxHeader() { disposeOnce(); }
254 virtual void dispose() override
{ m_pBrowseBox
.clear(); ::svt::EditBrowserHeader::dispose(); }
256 OSelectionBrwBoxHeader::OSelectionBrwBoxHeader(OSelectionBrowseBox
* pParent
)
257 : ::svt::EditBrowserHeader(pParent
,WB_BUTTONSTYLE
|WB_DRAG
)
258 ,m_pBrowseBox(pParent
)
262 void OSelectionBrwBoxHeader::Select()
264 EditBrowserHeader::Select();
265 m_pBrowseBox
->GrabFocus();
267 BrowserMode nMode
= m_pBrowseBox
->GetMode();
268 if ( 0 == m_pBrowseBox
->GetSelectColumnCount() )
270 m_pBrowseBox
->DeactivateCell();
271 // we are in the right mode if a row hase been selected row
272 if ( nMode
& BrowserMode::HIDESELECT
)
274 nMode
&= ~BrowserMode::HIDESELECT
;
275 nMode
|= BrowserMode::MULTISELECTION
;
276 m_pBrowseBox
->SetMode( nMode
);
279 m_pBrowseBox
->SelectColumnId( GetCurItemId() );
280 m_pBrowseBox
->DeactivateCell();
284 VclPtr
<BrowserHeader
> OSelectionBrowseBox::imp_CreateHeaderBar(BrowseBox
* /*pParent*/)
286 return VclPtr
<OSelectionBrwBoxHeader
>::Create(this);
289 void OSelectionBrowseBox::ColumnMoved( sal_uInt16 nColId
, bool _bCreateUndo
)
291 EditBrowseBox::ColumnMoved( nColId
);
292 // swap the two columns
293 sal_uInt16 nNewPos
= GetColumnPos( nColId
);
294 OTableFields
& rFields
= getFields();
295 if ( rFields
.size() > sal_uInt16(nNewPos
-1) )
297 sal_uInt16 nOldPos
= 0;
298 OTableFields::const_iterator aEnd
= rFields
.end();
299 OTableFields::const_iterator aIter
= rFields
.begin();
300 for (; aIter
!= aEnd
&& ( (*aIter
)->GetColumnId() != nColId
); ++aIter
,++nOldPos
)
303 OSL_ENSURE( (nNewPos
-1) != nOldPos
&& nOldPos
< rFields
.size(),"Old and new position are equal!");
306 OTableFieldDescRef pOldEntry
= rFields
[nOldPos
];
307 rFields
.erase(rFields
.begin() + nOldPos
);
308 rFields
.insert(rFields
.begin() + nNewPos
- 1,pOldEntry
);
310 // create the undo action
311 if ( !m_bInUndoMode
&& _bCreateUndo
)
313 OTabFieldMovedUndoAct
* pUndoAct
= new OTabFieldMovedUndoAct(this);
314 pUndoAct
->SetColumnPosition( nOldPos
+ 1);
315 pUndoAct
->SetTabFieldDescr(pOldEntry
);
317 getDesignView()->getController().addUndoActionAndInvalidate(pUndoAct
);
322 OSL_FAIL("Invalid column id!");
325 void OSelectionBrowseBox::Init()
328 EditBrowseBox::Init();
330 // set the header bar
331 BrowserHeader
* pNewHeaderBar
= CreateHeaderBar(this);
332 pNewHeaderBar
->SetMouseTransparent(false);
334 SetHeaderBar(pNewHeaderBar
);
337 vcl::Font
aFont( GetDataWindow().GetFont() );
338 aFont
.SetWeight( WEIGHT_NORMAL
);
339 GetDataWindow().SetFont( aFont
);
342 const Control
* pControls
[] = { m_pTextCell
,m_pVisibleCell
,m_pTableCell
,m_pFieldCell
};
344 for (const Control
* pControl
: pControls
)
346 const Size
aTemp(pControl
->GetOptimalSize());
347 if ( aTemp
.Height() > aHeight
.Height() )
348 aHeight
.Height() = aTemp
.Height();
350 SetDataRowHeight(aHeight
.Height());
352 // get number of visible rows
353 for(long i
=0;i
<BROW_ROW_CNT
;i
++)
358 RowInserted(0, m_nVisibleCount
, false);
361 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
364 Reference
< XDatabaseMetaData
> xMetaData
= xConnection
->getMetaData();
365 m_nMaxColumns
= xMetaData
.is() ? xMetaData
->getMaxColumnsInSelect() : 0;
371 catch(const SQLException
&)
373 OSL_FAIL("Catched Exception when asking for database metadata options!");
378 void OSelectionBrowseBox::PreFill()
380 SetUpdateMode(false);
382 if (GetCurRow() != 0)
385 static_cast< OQueryController
& >( getDesignView()->getController() ).clearFields();
390 InsertHandleColumn( HANDLE_COLUMN_WITDH
);
394 void OSelectionBrowseBox::ClearAll()
396 SetUpdateMode(false);
398 OTableFields::const_reverse_iterator aIter
= getFields().rbegin();
399 for ( ;aIter
!= getFields().rend(); ++aIter
)
401 if ( !(*aIter
)->IsEmpty() )
403 RemoveField( (*aIter
)->GetColumnId() );
404 aIter
= getFields().rbegin();
407 m_nLastSortColumn
= SORT_COLUMN_NONE
;
411 void OSelectionBrowseBox::SetReadOnly(bool bRO
)
416 m_nMode
&= ~BrowserMode::HIDECURSOR
;
421 m_nMode
|= BrowserMode::HIDECURSOR
;
427 CellController
* OSelectionBrowseBox::GetController(long nRow
, sal_uInt16 nColId
)
429 if ( nColId
> getFields().size() )
431 OTableFieldDescRef pEntry
= getFields()[nColId
-1];
432 OSL_ENSURE(pEntry
.is(), "OSelectionBrowseBox::GetController : keine FieldDescription !");
437 if (static_cast<OQueryController
&>(getDesignView()->getController()).isReadOnly())
440 long nCellIndex
= GetRealRow(nRow
);
444 return new ComboBoxCellController(m_pFieldCell
);
446 return new ListBoxCellController(m_pTableCell
);
448 return new CheckBoxCellController(m_pVisibleCell
);
450 return new ListBoxCellController(m_pOrderCell
);
451 case BROW_FUNCTION_ROW
:
452 return new ListBoxCellController(m_pFunctionCell
);
454 return new EditCellController(m_pTextCell
);
458 void OSelectionBrowseBox::InitController(CellControllerRef
& /*rController*/, long nRow
, sal_uInt16 nColId
)
460 OSL_ENSURE(nColId
!= BROWSER_INVALIDID
,"An Invalid Id was set!");
461 if ( nColId
== BROWSER_INVALIDID
)
463 sal_uInt16 nPos
= GetColumnPos(nColId
);
464 if ( nPos
== 0 || nPos
== BROWSER_INVALIDID
|| nPos
> getFields().size() )
466 OTableFieldDescRef pEntry
= getFields()[nPos
-1];
467 OSL_ENSURE(pEntry
.is(), "OSelectionBrowseBox::InitController : keine FieldDescription !");
468 long nCellIndex
= GetRealRow(nRow
);
474 m_pFieldCell
->Clear();
475 m_pFieldCell
->SetText(OUString());
477 OUString
aField(pEntry
->GetField());
478 OUString
aTable(pEntry
->GetAlias());
480 getDesignView()->fillValidFields(aTable
, m_pFieldCell
);
482 // replace with alias.*
483 if (aField
.trim() == "*")
485 aField
= aTable
+ ".*";
487 m_pFieldCell
->SetText(aField
);
491 m_pTableCell
->Clear();
492 enableControl(pEntry
,m_pTableCell
);
493 if ( !pEntry
->isCondition() )
495 OJoinTableView::OTableWindowMap
& rTabWinList
= getDesignView()->getTableView()->GetTabWinMap();
496 OJoinTableView::OTableWindowMap::const_iterator aIter
= rTabWinList
.begin();
497 OJoinTableView::OTableWindowMap::const_iterator aEnd
= rTabWinList
.end();
499 for(;aIter
!= aEnd
;++aIter
)
500 m_pTableCell
->InsertEntry(static_cast<OQueryTableWindow
*>(aIter
->second
.get())->GetAliasName());
502 m_pTableCell
->InsertEntry(OUString(ModuleRes(STR_QUERY_NOTABLE
)), 0);
503 if (!pEntry
->GetAlias().isEmpty())
504 m_pTableCell
->SelectEntry(pEntry
->GetAlias());
506 m_pTableCell
->SelectEntry(OUString(ModuleRes(STR_QUERY_NOTABLE
)));
511 m_pVisibleCell
->GetBox().Check(pEntry
->IsVisible());
512 m_pVisibleCell
->GetBox().SaveValue();
514 enableControl(pEntry
,m_pTextCell
);
516 if(!pEntry
->IsVisible() && pEntry
->GetOrderDir() != ORDER_NONE
&& !m_bOrderByUnRelated
)
518 // a column has to visible in order to show up in ORDER BY
519 pEntry
->SetVisible();
520 m_pVisibleCell
->GetBox().Check(pEntry
->IsVisible());
521 m_pVisibleCell
->GetBox().SaveValue();
522 m_pVisibleCell
->GetBox().Disable();
523 m_pVisibleCell
->GetBox().EnableInput(false);
524 OUString
aMessage(ModuleRes(STR_QRY_ORDERBY_UNRELATED
));
525 OQueryDesignView
* paDView
= getDesignView();
526 ScopedVclPtrInstance
<InfoBox
>(paDView
, aMessage
)->Execute();
530 m_pOrderCell
->SelectEntryPos(
531 sal::static_int_cast
< sal_uInt16
>(pEntry
->GetOrderDir()));
532 enableControl(pEntry
,m_pOrderCell
);
534 case BROW_COLUMNALIAS_ROW
:
535 setTextCellContext(pEntry
,pEntry
->GetFieldAlias(),HID_QRYDGN_ROW_ALIAS
);
537 case BROW_FUNCTION_ROW
:
538 setFunctionCell(pEntry
);
542 sal_uInt16 nIdx
= sal_uInt16(nCellIndex
- BROW_CRIT1_ROW
);
543 setTextCellContext(pEntry
,pEntry
->GetCriteria( nIdx
),HID_QRYDGN_ROW_CRIT
);
546 Controller()->ClearModified();
549 void OSelectionBrowseBox::notifyTableFieldChanged(const OUString
& _sOldAlias
, const OUString
& _sAlias
, bool& _bListAction
, sal_uInt16 _nColumnId
)
551 appendUndoAction(_sOldAlias
,_sAlias
,BROW_TABLE_ROW
,_bListAction
);
552 if ( m_bVisibleRow
[BROW_TABLE_ROW
] )
553 RowModified(GetBrowseRow(BROW_TABLE_ROW
), _nColumnId
);
556 void OSelectionBrowseBox::notifyFunctionFieldChanged(const OUString
& _sOldFunctionName
, const OUString
& _sFunctionName
, bool& _bListAction
, sal_uInt16 _nColumnId
)
558 appendUndoAction(_sOldFunctionName
,_sFunctionName
,BROW_FUNCTION_ROW
,_bListAction
);
559 if ( !m_bVisibleRow
[BROW_FUNCTION_ROW
] )
560 SetRowVisible(BROW_FUNCTION_ROW
, true);
561 RowModified(GetBrowseRow(BROW_FUNCTION_ROW
), _nColumnId
);
564 void OSelectionBrowseBox::clearEntryFunctionField(const OUString
& _sFieldName
,OTableFieldDescRef
& _pEntry
, bool& _bListAction
,sal_uInt16 _nColumnId
)
566 if ( isFieldNameAsterisk( _sFieldName
) && (!_pEntry
->isNoneFunction() || _pEntry
->IsGroupBy()) )
568 OUString sFunctionName
;
569 GetFunctionName(SQL_TOKEN_COUNT
,sFunctionName
);
570 OUString sOldLocalizedFunctionName
= _pEntry
->GetFunction();
571 if ( sOldLocalizedFunctionName
!= sFunctionName
|| _pEntry
->IsGroupBy() )
573 // append undo action for the function field
574 _pEntry
->SetFunctionType(FKT_NONE
);
575 _pEntry
->SetFunction(OUString());
576 _pEntry
->SetGroupBy(false);
577 notifyFunctionFieldChanged(sOldLocalizedFunctionName
,_pEntry
->GetFunction(),_bListAction
,_nColumnId
);
582 bool OSelectionBrowseBox::fillColumnRef(const OSQLParseNode
* _pColumnRef
, const Reference
< XConnection
>& _rxConnection
, OTableFieldDescRef
& _pEntry
, bool& _bListAction
)
584 OSL_ENSURE(_pColumnRef
,"No valid parsenode!");
585 OUString sColumnName
,sTableRange
;
586 OSQLParseTreeIterator::getColumnRange(_pColumnRef
,_rxConnection
,sColumnName
,sTableRange
);
587 return fillColumnRef(sColumnName
,sTableRange
,_rxConnection
->getMetaData(),_pEntry
,_bListAction
);
590 bool OSelectionBrowseBox::fillColumnRef(const OUString
& _sColumnName
, const OUString
& _sTableRange
, const Reference
<XDatabaseMetaData
>& _xMetaData
, OTableFieldDescRef
& _pEntry
, bool& _bListAction
)
593 ::comphelper::UStringMixEqual
bCase(_xMetaData
->supportsMixedCaseQuotedIdentifiers());
594 // check if the table name is the same
595 if ( !_sTableRange
.isEmpty() && (bCase(_pEntry
->GetTable(),_sTableRange
) || bCase(_pEntry
->GetAlias(),_sTableRange
)) )
596 { // a table was already inserted and the tables contains that column name
598 if ( !_pEntry
->GetTabWindow() )
600 OUString sOldAlias
= _pEntry
->GetAlias();
601 if ( !fillEntryTable(_pEntry
,_pEntry
->GetTable()) )
602 fillEntryTable(_pEntry
,_pEntry
->GetAlias()); // only when the first failed
603 if ( !bCase(sOldAlias
,_pEntry
->GetAlias()) )
604 notifyTableFieldChanged(sOldAlias
,_pEntry
->GetAlias(),_bListAction
,GetCurColumnId());
607 // check if the table window
608 OQueryTableWindow
* pEntryTab
= static_cast<OQueryTableWindow
*>(_pEntry
->GetTabWindow());
609 if ( !pEntryTab
) // no table found with this name so we have to travel through all tables
611 sal_uInt16 nTabCount
= 0;
612 if ( !static_cast<OQueryTableView
*>(getDesignView()->getTableView())->FindTableFromField(_sColumnName
,_pEntry
,nTabCount
) ) // error occurred: column not in table window
614 OUString
sErrorMsg(ModuleRes(RID_STR_FIELD_DOESNT_EXIST
));
615 sErrorMsg
= sErrorMsg
.replaceFirst("$name$",_sColumnName
);
616 ScopedVclPtrInstance
<OSQLErrorBox
>(this, sErrorMsg
)->Execute();
621 pEntryTab
= static_cast<OQueryTableWindow
*>(_pEntry
->GetTabWindow());
622 notifyTableFieldChanged(OUString(),_pEntry
->GetAlias(),_bListAction
,GetCurColumnId());
625 if ( pEntryTab
) // here we got a valid table
626 _pEntry
->SetField(_sColumnName
);
631 bool OSelectionBrowseBox::saveField(OUString
& _sFieldName
,OTableFieldDescRef
& _pEntry
, bool& _bListAction
)
635 OQueryController
& rController
= static_cast<OQueryController
&>(getDesignView()->getController());
637 // first look if the name can be found in our tables
638 sal_uInt16 nTabCount
= 0;
639 OUString sOldAlias
= _pEntry
->GetAlias();
640 if ( static_cast<OQueryTableView
*>(getDesignView()->getTableView())->FindTableFromField(_sFieldName
,_pEntry
,nTabCount
) )
642 // append undo action for the alias name
643 _pEntry
->SetField(_sFieldName
);
644 notifyTableFieldChanged(sOldAlias
,_pEntry
->GetAlias(),_bListAction
,GetCurColumnId());
645 clearEntryFunctionField(_sFieldName
,_pEntry
,_bListAction
,_pEntry
->GetColumnId());
649 Reference
<XConnection
> xConnection( rController
.getConnection() );
650 Reference
< XDatabaseMetaData
> xMetaData
;
651 if ( xConnection
.is() )
652 xMetaData
= xConnection
->getMetaData();
653 OSL_ENSURE( xMetaData
.is(), "OSelectionBrowseBox::saveField: invalid connection/meta data!" );
654 if ( !xMetaData
.is() )
658 // second test if the name can be set as select columns in a pseudo statement
659 // we have to look which entries we should quote
661 const OUString sFieldAlias
= _pEntry
->GetFieldAlias();
662 ::connectivity::OSQLParser
& rParser( rController
.getParser() );
664 // automatically add parentheses around subqueries
665 OSQLParseNode
*pParseNode
= nullptr;
667 pParseNode
= rParser
.parseTree( devnull
, _sFieldName
, true );
668 if (pParseNode
== nullptr)
669 pParseNode
= rParser
.parseTree( devnull
, _sFieldName
);
670 if (pParseNode
!= nullptr && SQL_ISRULE(pParseNode
, select_statement
))
671 _sFieldName
= "(" + _sFieldName
+ ")";
674 OSQLParseNode
* pParseNode
= nullptr;
676 // 4 passes in trying to interprete the field name
677 // - don't quote the field name, parse internationally
678 // - don't quote the field name, parse en-US
679 // - quote the field name, parse internationally
680 // - quote the field name, parse en-US
682 OUString
sQuotedFullFieldName(::dbtools::quoteName( xMetaData
->getIdentifierQuoteString(), _sFieldName
));
683 OUString
sFullFieldName(_sFieldName
);
685 if ( _pEntry
->isAggreateFunction() )
687 OSL_ENSURE(!_pEntry
->GetFunction().isEmpty(),"Functionname darf hier nicht leer sein! ;-(");
688 sQuotedFullFieldName
= _pEntry
->GetFunction() + "(" + sQuotedFullFieldName
+ ")";
689 sFullFieldName
= _pEntry
->GetFunction() + "(" + sFullFieldName
+ ")";
694 bool bQuote
= ( nPass
<= 2 );
695 bool bInternational
= ( nPass
% 2 ) == 0;
699 sSql
+= sQuotedFullFieldName
;
701 sSql
+= sFullFieldName
;
703 sSql
= "SELECT " + sSql
;
704 if ( !sFieldAlias
.isEmpty() )
705 { // always quote the alias name: there cannot be a function in it
707 sSql
+= ::dbtools::quoteName( xMetaData
->getIdentifierQuoteString(), sFieldAlias
);
711 pParseNode
= rParser
.parseTree( sErrorMsg
, sSql
, bInternational
);
713 while ( ( pParseNode
== nullptr ) && ( --nPass
> 0 ) );
716 if ( pParseNode
== nullptr )
718 // something different which we have to check
719 OUString
sErrorMessage( ModuleRes( STR_QRY_COLUMN_NOT_FOUND
) );
720 sErrorMessage
= sErrorMessage
.replaceFirst("$name$",_sFieldName
);
721 ScopedVclPtrInstance
<OSQLErrorBox
>(this, sErrorMessage
)->Execute();
726 // we got a valid select column
727 // find what type of column has be inserted
728 ::connectivity::OSQLParseNode
* pSelection
= pParseNode
->getChild(2);
729 if ( SQL_ISRULE(pSelection
,selection
) ) // we found the asterisk
731 _pEntry
->SetField(_sFieldName
);
732 clearEntryFunctionField(_sFieldName
,_pEntry
,_bListAction
,_pEntry
->GetColumnId());
734 else // travel through the select column parse node
736 ::comphelper::UStringMixEqual
bCase(xMetaData
->supportsMixedCaseQuotedIdentifiers());
738 OTableFieldDescRef aSelEntry
= _pEntry
;
739 sal_uInt16 nColumnId
= aSelEntry
->GetColumnId();
741 sal_uInt32 nCount
= pSelection
->count();
742 for (sal_uInt32 i
= 0; i
< nCount
; ++i
)
744 if ( i
> 0 ) // may we have to append more than one field
746 sal_uInt16 nColumnPostion
;
747 aSelEntry
= FindFirstFreeCol(nColumnPostion
);
748 if ( !aSelEntry
.is() )
751 aSelEntry
= FindFirstFreeCol(nColumnPostion
);
754 nColumnId
= GetColumnId(nColumnPostion
);
757 ::connectivity::OSQLParseNode
* pChild
= pSelection
->getChild( i
);
758 OSL_ENSURE(SQL_ISRULE(pChild
,derived_column
), "No derived column found!");
759 // get the column alias
760 OUString sColumnAlias
= OSQLParseTreeIterator::getColumnAlias(pChild
);
761 if ( !sColumnAlias
.isEmpty() ) // we found an as clause
763 OUString aSelectionAlias
= aSelEntry
->GetFieldAlias();
764 aSelEntry
->SetFieldAlias( sColumnAlias
);
766 appendUndoAction(aSelectionAlias
,aSelEntry
->GetFieldAlias(),BROW_COLUMNALIAS_ROW
,_bListAction
);
767 if ( m_bVisibleRow
[BROW_COLUMNALIAS_ROW
] )
768 RowModified(GetBrowseRow(BROW_COLUMNALIAS_ROW
), nColumnId
);
771 ::connectivity::OSQLParseNode
* pColumnRef
= pChild
->getChild(0);
773 pColumnRef
->getKnownRuleID() != OSQLParseNode::subquery
&&
774 pColumnRef
->count() == 3 &&
775 SQL_ISPUNCTUATION(pColumnRef
->getChild(0),"(") &&
776 SQL_ISPUNCTUATION(pColumnRef
->getChild(2),")")
778 pColumnRef
= pColumnRef
->getChild(1);
780 if ( SQL_ISRULE(pColumnRef
,column_ref
) ) // we found a valid column name or more column names
782 // look if we can find the corresponding table
783 bError
= fillColumnRef( pColumnRef
, xConnection
, aSelEntry
, _bListAction
);
785 // we found a simple column so we must clear the function fields but only when the column name is '*'
786 // and the function is different to count
787 clearEntryFunctionField(_sFieldName
,aSelEntry
,_bListAction
,nColumnId
);
789 // do we have a aggregate function and only a function?
790 else if ( SQL_ISRULE(pColumnRef
,general_set_fct
) )
792 OUString sLocalizedFunctionName
;
793 if ( GetFunctionName(pColumnRef
->getChild(0)->getTokenID(),sLocalizedFunctionName
) )
795 OUString sOldLocalizedFunctionName
= aSelEntry
->GetFunction();
796 aSelEntry
->SetFunction(sLocalizedFunctionName
);
797 sal_uInt32 nFunCount
= pColumnRef
->count() - 1;
798 sal_Int32 nFunctionType
= FKT_AGGREGATE
;
800 // may be there exists only one parameter which is a column, fill all information into our fields
801 if ( nFunCount
== 4 && SQL_ISRULE(pColumnRef
->getChild(3),column_ref
) )
802 bError
= fillColumnRef( pColumnRef
->getChild(3), xConnection
, aSelEntry
, _bListAction
);
803 else if ( nFunCount
== 3 ) // we have a COUNT(*) here, so take the first table
804 bError
= fillColumnRef( "*", OUString(), xMetaData
, aSelEntry
, _bListAction
);
807 nFunctionType
|= FKT_NUMERIC
;
809 aSelEntry
->SetDataType(DataType::DOUBLE
);
810 aSelEntry
->SetFieldType(TAB_NORMAL_FIELD
);
813 // now parse the parameters
814 OUString sParameters
;
815 for(sal_uInt32 function
= 2; function
< nFunCount
; ++function
) // we only want to parse the parameters of the function
816 pColumnRef
->getChild(function
)->parseNodeToStr( sParameters
, xConnection
, &rParser
.getContext(), true, bQuote
);
818 aSelEntry
->SetFunctionType(nFunctionType
);
819 aSelEntry
->SetField(sParameters
);
820 if ( aSelEntry
->IsGroupBy() )
822 sOldLocalizedFunctionName
= m_aFunctionStrings
.getToken(comphelper::string::getTokenCount(m_aFunctionStrings
, ';')-1, ';');
823 aSelEntry
->SetGroupBy(false);
826 // append undo action
827 notifyFunctionFieldChanged(sOldLocalizedFunctionName
,sLocalizedFunctionName
,_bListAction
, nColumnId
);
830 OSL_FAIL("Unsupported function inserted!");
835 // so we first clear the function field
836 clearEntryFunctionField(_sFieldName
,aSelEntry
,_bListAction
,nColumnId
);
838 pColumnRef
->parseNodeToStr( sFunction
,
840 &rController
.getParser().getContext(),
841 true); // quote is to true because we need quoted elements inside the function
843 getDesignView()->fillFunctionInfo(pColumnRef
,sFunction
,aSelEntry
);
845 if( SQL_ISRULEOR3(pColumnRef
, position_exp
, extract_exp
, fold
) ||
846 SQL_ISRULEOR3(pColumnRef
, char_substring_fct
, length_exp
, char_value_fct
) )
847 // a calculation has been found ( can be calc and function )
849 // now parse the whole statement
850 sal_uInt32 nFunCount
= pColumnRef
->count();
851 OUString sParameters
;
852 for(sal_uInt32 function
= 0; function
< nFunCount
; ++function
)
853 pColumnRef
->getChild(function
)->parseNodeToStr( sParameters
, xConnection
, &rParser
.getContext(), true );
855 sOldAlias
= aSelEntry
->GetAlias();
856 sal_Int32 nNewFunctionType
= aSelEntry
->GetFunctionType() | FKT_NUMERIC
| FKT_OTHER
;
857 aSelEntry
->SetFunctionType(nNewFunctionType
);
858 aSelEntry
->SetField(sParameters
);
862 aSelEntry
->SetFieldAlias(sColumnAlias
);
863 if ( SQL_ISRULE(pColumnRef
,set_fct_spec
) )
864 aSelEntry
->SetFunctionType(/*FKT_NUMERIC | */FKT_OTHER
);
866 aSelEntry
->SetFunctionType(FKT_NUMERIC
| FKT_OTHER
);
869 aSelEntry
->SetAlias(OUString());
870 notifyTableFieldChanged(sOldAlias
,aSelEntry
->GetAlias(),_bListAction
, nColumnId
);
873 if ( i
> 0 && !InsertField(aSelEntry
,BROWSER_INVALIDID
,true,false).is() ) // may we have to append more than one field
874 { // the field could not be inserted
875 OUString
sErrorMessage( ModuleRes( RID_STR_FIELD_DOESNT_EXIST
) );
876 sErrorMessage
= sErrorMessage
.replaceFirst("$name$",aSelEntry
->GetField());
877 ScopedVclPtrInstance
<OSQLErrorBox
>(this, sErrorMessage
)->Execute();
887 bool OSelectionBrowseBox::SaveModified()
889 OQueryController
& rController
= static_cast<OQueryController
&>(getDesignView()->getController());
890 OTableFieldDescRef pEntry
= nullptr;
891 sal_uInt16 nCurrentColumnPos
= GetColumnPos(GetCurColumnId());
892 if(getFields().size() > static_cast<sal_uInt16
>(nCurrentColumnPos
- 1))
893 pEntry
= getEntry(nCurrentColumnPos
- 1);
895 bool bWasEmpty
= pEntry
.is() && pEntry
->IsEmpty();
897 bool bListAction
= false;
899 if (pEntry
.is() && Controller().Is() && Controller()->IsModified())
901 // for the Undo-action
902 OUString strOldCellContents
,sNewValue
;
903 long nRow
= GetRealRow(GetCurRow());
904 bool bAppendRow
= false;
909 bool bOldValue
= m_pVisibleCell
->GetBox().GetSavedValue() != TRISTATE_FALSE
;
910 strOldCellContents
= bOldValue
? OUStringLiteral("1") : OUStringLiteral("0");
911 sNewValue
= !bOldValue
? OUStringLiteral("1") : OUStringLiteral("0");
913 if((m_bOrderByUnRelated
|| pEntry
->GetOrderDir() == ORDER_NONE
) &&
914 (m_bGroupByUnRelated
|| !pEntry
->IsGroupBy()))
916 pEntry
->SetVisible(m_pVisibleCell
->GetBox().IsChecked());
920 pEntry
->SetVisible();
921 m_pVisibleCell
->GetBox().Check();
927 OUString
aFieldName(m_pFieldCell
->GetText());
930 if (aFieldName
.isEmpty())
932 OTableFieldDescRef pNewEntry
= new OTableFieldDesc();
933 pNewEntry
->SetColumnId( pEntry
->GetColumnId() );
934 ::std::replace(getFields().begin(),getFields().end(),pEntry
,pNewEntry
);
935 sal_uInt16 nCol
= GetCurColumnId();
936 for (int i
= 0; i
< m_nVisibleCount
; i
++) // redraw column
941 strOldCellContents
= pEntry
->GetField();
943 if ( !m_bInUndoMode
)
944 rController
.GetUndoManager().EnterListAction(OUString(),OUString());
946 sal_Int32 nPos
= m_pFieldCell
->GetEntryPos(aFieldName
);
947 OUString aAliasName
= pEntry
->GetAlias();
948 if ( nPos
!= COMBOBOX_ENTRY_NOTFOUND
&& aAliasName
.isEmpty() && comphelper::string::getTokenCount(aFieldName
, '.') > 1 )
949 { // special case, we have a table field so we must cut the table name
950 OUString sTableAlias
= aFieldName
.getToken(0,'.');
951 pEntry
->SetAlias(sTableAlias
);
952 OUString sColumnName
= aFieldName
.copy(sTableAlias
.getLength()+1,aFieldName
.getLength() - sTableAlias
.getLength() -1);
953 Reference
<XConnection
> xConnection
= rController
.getConnection();
954 if ( !xConnection
.is() )
956 bError
= fillColumnRef( sColumnName
, sTableAlias
, xConnection
->getMetaData(), pEntry
, bListAction
);
962 bError
= saveField(aFieldName
,pEntry
,bListAction
);
971 sNewValue
= aFieldName
;
972 if ( !m_bInUndoMode
)
973 static_cast<OQueryController
&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
977 sNewValue
= pEntry
->GetField();
978 rController
.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE
);
984 OUString aAliasName
= m_pTableCell
->GetSelectEntry();
985 strOldCellContents
= pEntry
->GetAlias();
986 if ( m_pTableCell
->GetSelectEntryPos() != 0 )
988 pEntry
->SetAlias(aAliasName
);
989 // we have to set the table name as well as the table window
990 OJoinTableView::OTableWindowMap
& rTabWinList
= getDesignView()->getTableView()->GetTabWinMap();
991 OJoinTableView::OTableWindowMap::const_iterator aIter
= rTabWinList
.find(aAliasName
);
992 if(aIter
!= rTabWinList
.end())
994 OQueryTableWindow
* pEntryTab
= static_cast<OQueryTableWindow
*>(aIter
->second
.get());
997 pEntry
->SetTable(pEntryTab
->GetTableName());
998 pEntry
->SetTabWindow(pEntryTab
);
1004 pEntry
->SetAlias(OUString());
1005 pEntry
->SetTable(OUString());
1006 pEntry
->SetTabWindow(nullptr);
1008 sNewValue
= pEntry
->GetAlias();
1012 case BROW_ORDER_ROW
:
1014 strOldCellContents
= OUString::number((sal_uInt16
)pEntry
->GetOrderDir());
1015 sal_Int32 nIdx
= m_pOrderCell
->GetSelectEntryPos();
1016 if (nIdx
== LISTBOX_ENTRY_NOTFOUND
)
1018 pEntry
->SetOrderDir(EOrderDir(nIdx
));
1019 if(!m_bOrderByUnRelated
)
1021 pEntry
->SetVisible();
1022 m_pVisibleCell
->GetBox().Check();
1023 RowModified(GetBrowseRow(BROW_VIS_ROW
), GetCurColumnId());
1025 sNewValue
= OUString::number((sal_uInt16
)pEntry
->GetOrderDir());
1028 case BROW_COLUMNALIAS_ROW
:
1029 strOldCellContents
= pEntry
->GetFieldAlias();
1030 pEntry
->SetFieldAlias(m_pTextCell
->GetText());
1031 sNewValue
= pEntry
->GetFieldAlias();
1033 case BROW_FUNCTION_ROW
:
1035 strOldCellContents
= pEntry
->GetFunction();
1036 sal_Int32 nPos
= m_pFunctionCell
->GetSelectEntryPos();
1037 // these functions are only available in CORE
1038 OUString sFunctionName
= m_pFunctionCell
->GetEntry(nPos
);
1039 OUString sGroupFunctionName
= m_aFunctionStrings
.getToken(comphelper::string::getTokenCount(m_aFunctionStrings
, ';')-1, ';');
1040 bool bGroupBy
= false;
1041 if ( sGroupFunctionName
.equals(sFunctionName
) ) // check if the function name is GROUP
1045 if ( !m_bGroupByUnRelated
&& !pEntry
->IsVisible() )
1047 // we have to change the visible flag, so we must append also an undo action
1048 pEntry
->SetVisible();
1049 m_pVisibleCell
->GetBox().Check();
1050 appendUndoAction("0","1",BROW_VIS_ROW
,bListAction
);
1051 RowModified(GetBrowseRow(BROW_VIS_ROW
), GetCurColumnId());
1054 pEntry
->SetFunction(OUString());
1055 pEntry
->SetFunctionType(pEntry
->GetFunctionType() & ~FKT_AGGREGATE
);
1057 else if ( nPos
) // we found an aggregate function
1059 pEntry
->SetFunctionType(pEntry
->GetFunctionType() | FKT_AGGREGATE
);
1060 pEntry
->SetFunction(sFunctionName
);
1064 sFunctionName
.clear();
1065 pEntry
->SetFunction(OUString());
1066 pEntry
->SetFunctionType(pEntry
->GetFunctionType() & ~FKT_AGGREGATE
);
1069 pEntry
->SetGroupBy(bGroupBy
);
1071 sNewValue
= sFunctionName
;
1076 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
1077 if(!xConnection
.is())
1080 sal_uInt16 nIdx
= sal_uInt16(nRow
- BROW_CRIT1_ROW
);
1081 OUString aText
= comphelper::string::stripStart(m_pTextCell
->GetText(), ' ');
1084 if(!aText
.isEmpty())
1087 Reference
<XPropertySet
> xColumn
;
1088 OSQLParseNode
* pParseNode
= getDesignView()->getPredicateTreeFromEntry(pEntry
,aText
,aErrorMsg
,xColumn
);
1092 pParseNode
->parseNodeToPredicateStr(aCrit
,
1094 static_cast<OQueryController
&>(getDesignView()->getController()).getNumberFormatter(),
1097 getDesignView()->getLocale(),
1098 static_cast<sal_Char
>(getDesignView()->getDecimalSeparator().toChar()),
1099 &(static_cast<OQueryController
&>(getDesignView()->getController()).getParser().getContext()));
1106 sal_Int32 nType
= 0;
1107 xColumn
->getPropertyValue(PROPERTY_TYPE
) >>= nType
;
1110 case DataType::CHAR
:
1111 case DataType::VARCHAR
:
1112 case DataType::LONGVARCHAR
:
1113 case DataType::CLOB
:
1114 if(!aText
.startsWith("'") || !aText
.endsWith("'"))
1116 aText
= aText
.replaceAll("'", "''");
1117 aText
= "'" + aText
+ "'";
1123 ::connectivity::OSQLParser
& rParser
= static_cast<OQueryController
&>(getDesignView()->getController()).getParser();
1124 pParseNode
= rParser
.predicateTree(aErrorMsg
,
1126 static_cast<OQueryController
&>(getDesignView()->getController()).getNumberFormatter(),
1130 pParseNode
->parseNodeToPredicateStr(aCrit
,
1132 static_cast<OQueryController
&>(getDesignView()->getController()).getNumberFormatter(),
1135 getDesignView()->getLocale(),
1136 static_cast<sal_Char
>(getDesignView()->getDecimalSeparator().toChar()),
1137 &(static_cast<OQueryController
&>(getDesignView()->getController()).getParser().getContext()));
1142 if ( !m_bDisableErrorBox
)
1144 ScopedVclPtrInstance
<OSQLWarningBox
>(this, aErrorMsg
)->Execute();
1151 if ( !m_bDisableErrorBox
)
1153 ScopedVclPtrInstance
<OSQLWarningBox
>(this, aErrorMsg
)->Execute();
1159 strOldCellContents
= pEntry
->GetCriteria(nIdx
);
1160 pEntry
->SetCriteria(nIdx
, aCrit
);
1161 sNewValue
= pEntry
->GetCriteria(nIdx
);
1162 if(!aCrit
.isEmpty() && nRow
>= (GetRowCount()-1))
1166 if(!bError
&& Controller())
1167 Controller()->ClearModified();
1169 RowModified(GetCurRow(), GetCurColumnId());
1173 RowInserted( GetRowCount()-1 );
1174 m_bVisibleRow
.push_back(true);
1180 // and now the undo-action for the total
1181 appendUndoAction(strOldCellContents
,sNewValue
,nRow
);
1186 // did I store data in a FieldDescription which was empty before and which is not empty anymore after the changes?
1187 if ( pEntry
.is() && bWasEmpty
&& !pEntry
->IsEmpty() && !bError
)
1189 // Default to visible
1190 pEntry
->SetVisible();
1191 appendUndoAction("0","1",BROW_VIS_ROW
,bListAction
);
1192 RowModified(BROW_VIS_ROW
, GetCurColumnId());
1194 // if required add empty columns
1196 CheckFreeColumns(nDummy
);
1199 if ( bListAction
&& !m_bInUndoMode
)
1200 static_cast<OQueryController
&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
1202 return pEntry
!= nullptr && !bError
;
1205 bool OSelectionBrowseBox::SeekRow(long nRow
)
1208 return nRow
< m_nVisibleCount
;
1211 void OSelectionBrowseBox::PaintCell(OutputDevice
& rDev
, const Rectangle
& rRect
, sal_uInt16 nColumnId
) const
1213 rDev
.SetClipRegion(vcl::Region(rRect
));
1215 OTableFieldDescRef pEntry
= nullptr;
1216 sal_uInt16 nPos
= GetColumnPos(nColumnId
);
1217 if(getFields().size() > sal_uInt16(nPos
- 1))
1218 pEntry
= getFields()[nPos
- 1];
1223 long nRow
= GetRealRow(m_nSeekRow
);
1224 if (nRow
== BROW_VIS_ROW
)
1225 PaintTristate(rDev
, rRect
, pEntry
->IsVisible() ? TRISTATE_TRUE
: TRISTATE_FALSE
);
1227 rDev
.DrawText(rRect
, GetCellText(nRow
, nColumnId
),DrawTextFlags::VCenter
);
1229 rDev
.SetClipRegion( );
1232 void OSelectionBrowseBox::PaintStatusCell(OutputDevice
& rDev
, const Rectangle
& rRect
) const
1234 Rectangle
aRect(rRect
);
1235 aRect
.TopLeft().Y() -= 2;
1236 OUString
aLabel(ModuleRes(STR_QUERY_HANDLETEXT
));
1238 // from BROW_CRIT2_ROW onwards all rows are shown "or"
1239 sal_Int32 nToken
= (m_nSeekRow
>= GetBrowseRow(BROW_CRIT2_ROW
))
1240 ? BROW_CRIT2_ROW
: GetRealRow(m_nSeekRow
);
1241 rDev
.DrawText(aRect
, aLabel
.getToken(nToken
, ';'),DrawTextFlags::VCenter
);
1244 void OSelectionBrowseBox::RemoveColumn(sal_uInt16 _nColumnId
)
1246 OQueryController
& rController
= static_cast<OQueryController
&>(getDesignView()->getController());
1248 sal_uInt16 nPos
= GetColumnPos(_nColumnId
);
1249 // the control should always have exactly one more column: the HandleColumn
1250 OSL_ENSURE((nPos
== 0) || (nPos
<= getFields().size()), "OSelectionBrowseBox::RemoveColumn : invalid parameter nColId");
1251 // ColId is synonymous to Position, and the condition should be valid
1253 sal_uInt16 nCurCol
= GetCurColumnId();
1254 long nCurrentRow
= GetCurRow();
1258 getFields().erase( getFields().begin() + (nPos
- 1) );
1259 OTableFieldDescRef pEntry
= new OTableFieldDesc();
1260 pEntry
->SetColumnId(_nColumnId
);
1261 getFields().push_back(pEntry
);
1263 EditBrowseBox::RemoveColumn( _nColumnId
);
1264 InsertDataColumn( _nColumnId
, OUString(), DEFAULT_SIZE
);
1267 Rectangle aInvalidRect
= GetInvalidRect( _nColumnId
);
1268 Invalidate( aInvalidRect
);
1270 ActivateCell( nCurrentRow
, nCurCol
);
1272 rController
.setModified( true );
1274 invalidateUndoRedo();
1277 void OSelectionBrowseBox::RemoveField(sal_uInt16 nColumnId
)
1279 OQueryController
& rController
= static_cast<OQueryController
&>(getDesignView()->getController());
1281 sal_uInt16 nPos
= GetColumnPos(nColumnId
);
1282 OSL_ENSURE(getFields().size() > sal_uInt16(nPos
-1),"ID is to great!");
1284 OTableFieldDescRef pDesc
= getEntry((sal_uInt32
)(nPos
- 1)) ;
1285 pDesc
->SetColWidth( (sal_uInt16
)GetColumnWidth(nColumnId
) ); // was not stored this before
1287 // trigger UndoAction
1288 if ( !m_bInUndoMode
)
1290 OTabFieldDelUndoAct
* pUndoAction
= new OTabFieldDelUndoAct( this );
1291 pUndoAction
->SetTabFieldDescr(pDesc
);
1292 pUndoAction
->SetColumnPosition(nPos
);
1293 rController
.addUndoActionAndInvalidate( pUndoAction
);
1296 RemoveColumn(nColumnId
);
1298 invalidateUndoRedo();
1301 void OSelectionBrowseBox::adjustSelectionMode( bool _bClickedOntoHeader
, bool _bClickedOntoHandleCol
)
1303 // if a Header has been selected it should be shown otherwise not
1304 if ( _bClickedOntoHeader
)
1306 if (0 == GetSelectColumnCount() )
1307 // I am in the correct mode if a selected column exists
1308 if ( BrowserMode::HIDESELECT
== ( m_nMode
& BrowserMode::HIDESELECT
) )
1310 m_nMode
&= ~BrowserMode::HIDESELECT
;
1311 m_nMode
|= BrowserMode::MULTISELECTION
;
1315 else if ( BrowserMode::HIDESELECT
!= ( m_nMode
& BrowserMode::HIDESELECT
) )
1317 if ( GetSelectColumnCount() != 0 )
1320 if ( _bClickedOntoHandleCol
)
1322 m_nMode
|= BrowserMode::HIDESELECT
;
1323 m_nMode
&= ~BrowserMode::MULTISELECTION
;
1329 void OSelectionBrowseBox::MouseButtonDown(const BrowserMouseEvent
& rEvt
)
1333 bool bOnHandle
= HANDLE_ID
== rEvt
.GetColumnId();
1334 bool bOnHeader
= ( rEvt
.GetRow() < 0 ) && !bOnHandle
;
1335 adjustSelectionMode( bOnHeader
, bOnHandle
);
1337 EditBrowseBox::MouseButtonDown(rEvt
);
1340 void OSelectionBrowseBox::MouseButtonUp(const BrowserMouseEvent
& rEvt
)
1342 EditBrowseBox::MouseButtonUp( rEvt
);
1343 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature( ID_BROWSER_QUERY_EXECUTE
);
1346 void OSelectionBrowseBox::KeyInput( const KeyEvent
& rEvt
)
1348 if (IsColumnSelected(GetCurColumnId()))
1350 if (rEvt
.GetKeyCode().GetCode() == KEY_DELETE
&& // Delete rows
1351 !rEvt
.GetKeyCode().IsShift() &&
1352 !rEvt
.GetKeyCode().IsMod1())
1354 RemoveField(GetCurColumnId());
1358 EditBrowseBox::KeyInput(rEvt
);
1361 sal_Int8
OSelectionBrowseBox::AcceptDrop( const BrowserAcceptDropEvent
& rEvt
)
1363 sal_Int8 nDropAction
= DND_ACTION_NONE
;
1364 if ( rEvt
.GetRow() >= -1 )
1368 // allow the asterisk again
1369 m_bDisableErrorBox
= true;
1371 m_bDisableErrorBox
= false;
1374 // check if the format is already supported, if not deactivate the current cell and try again
1375 if ( OJoinExchObj::isFormatAvailable(GetDataFlavors()) )
1376 nDropAction
= DND_ACTION_LINK
;
1382 sal_Int8
OSelectionBrowseBox::ExecuteDrop( const BrowserExecuteDropEvent
& _rEvt
)
1385 TransferableDataHelper
aDropped(_rEvt
.maDropEvent
.Transferable
);
1386 if (!OJoinExchObj::isFormatAvailable(aDropped
.GetDataFlavorExVector()))
1388 OSL_FAIL("OSelectionBrowseBox::ExecuteDrop: this should never have passed AcceptDrop!");
1389 return DND_ACTION_NONE
;
1392 rtl::Reference
<OTableFieldDesc
> aInfo
;
1393 // insert the field at the selected position
1394 OJoinExchangeData jxdSource
= OJoinExchObj::GetSourceDescription(_rEvt
.maDropEvent
.Transferable
);
1395 InsertField(jxdSource
);
1397 return DND_ACTION_LINK
;
1400 OTableFieldDescRef
OSelectionBrowseBox::AppendNewCol( sal_uInt16 nCnt
)
1402 // one or more can be created, but the first one will is not returned
1403 sal_uInt32 nCount
= getFields().size();
1404 for (sal_uInt16 i
=0 ; i
<nCnt
; i
++)
1406 OTableFieldDescRef pEmptyEntry
= new OTableFieldDesc();
1407 getFields().push_back(pEmptyEntry
);
1408 sal_uInt16 nColumnId
= sal::static_int_cast
< sal_uInt16
>(getFields().size());
1409 pEmptyEntry
->SetColumnId( nColumnId
);
1411 InsertDataColumn( nColumnId
, OUString(), DEFAULT_SIZE
);
1414 return getFields()[nCount
];
1417 void OSelectionBrowseBox::DeleteFields(const OUString
& rAliasName
)
1419 if (!getFields().empty())
1421 sal_uInt16 nColId
= GetCurColumnId();
1422 sal_uInt32 nRow
= GetCurRow();
1424 bool bWasEditing
= IsEditing();
1428 OTableFields::const_reverse_iterator aIter
= getFields().rbegin();
1429 OTableFieldDescRef pEntry
= nullptr;
1430 for(sal_uInt16 nPos
=sal::static_int_cast
< sal_uInt16
>(getFields().size());aIter
!= getFields().rend();++aIter
,--nPos
)
1433 if ( pEntry
->GetAlias().equals( rAliasName
) )
1435 RemoveField( GetColumnId( nPos
) );
1441 ActivateCell(nRow
, nColId
);
1445 void OSelectionBrowseBox::SetColWidth(sal_uInt16 nColId
, long nNewWidth
)
1447 bool bWasEditing
= IsEditing();
1451 // create the BaseClass
1452 SetColumnWidth(nColId
, nNewWidth
);
1454 // tell it the FieldDescription
1455 OTableFieldDescRef pEntry
= getEntry(GetColumnPos(nColId
) - 1);
1457 pEntry
->SetColWidth(sal_uInt16(GetColumnWidth(nColId
)));
1460 ActivateCell(GetCurRow(), GetCurColumnId());
1463 Rectangle
OSelectionBrowseBox::GetInvalidRect( sal_uInt16 nColId
)
1465 // The rectangle is the full output area of the window
1466 Rectangle
aInvalidRect( Point(0,0), GetOutputSizePixel() );
1468 // now update the left side
1469 Rectangle
aFieldRect(GetCellRect( 0, nColId
)); // used instead of GetFieldRectPixel
1470 aInvalidRect
.Left() = aFieldRect
.Left();
1472 return aInvalidRect
;
1475 void OSelectionBrowseBox::InsertColumn(const OTableFieldDescRef
& pEntry
, sal_uInt16
& _nColumnPosition
)
1477 // the control should have exactly one more column: the HandleColumn
1478 OSL_ENSURE(_nColumnPosition
== BROWSER_INVALIDID
|| (_nColumnPosition
<= (long)getFields().size()), "OSelectionBrowseBox::InsertColumn : invalid parameter nColId.");
1479 // -1 means at the end. Count means at the end, others denotes a correct position
1481 sal_uInt16 nCurCol
= GetCurColumnId();
1482 long nCurrentRow
= GetCurRow();
1486 // remember the column id of the current position
1487 sal_uInt16 nColumnId
= GetColumnId(_nColumnPosition
);
1488 // put at the end of the list if to small or to big,
1489 if ((_nColumnPosition
== BROWSER_INVALIDID
) || (_nColumnPosition
>= getFields().size())) // append the field
1491 if (FindFirstFreeCol(_nColumnPosition
) == nullptr) // no more free columns
1494 _nColumnPosition
= sal::static_int_cast
< sal_uInt16
>(
1495 getFields().size());
1498 ++_nColumnPosition
; // within the list
1499 nColumnId
= GetColumnId(_nColumnPosition
);
1500 pEntry
->SetColumnId( nColumnId
);
1501 getFields()[ _nColumnPosition
- 1] = pEntry
;
1504 // check if the column ids are identical, if not we have to move
1505 if ( pEntry
->GetColumnId() != nColumnId
)
1507 sal_uInt16 nOldPosition
= GetColumnPos(pEntry
->GetColumnId());
1508 OSL_ENSURE( nOldPosition
!= 0,"Old position was 0. Not possible!");
1509 SetColumnPos(pEntry
->GetColumnId(),_nColumnPosition
);
1510 // we have to delete an empty field for the fields list, because the columns must have equal length
1511 if ( nOldPosition
> 0 && nOldPosition
<= getFields().size() )
1512 getFields()[nOldPosition
- 1] = pEntry
;
1514 ColumnMoved(pEntry
->GetColumnId(),false);
1517 if ( pEntry
->GetFunctionType() & (FKT_AGGREGATE
) )
1519 OUString sFunctionName
= pEntry
->GetFunction();
1520 if ( GetFunctionName(sal_uInt32(-1),sFunctionName
) )
1521 pEntry
->SetFunction(sFunctionName
);
1524 nColumnId
= pEntry
->GetColumnId();
1526 SetColWidth(nColumnId
,getDesignView()->getColWidth(GetColumnPos(nColumnId
)-1));
1528 Rectangle aInvalidRect
= GetInvalidRect( nColumnId
);
1529 Invalidate( aInvalidRect
);
1531 ActivateCell( nCurrentRow
, nCurCol
);
1532 static_cast<OQueryController
&>(getDesignView()->getController()).setModified( true );
1534 invalidateUndoRedo();
1537 OTableFieldDescRef
OSelectionBrowseBox::InsertField(const OJoinExchangeData
& jxdSource
)
1539 OQueryTableWindow
* pSourceWin
= static_cast<OQueryTableWindow
*>(jxdSource
.pListBox
->GetTabWin());
1543 // name and position of the selected field
1544 OUString aFieldName
= jxdSource
.pListBox
->GetEntryText(jxdSource
.pEntry
);
1545 sal_uInt32 nFieldIndex
= jxdSource
.pListBox
->GetModel()->GetAbsPos(jxdSource
.pEntry
);
1546 OTableFieldInfo
* pInf
= static_cast<OTableFieldInfo
*>(jxdSource
.pEntry
->GetUserData());
1548 // construct DragInfo, such that I use the other InsertField
1549 OTableFieldDescRef aInfo
= new OTableFieldDesc(pSourceWin
->GetTableName(),aFieldName
);
1550 aInfo
->SetTabWindow(pSourceWin
);
1551 aInfo
->SetFieldIndex(nFieldIndex
);
1552 aInfo
->SetFieldType(pInf
->GetKeyType());
1553 aInfo
->SetAlias(pSourceWin
->GetAliasName());
1555 aInfo
->SetDataType(pInf
->GetDataType());
1556 aInfo
->SetVisible();
1558 return InsertField(aInfo
);
1561 OTableFieldDescRef
OSelectionBrowseBox::InsertField(const OTableFieldDescRef
& _rInfo
, sal_uInt16 _nColumnPosition
, bool bVis
, bool bActivate
)
1564 if(m_nMaxColumns
&& m_nMaxColumns
<= FieldsCount())
1569 // new column description
1570 OTableFieldDescRef pEntry
= _rInfo
;
1571 pEntry
->SetVisible(bVis
);
1574 InsertColumn( pEntry
, _nColumnPosition
);
1576 if ( !m_bInUndoMode
)
1578 // trigger UndoAction
1579 OTabFieldCreateUndoAct
* pUndoAction
= new OTabFieldCreateUndoAct( this );
1580 pUndoAction
->SetTabFieldDescr( pEntry
);
1581 pUndoAction
->SetColumnPosition(_nColumnPosition
);
1582 getDesignView()->getController().addUndoActionAndInvalidate( pUndoAction
);
1588 sal_uInt16
OSelectionBrowseBox::FieldsCount()
1590 OTableFields::const_iterator aIter
= getFields().begin();
1591 OTableFields::const_iterator aEnd
= getFields().end();
1592 sal_uInt16 nCount
= 0;
1594 while (aIter
!= aEnd
)
1596 if ((*aIter
).is() && !(*aIter
)->IsEmpty())
1604 OTableFieldDescRef
OSelectionBrowseBox::FindFirstFreeCol(sal_uInt16
& _rColumnPosition
)
1606 OTableFields::const_iterator aIter
= getFields().begin();
1607 OTableFields::const_iterator aEnd
= getFields().end();
1609 _rColumnPosition
= BROWSER_INVALIDID
;
1611 while ( aIter
!= aEnd
)
1614 OTableFieldDescRef pEntry
= (*aIter
);
1615 if ( pEntry
.is() && pEntry
->IsEmpty() )
1623 void OSelectionBrowseBox::CheckFreeColumns(sal_uInt16
& _rColumnPosition
)
1625 if (FindFirstFreeCol(_rColumnPosition
) == nullptr)
1627 // it is full, append a Packen column
1628 AppendNewCol(DEFAULT_QUERY_COLS
);
1629 OSL_VERIFY(FindFirstFreeCol(_rColumnPosition
).is());
1633 void OSelectionBrowseBox::AddGroupBy( const OTableFieldDescRef
& rInfo
, sal_uInt32
/*_nCurrentPos*/)
1635 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
1636 if(!xConnection
.is())
1638 OSL_ENSURE(!rInfo
->IsEmpty(),"AddGroupBy:: OTableFieldDescRef sollte nicht Empty sein!");
1639 OTableFieldDescRef pEntry
;
1640 const Reference
<XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
1641 const ::comphelper::UStringMixEqual
bCase(xMeta
.is() && xMeta
->supportsMixedCaseQuotedIdentifiers());
1642 //sal_Bool bAppend = sal_False;
1644 OTableFields
& rFields
= getFields();
1645 OTableFields::const_iterator aIter
= rFields
.begin();
1646 OTableFields::const_iterator aEnd
= rFields
.end();
1647 for(;aIter
!= aEnd
;++aIter
)
1650 OSL_ENSURE(pEntry
.is(),"OTableFieldDescRef was null!");
1652 const OUString aField
= pEntry
->GetField();
1653 const OUString aAlias
= pEntry
->GetAlias();
1655 if (bCase(aField
,rInfo
->GetField()) &&
1656 bCase(aAlias
,rInfo
->GetAlias()) &&
1657 pEntry
->GetFunctionType() == rInfo
->GetFunctionType() &&
1658 pEntry
->GetFunction() == rInfo
->GetFunction())
1660 if ( pEntry
->isNumericOrAggreateFunction() && rInfo
->IsGroupBy() )
1662 pEntry
->SetGroupBy(false);
1663 aIter
= rFields
.end();
1668 if ( !pEntry
->IsGroupBy() && !pEntry
->HasCriteria() ) // here we have a where condition which is no having clause
1670 pEntry
->SetGroupBy(rInfo
->IsGroupBy());
1671 if(!m_bGroupByUnRelated
&& pEntry
->IsGroupBy())
1672 pEntry
->SetVisible();
1680 if (aIter
== rFields
.end())
1682 OTableFieldDescRef pTmp
= InsertField(rInfo
, BROWSER_INVALIDID
, false, false );
1683 if ( (pTmp
->isNumericOrAggreateFunction() && rInfo
->IsGroupBy()) ) // the GroupBy is inherited from rInfo
1684 pTmp
->SetGroupBy(false);
1688 void OSelectionBrowseBox::DuplicateConditionLevel( const sal_uInt16 nLevel
)
1690 const sal_uInt16 nNewLevel
= nLevel
+1;
1691 OTableFields
& rFields
= getFields();
1692 OTableFields::const_iterator aIter
= rFields
.begin();
1693 OTableFields::const_iterator aEnd
= rFields
.end();
1694 for(;aIter
!= aEnd
;++aIter
)
1696 OTableFieldDescRef pEntry
= *aIter
;
1698 OUString sValue
= pEntry
->GetCriteria(nLevel
);
1699 if ( !sValue
.isEmpty() )
1701 pEntry
->SetCriteria( nNewLevel
, sValue
);
1702 if ( nNewLevel
== (m_nVisibleCount
-BROW_CRIT1_ROW
-1) )
1704 RowInserted( GetRowCount()-1 );
1705 m_bVisibleRow
.push_back(true);
1708 m_bVisibleRow
[BROW_CRIT1_ROW
+ nNewLevel
] = true;
1713 void OSelectionBrowseBox::AddCondition( const OTableFieldDescRef
& rInfo
, const OUString
& rValue
, const sal_uInt16 nLevel
,bool _bAddOrOnOneLine
)
1715 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
1716 if(!xConnection
.is())
1718 OSL_ENSURE(rInfo
.is() && !rInfo
->IsEmpty(),"AddCondition:: OTableFieldDescRef sollte nicht Empty sein!");
1720 OTableFieldDescRef pLastEntry
;
1721 Reference
<XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
1722 ::comphelper::UStringMixEqual
bCase(xMeta
.is() && xMeta
->supportsMixedCaseQuotedIdentifiers());
1724 OTableFields
& rFields
= getFields();
1725 OTableFields::const_iterator aIter
= rFields
.begin();
1726 OTableFields::const_iterator aEnd
= rFields
.end();
1727 for(;aIter
!= aEnd
;++aIter
)
1729 OTableFieldDescRef pEntry
= *aIter
;
1730 const OUString aField
= pEntry
->GetField();
1731 const OUString aAlias
= pEntry
->GetAlias();
1733 if (bCase(aField
,rInfo
->GetField()) &&
1734 bCase(aAlias
,rInfo
->GetAlias()) &&
1735 pEntry
->GetFunctionType() == rInfo
->GetFunctionType() &&
1736 pEntry
->GetFunction() == rInfo
->GetFunction() &&
1737 pEntry
->IsGroupBy() == rInfo
->IsGroupBy() )
1739 if ( pEntry
->isNumericOrAggreateFunction() && rInfo
->IsGroupBy() )
1740 pEntry
->SetGroupBy(false);
1743 if(!m_bGroupByUnRelated
&& pEntry
->IsGroupBy())
1744 pEntry
->SetVisible();
1746 if (pEntry
->GetCriteria(nLevel
).isEmpty() )
1748 pEntry
->SetCriteria( nLevel
, rValue
);
1749 if(nLevel
== (m_nVisibleCount
-BROW_CRIT1_ROW
-1))
1751 RowInserted( GetRowCount()-1 );
1752 m_bVisibleRow
.push_back(true);
1755 m_bVisibleRow
[BROW_CRIT1_ROW
+ nLevel
] = true;
1758 if ( _bAddOrOnOneLine
)
1760 pLastEntry
= pEntry
;
1764 if ( pLastEntry
.is() )
1766 OUString sCriteria
= rValue
;
1767 OUString sOldCriteria
= pLastEntry
->GetCriteria( nLevel
);
1768 if ( !sOldCriteria
.isEmpty() )
1771 sCriteria
+= sOldCriteria
;
1772 sCriteria
+= " OR ";
1773 sCriteria
+= rValue
;
1776 pLastEntry
->SetCriteria( nLevel
, sCriteria
);
1777 if(nLevel
== (m_nVisibleCount
-BROW_CRIT1_ROW
-1))
1779 RowInserted( GetRowCount()-1 );
1780 m_bVisibleRow
.push_back(true);
1783 m_bVisibleRow
[BROW_CRIT1_ROW
+ nLevel
] = true;
1785 else if (aIter
== rFields
.end())
1787 OTableFieldDescRef pTmp
= InsertField(rInfo
, BROWSER_INVALIDID
, false, false );
1788 if ( pTmp
->isNumericOrAggreateFunction() && rInfo
->IsGroupBy() ) // the GroupBy was inherited from rInfo
1789 pTmp
->SetGroupBy(false);
1792 pTmp
->SetCriteria( nLevel
, rValue
);
1793 if(nLevel
== (m_nVisibleCount
-BROW_CRIT1_ROW
-1))
1795 RowInserted( GetRowCount()-1 );
1796 m_bVisibleRow
.push_back(true);
1803 void OSelectionBrowseBox::AddOrder( const OTableFieldDescRef
& rInfo
, const EOrderDir eDir
, sal_uInt32 _nCurrentPos
)
1805 if (_nCurrentPos
== 0)
1806 m_nLastSortColumn
= SORT_COLUMN_NONE
;
1808 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
1809 if(!xConnection
.is())
1811 OSL_ENSURE(!rInfo
->IsEmpty(),"AddOrder:: OTableFieldDescRef should not be Empty!");
1812 OTableFieldDescRef pEntry
;
1813 Reference
<XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
1814 ::comphelper::UStringMixEqual
bCase(xMeta
.is() && xMeta
->supportsMixedCaseQuotedIdentifiers());
1816 bool bAppend
= false;
1817 OTableFields
& rFields
= getFields();
1818 OTableFields::const_iterator aIter
= rFields
.begin();
1819 OTableFields::const_iterator aEnd
= rFields
.end();
1820 for(;aIter
!= aEnd
;++aIter
)
1823 OUString aField
= pEntry
->GetField();
1824 OUString aAlias
= pEntry
->GetAlias();
1826 if (bCase(aField
,rInfo
->GetField()) &&
1827 bCase(aAlias
,rInfo
->GetAlias()))
1829 sal_uInt32 nPos
= aIter
- rFields
.begin();
1830 bAppend
= (m_nLastSortColumn
!= SORT_COLUMN_NONE
) && (nPos
<= m_nLastSortColumn
);
1832 aIter
= rFields
.end();
1835 if ( !m_bOrderByUnRelated
)
1836 pEntry
->SetVisible();
1837 pEntry
->SetOrderDir( eDir
);
1838 m_nLastSortColumn
= nPos
;
1844 if (aIter
== rFields
.end())
1846 OTableFieldDescRef pTmp
= InsertField(rInfo
, BROWSER_INVALIDID
, false, false );
1849 m_nLastSortColumn
= pTmp
->GetColumnId() - 1;
1850 if ( !m_bOrderByUnRelated
&& !bAppend
)
1852 pTmp
->SetOrderDir( eDir
);
1857 void OSelectionBrowseBox::ArrangeControls(sal_uInt16
& nX
, sal_uInt16 nY
)
1859 EditBrowseBox::ArrangeControls(nX
, nY
);
1862 bool OSelectionBrowseBox::Save()
1866 bRet
= SaveModified();
1870 void OSelectionBrowseBox::CellModified()
1872 long nRow
= GetRealRow(GetCurRow());
1877 OTableFieldDescRef pEntry
= getEntry(GetColumnPos(GetCurColumnId()) - 1);
1879 sal_Int32 nIdx
= m_pOrderCell
->GetSelectEntryPos();
1880 if(!m_bOrderByUnRelated
&& nIdx
> 0 &&
1881 nIdx
!= LISTBOX_ENTRY_NOTFOUND
&&
1882 !pEntry
->IsEmpty() &&
1883 pEntry
->GetOrderDir() != ORDER_NONE
)
1885 m_pVisibleCell
->GetBox().Check();
1886 pEntry
->SetVisible();
1889 pEntry
->SetVisible(m_pVisibleCell
->GetBox().IsChecked());
1893 static_cast<OQueryController
&>(getDesignView()->getController()).setModified( true );
1896 void OSelectionBrowseBox::Fill()
1898 OSL_ENSURE(ColCount() >= 1, "OSelectionBrowseBox::Fill : please call only after inserting the handle column !");
1900 sal_uInt16 nColCount
= ColCount() - 1;
1901 if (nColCount
< DEFAULT_QUERY_COLS
)
1902 AppendNewCol(DEFAULT_QUERY_COLS
- nColCount
);
1905 Size
OSelectionBrowseBox::CalcOptimalSize( const Size
& _rAvailable
)
1907 Size
aReturn( _rAvailable
.Width(), GetTitleHeight() );
1909 aReturn
.Height() += ( m_nVisibleCount
? m_nVisibleCount
: 15 ) * GetDataRowHeight();
1910 aReturn
.Height() += 40; // just some space
1915 void OSelectionBrowseBox::Command(const CommandEvent
& rEvt
)
1917 switch (rEvt
.GetCommand())
1919 case CommandEventId::ContextMenu
:
1921 Point
aMenuPos( rEvt
.GetMousePosPixel() );
1923 if (!rEvt
.IsMouseEvent())
1925 if ( 1 == GetSelectColumnCount() )
1927 sal_uInt16 nSelId
= GetColumnId(
1928 sal::static_int_cast
< sal_uInt16
>(
1929 FirstSelectedColumn() ) );
1930 ::Rectangle
aColRect( GetFieldRectPixel( 0, nSelId
, false ) );
1932 aMenuPos
= aColRect
.TopCenter();
1936 EditBrowseBox::Command(rEvt
);
1941 sal_uInt16 nColId
= GetColumnId(GetColumnAtXPosPixel( aMenuPos
.X() ));
1942 long nRow
= GetRowAtYPosPixel( aMenuPos
.Y() );
1944 if (nRow
< 0 && nColId
> HANDLE_ID
)
1946 if ( !IsColumnSelected( nColId
) )
1948 adjustSelectionMode( true /* clicked onto a header */ , false /* not onto the handle col */ );
1949 SelectColumnId( nColId
);
1952 if (!static_cast<OQueryController
&>(getDesignView()->getController()).isReadOnly())
1954 PopupMenu
aContextMenu( ModuleRes( RID_QUERYCOLPOPUPMENU
) );
1955 switch (aContextMenu
.Execute(this, aMenuPos
))
1958 RemoveField(nColId
);
1961 case ID_BROWSER_COLWIDTH
:
1962 adjustBrowseBoxColumnWidth( this, nColId
);
1967 else if(nRow
>= 0 && nColId
<= HANDLE_ID
)
1969 if (!static_cast<OQueryController
&>(getDesignView()->getController()).isReadOnly())
1971 PopupMenu
aContextMenu(ModuleRes(RID_QUERYFUNCTION_POPUPMENU
));
1972 aContextMenu
.CheckItem( ID_QUERY_FUNCTION
, m_bVisibleRow
[BROW_FUNCTION_ROW
]);
1973 aContextMenu
.CheckItem( ID_QUERY_TABLENAME
, m_bVisibleRow
[BROW_TABLE_ROW
]);
1974 aContextMenu
.CheckItem( ID_QUERY_ALIASNAME
, m_bVisibleRow
[BROW_COLUMNALIAS_ROW
]);
1975 aContextMenu
.CheckItem( ID_QUERY_DISTINCT
, static_cast<OQueryController
&>(getDesignView()->getController()).isDistinct());
1977 switch (aContextMenu
.Execute(this, aMenuPos
))
1979 case ID_QUERY_FUNCTION
:
1980 SetRowVisible(BROW_FUNCTION_ROW
, !IsRowVisible(BROW_FUNCTION_ROW
));
1981 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_FUNCTIONS
);
1983 case ID_QUERY_TABLENAME
:
1984 SetRowVisible(BROW_TABLE_ROW
, !IsRowVisible(BROW_TABLE_ROW
));
1985 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_TABLES
);
1987 case ID_QUERY_ALIASNAME
:
1988 SetRowVisible(BROW_COLUMNALIAS_ROW
, !IsRowVisible(BROW_COLUMNALIAS_ROW
));
1989 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_ALIASES
);
1991 case ID_QUERY_DISTINCT
:
1992 static_cast<OQueryController
&>(getDesignView()->getController()).setDistinct(!static_cast<OQueryController
&>(getDesignView()->getController()).isDistinct());
1993 static_cast<OQueryController
&>(getDesignView()->getController()).setModified( true );
1994 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_DISTINCT_VALUES
);
1998 static_cast<OQueryController
&>(getDesignView()->getController()).setModified( true );
2003 EditBrowseBox::Command(rEvt
);
2010 EditBrowseBox::Command(rEvt
);
2014 bool OSelectionBrowseBox::IsRowVisible(sal_uInt16 _nWhich
) const
2016 OSL_ENSURE(_nWhich
<(m_bVisibleRow
.size()), "OSelectionBrowseBox::IsRowVisible : invalid parameter !");
2017 return m_bVisibleRow
[_nWhich
];
2020 void OSelectionBrowseBox::SetRowVisible(sal_uInt16 _nWhich
, bool _bVis
)
2022 OSL_ENSURE(_nWhich
<m_bVisibleRow
.size(), "OSelectionBrowseBox::SetRowVisible : invalid parameter !");
2024 bool bWasEditing
= IsEditing();
2028 // do this before removing or inserting rows, as this triggers ActivateCell-calls, which rely on m_bVisibleRow
2029 m_bVisibleRow
[_nWhich
] = !m_bVisibleRow
[_nWhich
];
2031 long nId
= GetBrowseRow(_nWhich
);
2047 long OSelectionBrowseBox::GetBrowseRow(long nRowId
) const
2049 sal_uInt16
nCount(0);
2050 for(long i
= 0 ; i
< nRowId
; ++i
)
2052 if ( m_bVisibleRow
[i
] )
2058 long OSelectionBrowseBox::GetRealRow(long nRowId
) const
2061 const long nCount
= m_bVisibleRow
.size();
2062 for(i
=0;i
< nCount
; ++i
)
2064 if(m_bVisibleRow
[i
])
2066 if(nErg
++ == nRowId
)
2070 OSL_ENSURE(nErg
<= long(m_bVisibleRow
.size()),"nErg kann nicht groesser als BROW_ROW_CNT sein!");
2074 static const long nVisibleRowMask
[] =
2089 sal_Int32
OSelectionBrowseBox::GetNoneVisibleRows() const
2092 // only the first 11 row are interesting
2093 sal_Int32 nSize
= SAL_N_ELEMENTS(nVisibleRowMask
);
2094 for(sal_Int32 i
=0;i
<nSize
;i
++)
2096 if(!m_bVisibleRow
[i
])
2097 nErg
|= nVisibleRowMask
[i
];
2102 void OSelectionBrowseBox::SetNoneVisbleRow(long nRows
)
2104 // only the first 11 row are interesting
2105 sal_Int32 nSize
= SAL_N_ELEMENTS(nVisibleRowMask
);
2106 for(sal_Int32 i
=0;i
< nSize
;i
++)
2107 m_bVisibleRow
[i
] = !(nRows
& nVisibleRowMask
[i
]);
2110 OUString
OSelectionBrowseBox::GetCellText(long nRow
, sal_uInt16 nColId
) const
2113 sal_uInt16 nPos
= GetColumnPos(nColId
);
2115 OTableFieldDescRef pEntry
= getFields()[nPos
-1];
2116 OSL_ENSURE(pEntry
!= nullptr, "OSelectionBrowseBox::GetCellText : invalid column id, prepare for GPF ... ");
2117 if ( pEntry
->IsEmpty() )
2123 case BROW_TABLE_ROW
:
2124 aText
= pEntry
->GetAlias();
2126 case BROW_FIELD_ROW
:
2128 OUString aField
= pEntry
->GetField();
2129 if (!aField
.isEmpty() && aField
[0] == '*') // * durch alias.* ersetzen
2131 aField
= pEntry
->GetAlias();
2132 if(!aField
.isEmpty())
2138 case BROW_ORDER_ROW
:
2139 if (pEntry
->GetOrderDir() != ORDER_NONE
)
2140 aText
= OUString(ModuleRes(STR_QUERY_SORTTEXT
)).getToken(sal::static_int_cast
< sal_uInt16
>(pEntry
->GetOrderDir()), ';');
2144 case BROW_COLUMNALIAS_ROW
:
2145 aText
= pEntry
->GetFieldAlias();
2147 case BROW_FUNCTION_ROW
:
2148 // we always show the group function at first
2149 if ( pEntry
->IsGroupBy() )
2150 aText
= m_aFunctionStrings
.getToken(comphelper::string::getTokenCount(m_aFunctionStrings
, ';')-1, ';');
2151 else if ( pEntry
->isNumericOrAggreateFunction() )
2152 aText
= pEntry
->GetFunction();
2155 aText
= pEntry
->GetCriteria(sal_uInt16(nRow
- BROW_CRIT1_ROW
));
2160 bool OSelectionBrowseBox::GetFunctionName(sal_uInt32 _nFunctionTokenId
, OUString
& rFkt
)
2163 switch(_nFunctionTokenId
)
2165 case SQL_TOKEN_COUNT
:
2166 rFkt
= (m_pFunctionCell
->GetEntryCount() < 3) ? m_pFunctionCell
->GetEntry(1) : m_pFunctionCell
->GetEntry(2);
2169 rFkt
= m_pFunctionCell
->GetEntry(1);
2172 rFkt
= m_pFunctionCell
->GetEntry(3);
2175 rFkt
= m_pFunctionCell
->GetEntry(4);
2178 rFkt
= m_pFunctionCell
->GetEntry(5);
2180 case SQL_TOKEN_EVERY
:
2181 rFkt
= m_pFunctionCell
->GetEntry(6);
2184 rFkt
= m_pFunctionCell
->GetEntry(7);
2186 case SQL_TOKEN_SOME
:
2187 rFkt
= m_pFunctionCell
->GetEntry(8);
2189 case SQL_TOKEN_STDDEV_POP
:
2190 rFkt
= m_pFunctionCell
->GetEntry(9);
2192 case SQL_TOKEN_STDDEV_SAMP
:
2193 rFkt
= m_pFunctionCell
->GetEntry(10);
2195 case SQL_TOKEN_VAR_SAMP
:
2196 rFkt
= m_pFunctionCell
->GetEntry(11);
2198 case SQL_TOKEN_VAR_POP
:
2199 rFkt
= m_pFunctionCell
->GetEntry(12);
2201 case SQL_TOKEN_COLLECT
:
2202 rFkt
= m_pFunctionCell
->GetEntry(13);
2204 case SQL_TOKEN_FUSION
:
2205 rFkt
= m_pFunctionCell
->GetEntry(14);
2207 case SQL_TOKEN_INTERSECTION
:
2208 rFkt
= m_pFunctionCell
->GetEntry(15);
2212 sal_Int32 nCount
= comphelper::string::getTokenCount(m_aFunctionStrings
, ';');
2214 for( i
= 0; i
< nCount
-1; i
++ ) // grouping is not counted
2216 if(rFkt
.equalsIgnoreAsciiCase(m_aFunctionStrings
.getToken(i
, ';')))
2218 rFkt
= m_aFunctionStrings
.getToken(i
, ';');
2230 OUString
OSelectionBrowseBox::GetCellContents(sal_Int32 nCellIndex
, sal_uInt16 nColId
)
2232 if ( GetCurColumnId() == nColId
&& !m_bInUndoMode
)
2235 sal_uInt16 nPos
= GetColumnPos(nColId
);
2236 OTableFieldDescRef pEntry
= getFields()[nPos
- 1];
2237 OSL_ENSURE(pEntry
!= nullptr, "OSelectionBrowseBox::GetCellContents : invalid column id, prepare for GPF ... ");
2242 return pEntry
->IsVisible() ? OUStringLiteral("1") : OUStringLiteral("0");
2243 case BROW_ORDER_ROW
:
2245 sal_Int32 nIdx
= m_pOrderCell
->GetSelectEntryPos();
2246 if (nIdx
== LISTBOX_ENTRY_NOTFOUND
)
2248 return OUString::number(nIdx
);
2251 return GetCellText(nCellIndex
, nColId
);
2255 void OSelectionBrowseBox::SetCellContents(sal_Int32 nRow
, sal_uInt16 nColId
, const OUString
& strNewText
)
2257 bool bWasEditing
= IsEditing() && (GetCurColumnId() == nColId
) && IsRowVisible(static_cast<sal_uInt16
>(nRow
)) && (GetCurRow() == static_cast<sal_uInt16
>(GetBrowseRow(nRow
)));
2261 sal_uInt16 nPos
= GetColumnPos(nColId
);
2262 OTableFieldDescRef pEntry
= getEntry(nPos
- 1);
2263 OSL_ENSURE(pEntry
!= nullptr, "OSelectionBrowseBox::SetCellContents : invalid column id, prepare for GPF ... ");
2268 pEntry
->SetVisible(strNewText
== "1");
2270 case BROW_FIELD_ROW
:
2271 pEntry
->SetField(strNewText
);
2273 case BROW_TABLE_ROW
:
2274 pEntry
->SetAlias(strNewText
);
2276 case BROW_ORDER_ROW
:
2278 sal_uInt16 nIdx
= (sal_uInt16
)strNewText
.toInt32();
2279 pEntry
->SetOrderDir(EOrderDir(nIdx
));
2281 case BROW_COLUMNALIAS_ROW
:
2282 pEntry
->SetFieldAlias(strNewText
);
2284 case BROW_FUNCTION_ROW
:
2286 OUString sGroupFunctionName
= m_aFunctionStrings
.getToken(comphelper::string::getTokenCount(m_aFunctionStrings
, ';')-1, ';');
2287 pEntry
->SetFunction(strNewText
);
2288 // first reset this two member
2289 sal_Int32 nFunctionType
= pEntry
->GetFunctionType();
2290 nFunctionType
&= ~FKT_AGGREGATE
;
2291 pEntry
->SetFunctionType(nFunctionType
);
2292 if ( pEntry
->IsGroupBy() && !sGroupFunctionName
.equalsIgnoreAsciiCase(strNewText
) )
2293 pEntry
->SetGroupBy(false);
2295 if ( sGroupFunctionName
.equalsIgnoreAsciiCase(strNewText
) )
2296 pEntry
->SetGroupBy(true);
2297 else if ( !strNewText
.isEmpty() )
2299 nFunctionType
|= FKT_AGGREGATE
;
2300 pEntry
->SetFunctionType(nFunctionType
);
2304 pEntry
->SetCriteria(sal_uInt16(nRow
- BROW_CRIT1_ROW
), strNewText
);
2307 long nCellIndex
= GetRealRow(nRow
);
2308 if(IsRowVisible(static_cast<sal_uInt16
>(nRow
)))
2309 RowModified(nCellIndex
, nColId
);
2311 // the appropriate field-description is now empty -> set Visible to sal_False (now it is consistent to normal empty rows)
2312 if (pEntry
->IsEmpty())
2313 pEntry
->SetVisible(false);
2316 ActivateCell(nCellIndex
, nColId
);
2318 static_cast<OQueryController
&>(getDesignView()->getController()).setModified( true );
2321 void OSelectionBrowseBox::ColumnResized(sal_uInt16 nColId
)
2323 if (static_cast<OQueryController
&>(getDesignView()->getController()).isReadOnly())
2325 // The resizing of columns can't be suppressed (BrowseBox doesn't support that) so we have to do this
2326 // fake. It's not _that_ bad : the user may change column widths while in read-only mode to see all details
2327 // but the changes aren't permanent ...
2329 sal_uInt16 nPos
= GetColumnPos(nColId
);
2330 OSL_ENSURE(nPos
<= getFields().size(),"ColumnResized:: nColId sollte nicht groesser als List::count sein!");
2331 OTableFieldDescRef pEntry
= getEntry(nPos
-1);
2332 OSL_ENSURE(pEntry
.is(), "OSelectionBrowseBox::ColumnResized : keine FieldDescription !");
2333 static_cast<OQueryController
&>(getDesignView()->getController()).setModified( true );
2334 EditBrowseBox::ColumnResized(nColId
);
2338 if ( !m_bInUndoMode
)
2340 // create the undo action
2341 OTabFieldSizedUndoAct
* pUndo
= new OTabFieldSizedUndoAct(this);
2342 pUndo
->SetColumnPosition( nPos
);
2343 pUndo
->SetOriginalWidth(pEntry
->GetColWidth());
2344 getDesignView()->getController().addUndoActionAndInvalidate(pUndo
);
2346 pEntry
->SetColWidth(sal_uInt16(GetColumnWidth(nColId
)));
2350 sal_uInt32
OSelectionBrowseBox::GetTotalCellWidth(long nRowId
, sal_uInt16 nColId
)
2352 sal_uInt16 nPos
= GetColumnPos(nColId
);
2353 OSL_ENSURE((nPos
== 0) || (nPos
<= getFields().size()), "OSelectionBrowseBox::GetTotalCellWidth : invalid parameter nColId");
2355 OTableFieldDescRef pEntry
= getFields()[nPos
-1];
2356 OSL_ENSURE(pEntry
.is(), "OSelectionBrowseBox::GetTotalCellWidth : invalid FieldDescription !");
2358 long nRow
= GetRealRow(nRowId
);
2359 OUString
strText(GetCellText(nRow
, nColId
));
2360 return GetDataWindow().LogicToPixel(Size(GetDataWindow().GetTextWidth(strText
),0)).Width();
2363 bool OSelectionBrowseBox::isCutAllowed()
2365 bool bCutAllowed
= false;
2366 long nRow
= GetRealRow(GetCurRow());
2370 case BROW_ORDER_ROW
:
2371 case BROW_TABLE_ROW
:
2372 case BROW_FUNCTION_ROW
:
2374 case BROW_FIELD_ROW
:
2375 bCutAllowed
= !m_pFieldCell
->GetSelected().isEmpty();
2378 bCutAllowed
= !m_pTextCell
->GetSelected().isEmpty();
2384 void OSelectionBrowseBox::cut()
2386 long nRow
= GetRealRow(GetCurRow());
2389 case BROW_FIELD_ROW
:
2390 m_pFieldCell
->Cut();
2391 m_pFieldCell
->SetModifyFlag();
2395 m_pTextCell
->SetModifyFlag();
2398 RowModified(GetBrowseRow(nRow
), GetCurColumnId());
2400 invalidateUndoRedo();
2403 void OSelectionBrowseBox::paste()
2405 long nRow
= GetRealRow(GetCurRow());
2408 case BROW_FIELD_ROW
:
2409 m_pFieldCell
->Paste();
2410 m_pFieldCell
->SetModifyFlag();
2413 m_pTextCell
->Paste();
2414 m_pTextCell
->SetModifyFlag();
2416 RowModified(GetBrowseRow(nRow
), GetCurColumnId());
2417 invalidateUndoRedo();
2420 bool OSelectionBrowseBox::isPasteAllowed()
2422 bool bPasteAllowed
= true;
2423 long nRow
= GetRealRow(GetCurRow());
2427 case BROW_ORDER_ROW
:
2428 case BROW_TABLE_ROW
:
2429 case BROW_FUNCTION_ROW
:
2430 bPasteAllowed
= false;
2433 return bPasteAllowed
;
2436 bool OSelectionBrowseBox::isCopyAllowed()
2438 return isCutAllowed();
2441 void OSelectionBrowseBox::copy()
2443 long nRow
= GetRealRow(GetCurRow());
2446 case BROW_FIELD_ROW
:
2447 m_pFieldCell
->Copy();
2450 m_pTextCell
->Copy();
2454 void OSelectionBrowseBox::appendUndoAction(const OUString
& _rOldValue
, const OUString
& _rNewValue
, sal_Int32 _nRow
, bool& _bListAction
)
2456 if ( !m_bInUndoMode
&& _rNewValue
!= _rOldValue
)
2458 if ( !_bListAction
)
2460 _bListAction
= true;
2461 static_cast<OQueryController
&>(getDesignView()->getController()).GetUndoManager().EnterListAction(OUString(),OUString());
2463 appendUndoAction(_rOldValue
,_rNewValue
,_nRow
);
2467 void OSelectionBrowseBox::appendUndoAction(const OUString
& _rOldValue
,const OUString
& _rNewValue
,sal_Int32 _nRow
)
2469 if ( !m_bInUndoMode
&& _rNewValue
!= _rOldValue
)
2471 OTabFieldCellModifiedUndoAct
* pUndoAct
= new OTabFieldCellModifiedUndoAct(this);
2472 pUndoAct
->SetCellIndex(_nRow
);
2473 OSL_ENSURE(GetColumnPos(GetCurColumnId()) != BROWSER_INVALIDID
,"Current position isn't valid!");
2474 pUndoAct
->SetColumnPosition( GetColumnPos(GetCurColumnId()) );
2475 pUndoAct
->SetCellContents(_rOldValue
);
2476 getDesignView()->getController().addUndoActionAndInvalidate(pUndoAct
);
2480 IMPL_LINK_NOARG_TYPED(OSelectionBrowseBox
, OnInvalidateTimer
, Timer
*, void)
2482 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature(SID_CUT
);
2483 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature(SID_COPY
);
2484 static_cast<OQueryController
&>(getDesignView()->getController()).InvalidateFeature(SID_PASTE
);
2486 m_timerInvalidate
.Start();
2489 void OSelectionBrowseBox::stopTimer()
2491 m_bStopTimer
= true;
2492 if (m_timerInvalidate
.IsActive())
2493 m_timerInvalidate
.Stop();
2496 void OSelectionBrowseBox::startTimer()
2498 m_bStopTimer
= false;
2499 if (!m_timerInvalidate
.IsActive())
2500 m_timerInvalidate
.Start();
2503 OTableFields
& OSelectionBrowseBox::getFields() const
2505 OQueryController
& rController
= static_cast<OQueryController
&>(getDesignView()->getController());
2506 return rController
.getTableFieldDesc();
2509 void OSelectionBrowseBox::enableControl(const OTableFieldDescRef
& _rEntry
,Window
* _pControl
)
2511 bool bEnable
= !_rEntry
->isCondition();
2512 _pControl
->Enable(bEnable
);
2513 _pControl
->EnableInput(bEnable
);
2516 void OSelectionBrowseBox::setTextCellContext(const OTableFieldDescRef
& _rEntry
,const OUString
& _sText
,const OString
& _sHelpId
)
2518 m_pTextCell
->SetText(_sText
);
2519 m_pTextCell
->ClearModifyFlag();
2520 if (!m_pTextCell
->HasFocus())
2521 m_pTextCell
->GrabFocus();
2523 enableControl(_rEntry
,m_pTextCell
);
2525 if (m_pTextCell
->GetHelpId() != _sHelpId
)
2526 // as TextCell is used in various contexts I will delete the cached HelpText
2527 m_pTextCell
->SetHelpText(OUString());
2528 m_pTextCell
->SetHelpId(_sHelpId
);
2531 void OSelectionBrowseBox::invalidateUndoRedo()
2533 OQueryController
& rController
= static_cast<OQueryController
&>(getDesignView()->getController());
2534 rController
.InvalidateFeature( ID_BROWSER_UNDO
);
2535 rController
.InvalidateFeature( ID_BROWSER_REDO
);
2536 rController
.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE
);
2539 OTableFieldDescRef
OSelectionBrowseBox::getEntry(OTableFields::size_type _nPos
)
2541 // we have to check if we need a new entry at this position
2542 OTableFields
& aFields
= getFields();
2543 OSL_ENSURE(aFields
.size() > _nPos
,"ColID is to great!");
2545 OTableFieldDescRef pEntry
= aFields
[_nPos
];
2546 OSL_ENSURE(pEntry
.is(),"Invalid entry!");
2549 pEntry
= new OTableFieldDesc();
2550 pEntry
->SetColumnId(
2551 GetColumnId(sal::static_int_cast
< sal_uInt16
>(_nPos
+1)));
2552 aFields
[_nPos
] = pEntry
;
2557 void OSelectionBrowseBox::GetFocus()
2559 if(!IsEditing() && !m_bWasEditing
)
2561 EditBrowseBox::GetFocus();
2564 void OSelectionBrowseBox::DeactivateCell(bool _bUpdate
)
2566 m_bWasEditing
= true;
2567 EditBrowseBox::DeactivateCell(_bUpdate
);
2568 m_bWasEditing
= false;
2571 OUString
OSelectionBrowseBox::GetRowDescription( sal_Int32 _nRow
) const
2573 OUString
aLabel(ModuleRes(STR_QUERY_HANDLETEXT
));
2575 // from BROW_CRIT2_ROW onwards all rows are shown as "or"
2576 sal_Int32 nToken
= (_nRow
>= GetBrowseRow(BROW_CRIT2_ROW
))
2577 ? BROW_CRIT2_ROW
: GetRealRow(_nRow
);
2578 return aLabel
.getToken(nToken
, ';');
2581 OUString
OSelectionBrowseBox::GetAccessibleObjectName( ::svt::AccessibleBrowseBoxObjType _eObjType
,sal_Int32 _nPosition
) const
2586 case ::svt::BBTYPE_ROWHEADERCELL
:
2587 sRetText
= GetRowDescription(_nPosition
);
2590 sRetText
= EditBrowseBox::GetAccessibleObjectDescription(_eObjType
,_nPosition
);
2595 bool OSelectionBrowseBox::fillEntryTable(OTableFieldDescRef
& _pEntry
,const OUString
& _sTableName
)
2598 OJoinTableView::OTableWindowMap
& rTabWinList
= getDesignView()->getTableView()->GetTabWinMap();
2599 OJoinTableView::OTableWindowMap::const_iterator aIter
= rTabWinList
.find(_sTableName
);
2600 if(aIter
!= rTabWinList
.end())
2602 OQueryTableWindow
* pEntryTab
= static_cast<OQueryTableWindow
*>(aIter
->second
.get());
2605 _pEntry
->SetTable(pEntryTab
->GetTableName());
2606 _pEntry
->SetTabWindow(pEntryTab
);
2613 void OSelectionBrowseBox::setFunctionCell(OTableFieldDescRef
& _pEntry
)
2615 Reference
< XConnection
> xConnection
= static_cast<OQueryController
&>(getDesignView()->getController()).getConnection();
2616 if ( xConnection
.is() )
2618 // Aggregate functions in general only available with Core SQL
2619 if ( lcl_SupportsCoreSQLGrammar(xConnection
) )
2621 // if we have an asterisk, no other function than count is allowed
2622 m_pFunctionCell
->Clear();
2623 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(0, ';'));
2624 if ( isFieldNameAsterisk(_pEntry
->GetField()) )
2625 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(2, ';')); // 2 -> COUNT
2628 sal_Int32 nCount
= comphelper::string::getTokenCount(m_aFunctionStrings
, ';');
2629 if ( _pEntry
->isNumeric() )
2631 for( sal_Int32 nIdx
= 1; nIdx
< nCount
; nIdx
++ )
2632 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(nIdx
, ';'));
2635 if ( _pEntry
->IsGroupBy() )
2637 OSL_ENSURE(!_pEntry
->isNumeric(),"Not allowed to combine group by and numeric values!");
2638 m_pFunctionCell
->SelectEntry(m_pFunctionCell
->GetEntry(m_pFunctionCell
->GetEntryCount() - 1));
2640 else if ( m_pFunctionCell
->GetEntryPos(OUString(_pEntry
->GetFunction())) != COMBOBOX_ENTRY_NOTFOUND
)
2641 m_pFunctionCell
->SelectEntry(OUString(_pEntry
->GetFunction()));
2643 m_pFunctionCell
->SelectEntryPos(0);
2645 enableControl(_pEntry
,m_pFunctionCell
);
2649 // only COUNT(*) and COUNT("table".*) allowed
2650 bool bCountRemoved
= !isFieldNameAsterisk(_pEntry
->GetField());
2651 if ( bCountRemoved
)
2652 m_pFunctionCell
->RemoveEntry(1);
2654 if ( !bCountRemoved
&& m_pFunctionCell
->GetEntryCount() < 2)
2655 m_pFunctionCell
->InsertEntry(m_aFunctionStrings
.getToken(2, ';')); // 2 -> COUNT
2657 if(m_pFunctionCell
->GetEntryPos(OUString(_pEntry
->GetFunction())) != COMBOBOX_ENTRY_NOTFOUND
)
2658 m_pFunctionCell
->SelectEntry(_pEntry
->GetFunction());
2660 m_pFunctionCell
->SelectEntryPos(0);
2665 Reference
< XAccessible
> OSelectionBrowseBox::CreateAccessibleCell( sal_Int32 _nRow
, sal_uInt16 _nColumnPos
)
2667 OTableFieldDescRef pEntry
= nullptr;
2668 if(getFields().size() > sal_uInt16(_nColumnPos
- 1))
2669 pEntry
= getFields()[_nColumnPos
- 1];
2671 if ( _nRow
== BROW_VIS_ROW
&& pEntry
.is() )
2672 return EditBrowseBox::CreateAccessibleCheckBoxCell( _nRow
, _nColumnPos
,pEntry
->IsVisible() ? TRISTATE_TRUE
: TRISTATE_FALSE
);
2674 return EditBrowseBox::CreateAccessibleCell( _nRow
, _nColumnPos
);
2677 bool OSelectionBrowseBox::HasFieldByAliasName(const OUString
& rFieldName
, OTableFieldDescRef
& rInfo
) const
2679 OTableFields
& aFields
= getFields();
2680 OTableFields::const_iterator aIter
= aFields
.begin();
2681 OTableFields::const_iterator aEnd
= aFields
.end();
2683 for(;aIter
!= aEnd
;++aIter
)
2685 if ( (*aIter
)->GetFieldAlias() == rFieldName
)
2691 return aIter
!= aEnd
;
2694 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */