LibreOffice Module dbaccess (master) 1
SelectionBrowseBox.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <string_view>
23
25#include <com/sun/star/sdbc/XDatabaseMetaData.hpp>
26#include <com/sun/star/sdbc/DataType.hpp>
27#include <JoinExchange.hxx>
28#include <QueryDesignView.hxx>
29#include <querycontroller.hxx>
30#include <sqlbison.hxx>
31#include <QueryTableView.hxx>
32#include <browserids.hxx>
34#include <comphelper/string.hxx>
35#include "TableFieldInfo.hxx"
36#include <core_resource.hxx>
37#include <strings.hrc>
38#include <strings.hxx>
39#include <helpids.h>
40#include "QTableWindow.hxx"
41#include <vcl/weld.hxx>
42#include <vcl/settings.hxx>
44#include <sqlmessage.hxx>
45#include <UITools.hxx>
46#include <o3tl/safeint.hxx>
47#include <osl/diagnose.h>
49#include <vcl/commandevent.hxx>
50#include <vcl/svapp.hxx>
52#include <o3tl/string_view.hxx>
53
54using namespace ::svt;
55using namespace ::dbaui;
56using namespace ::connectivity;
57using namespace ::com::sun::star::uno;
58using namespace ::com::sun::star::sdbc;
59using namespace ::com::sun::star::beans;
60using namespace ::com::sun::star::container;
61using namespace ::com::sun::star::util;
62using namespace ::com::sun::star::accessibility;
63
64#define DEFAULT_QUERY_COLS 20
65#define DEFAULT_SIZE GetTextWidth("0") * 30
66#define HANDLE_ID 0
67#define HANDLE_COLUMN_WIDTH 70
68#define SORT_COLUMN_NONE 0xFFFFFFFF
69
70namespace
71{
72 bool isFieldNameAsterisk(std::u16string_view _sFieldName )
73 {
74 bool bAsterisk = _sFieldName.empty() || _sFieldName[0] == '*';
75 if ( !bAsterisk )
76 {
77 sal_Int32 nTokenCount = comphelper::string::getTokenCount(_sFieldName, '.');
78 if ( (nTokenCount == 2 && o3tl::getToken(_sFieldName,1,'.')[0] == '*' )
79 || (nTokenCount == 3 && o3tl::getToken(_sFieldName,2,'.')[0] == '*' ) )
80 {
81 bAsterisk = true;
82 }
83 }
84 return bAsterisk;
85 }
86 bool lcl_SupportsCoreSQLGrammar(const Reference< XConnection>& _xConnection)
87 {
88 bool bSupportsCoreGrammar = false;
89 if ( _xConnection.is() )
90 {
91 try
92 {
93 Reference< XDatabaseMetaData > xMetaData = _xConnection->getMetaData();
94 bSupportsCoreGrammar = xMetaData.is() && xMetaData->supportsCoreSQLGrammar();
95 }
96 catch(Exception&)
97 {
98 }
99 }
100 return bSupportsCoreGrammar;
101 }
102}
103
104OSelectionBrowseBox::OSelectionBrowseBox( vcl::Window* pParent )
107 ,m_timerInvalidate("dbaccess OSelectionBrowseBox m_timerInvalidate")
108 ,m_nSeekRow(0)
109 ,m_nMaxColumns(0)
110 ,m_aFunctionStrings(DBA_RES(STR_QUERY_FUNCTIONS))
111 ,m_nVisibleCount(0)
112 ,m_nLastSortColumn(SORT_COLUMN_NONE)
113 ,m_bOrderByUnRelated(true)
114 ,m_bGroupByUnRelated(true)
115 ,m_bStopTimer(false)
116 ,m_bWasEditing(false)
117 ,m_bDisableErrorBox(false)
118 ,m_bInUndoMode(false)
119{
121
122 m_nMode = BrowserMode::COLUMNSELECTION | BrowserMode::HIDESELECT
123 | BrowserMode::KEEPHIGHLIGHT | BrowserMode::HIDECURSOR
124 | BrowserMode::HLINES | BrowserMode::VLINES
125 | BrowserMode::HEADERBAR_NEW ;
126
133
137 weld::ComboBox& rOrderBox = m_pOrderCell->get_widget();
140
141 // switch off triState of css::form::CheckBox
142 m_pVisibleCell->EnableTriState( false );
143
144 vcl::Font aTitleFont = OutputDevice::GetDefaultFont( DefaultFontType::SANS_UNICODE,Window::GetSettings().GetLanguageTag().getLanguageType(),GetDefaultFontFlags::OnlyOne);
145 aTitleFont.SetFontSize(Size(0, 6));
146 SetTitleFont(aTitleFont);
147
148 const OUString aTxt(DBA_RES(STR_QUERY_SORTTEXT));
149 for (sal_Int32 nIdx {0}; nIdx>=0;)
150 rOrderBox.append_text(OUString(o3tl::getToken(aTxt, 0, ';', nIdx)));
151
152 m_bVisibleRow.insert(m_bVisibleRow.end(), BROW_ROW_CNT, true);
153
154 m_bVisibleRow[BROW_FUNCTION_ROW] = false; // first hide
155
159}
160
162{
163 disposeOnce();
164}
165
167{
168 m_pTextCell.disposeAndClear();
169 m_pVisibleCell.disposeAndClear();
170 m_pFieldCell.disposeAndClear();
171 m_pTableCell.disposeAndClear();
172 m_pOrderCell.disposeAndClear();
173 m_pFunctionCell.disposeAndClear();
175}
176
178{
180 if(xConnection.is())
181 {
182 const IParseContext& rContext = static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext();
183 const IParseContext::InternationalKeyCode eFunctions[] = {
184 IParseContext::InternationalKeyCode::Avg,IParseContext::InternationalKeyCode::Count,IParseContext::InternationalKeyCode::Max
185 ,IParseContext::InternationalKeyCode::Min,IParseContext::InternationalKeyCode::Sum
186 ,IParseContext::InternationalKeyCode::Every
187 ,IParseContext::InternationalKeyCode::Any
188 ,IParseContext::InternationalKeyCode::Some
189 ,IParseContext::InternationalKeyCode::StdDevPop
190 ,IParseContext::InternationalKeyCode::StdDevSamp
191 ,IParseContext::InternationalKeyCode::VarSamp
192 ,IParseContext::InternationalKeyCode::VarPop
193 ,IParseContext::InternationalKeyCode::Collect
194 ,IParseContext::InternationalKeyCode::Fusion
195 ,IParseContext::InternationalKeyCode::Intersection
196 };
197
198 OUString sGroup = m_aFunctionStrings.copy(m_aFunctionStrings.lastIndexOf(';')+1);
199 m_aFunctionStrings = m_aFunctionStrings.getToken(0, ';');
200
201 for (IParseContext::InternationalKeyCode eFunction : eFunctions)
202 {
203 m_aFunctionStrings += ";" + OStringToOUString(rContext.getIntlKeywordAscii(eFunction), RTL_TEXTENCODING_UTF8);
204 }
205 m_aFunctionStrings += ";" + sGroup;
206
207 // Aggregate functions in general available only with Core SQL
208 // We slip in a few optionals one, too.
209 if ( lcl_SupportsCoreSQLGrammar(xConnection) )
210 {
211 weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
212 for (sal_Int32 nIdx {0}; nIdx>=0;)
213 rComboBox.append_text(m_aFunctionStrings.getToken(0, ';', nIdx));
214 }
215 else // else only COUNT(*) and COUNT("table".*)
216 {
217 weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
218 rComboBox.append_text(m_aFunctionStrings.getToken(0, ';'));
219 rComboBox.append_text(m_aFunctionStrings.getToken(2, ';')); // 2 -> COUNT
220 }
221 try
222 {
223 Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
224 if ( xMetaData.is() )
225 {
226 m_bOrderByUnRelated = xMetaData->supportsOrderByUnrelated();
227 m_bGroupByUnRelated = xMetaData->supportsGroupByUnrelated();
228 }
229 }
230 catch(Exception&)
231 {
232 }
233 }
234
235 Init();
236}
237
239{
240 OSL_ENSURE(static_cast<const OQueryDesignView*>(GetParent()),"Parent isn't an OQueryDesignView!");
241 return static_cast<OQueryDesignView*>(GetParent());
242}
243
245{
246 OSL_ENSURE(static_cast<const OQueryDesignView*>(GetParent()),"Parent isn't an OQueryDesignView!");
247 return static_cast<OQueryDesignView*>(GetParent());
248}
249
250namespace
251{
252 class OSelectionBrwBoxHeader : public ::svt::EditBrowserHeader
253 {
254 VclPtr<OSelectionBrowseBox> m_pBrowseBox;
255 protected:
256 virtual void Select() override;
257 public:
258 explicit OSelectionBrwBoxHeader(OSelectionBrowseBox* pParent);
259 virtual ~OSelectionBrwBoxHeader() override { disposeOnce(); }
260 virtual void dispose() override { m_pBrowseBox.clear(); ::svt::EditBrowserHeader::dispose(); }
261 };
262 OSelectionBrwBoxHeader::OSelectionBrwBoxHeader(OSelectionBrowseBox* pParent)
263 : ::svt::EditBrowserHeader(pParent,WB_BUTTONSTYLE|WB_DRAG)
264 ,m_pBrowseBox(pParent)
265 {
266 }
267
268 void OSelectionBrwBoxHeader::Select()
269 {
270 EditBrowserHeader::Select();
271 m_pBrowseBox->GrabFocus();
272
273 BrowserMode nMode = m_pBrowseBox->GetMode();
274 if ( 0 == m_pBrowseBox->GetSelectColumnCount() )
275 {
276 m_pBrowseBox->DeactivateCell();
277 // we are in the right mode if a row has been selected row
278 if ( nMode & BrowserMode::HIDESELECT )
279 {
280 nMode &= ~BrowserMode::HIDESELECT;
281 nMode |= BrowserMode::MULTISELECTION;
282 m_pBrowseBox->SetMode( nMode );
283 }
284 }
285 m_pBrowseBox->SelectColumnId( GetCurItemId() );
286 m_pBrowseBox->DeactivateCell();
287 }
288}
289
291{
293}
294
295void OSelectionBrowseBox::ColumnMoved( sal_uInt16 nColId, bool _bCreateUndo )
296{
298 // swap the two columns
299 sal_uInt16 nNewPos = GetColumnPos( nColId );
300 OTableFields& rFields = getFields();
301 if ( rFields.size() > o3tl::make_unsigned(nNewPos-1) )
302 {
303 sal_uInt16 nOldPos = 0;
304 bool bFoundElem = false;
305 for (auto const& field : rFields)
306 {
307 if (field->GetColumnId() == nColId)
308 {
309 bFoundElem = true;
310 break;
311 }
312 ++nOldPos;
313 }
314
315 OSL_ENSURE( (nNewPos-1) != nOldPos && nOldPos < rFields.size(),"Old and new position are equal!");
316 if (bFoundElem)
317 {
318 OTableFieldDescRef pOldEntry = rFields[nOldPos];
319 rFields.erase(rFields.begin() + nOldPos);
320 rFields.insert(rFields.begin() + nNewPos - 1,pOldEntry);
321
322 // create the undo action
323 if ( !m_bInUndoMode && _bCreateUndo )
324 {
325 std::unique_ptr<OTabFieldMovedUndoAct> pUndoAct(new OTabFieldMovedUndoAct(this));
326 pUndoAct->SetColumnPosition( nOldPos + 1);
327 pUndoAct->SetTabFieldDescr(pOldEntry);
328
330 }
331 }
332 }
333 else
334 OSL_FAIL("Invalid column id!");
335}
336
338{
339
341
342 // set the header bar
343 VclPtr<BrowserHeader> pNewHeaderBar = CreateHeaderBar(this);
344 pNewHeaderBar->SetMouseTransparent(false);
345
346 SetHeaderBar(pNewHeaderBar);
348
349 vcl::Font aFont( GetDataWindow().GetFont() );
350 aFont.SetWeight( WEIGHT_NORMAL );
351 GetDataWindow().SetFont( aFont );
352
353 Size aHeight;
355
356 for (const Control* pControl : pControls)
357 {
358 const Size aTemp(pControl->GetOptimalSize());
359 if ( aTemp.Height() > aHeight.Height() )
360 aHeight.setHeight( aTemp.Height() );
361 }
362 SetDataRowHeight(aHeight.Height());
363 SetTitleLines(1);
364 // get number of visible rows
365 for(tools::Long i=0;i<BROW_ROW_CNT;i++)
366 {
367 if(m_bVisibleRow[i])
369 }
370 RowInserted(0, m_nVisibleCount, false);
371 try
372 {
374 if(xConnection.is())
375 {
376 Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData();
377 m_nMaxColumns = xMetaData.is() ? xMetaData->getMaxColumnsInSelect() : 0;
378
379 }
380 else
381 m_nMaxColumns = 0;
382 }
383 catch(const SQLException&)
384 {
385 TOOLS_WARN_EXCEPTION( "dbaccess", "Caught Exception when asking for database metadata options!");
386 m_nMaxColumns = 0;
387 }
388}
389
391{
392 SetUpdateMode(false);
393
394 if (GetCurRow() != 0)
395 GoToRow(0);
396
397 static_cast< OQueryController& >( getDesignView()->getController() ).clearFields();
398
400
403 SetUpdateMode(true);
404}
405
407{
408 SetUpdateMode(false);
409
410 OTableFields::const_reverse_iterator aIter = getFields().rbegin();
411 for ( ;aIter != getFields().rend(); ++aIter )
412 {
413 if ( !(*aIter)->IsEmpty() )
414 {
415 RemoveField( (*aIter)->GetColumnId() );
416 aIter = getFields().rbegin();
417 }
418 }
420 SetUpdateMode(true);
421}
422
424{
425 if (bRO)
426 {
428 m_nMode &= ~BrowserMode::HIDECURSOR;
430 }
431 else
432 {
433 m_nMode |= BrowserMode::HIDECURSOR;
435 ActivateCell();
436 }
437}
438
439CellController* OSelectionBrowseBox::GetController(sal_Int32 nRow, sal_uInt16 nColId)
440{
441 if ( nColId > getFields().size() )
442 return nullptr;
443 OTableFieldDescRef pEntry = getFields()[nColId-1];
444 OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::GetController : invalid FieldDescription !");
445
446 if (!pEntry.is())
447 return nullptr;
448
449 if (static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
450 return nullptr;
451
452 sal_Int32 nCellIndex = GetRealRow(nRow);
453 switch (nCellIndex)
454 {
455 case BROW_FIELD_ROW:
457 case BROW_TABLE_ROW:
459 case BROW_VIS_ROW:
461 case BROW_ORDER_ROW:
465 default:
467 }
468}
469
470void OSelectionBrowseBox::InitController(CellControllerRef& /*rController*/, sal_Int32 nRow, sal_uInt16 nColId)
471{
472 OSL_ENSURE(nColId != BROWSER_INVALIDID,"An Invalid Id was set!");
473 if ( nColId == BROWSER_INVALIDID )
474 return;
475 sal_uInt16 nPos = GetColumnPos(nColId);
476 if ( nPos == 0 || nPos == BROWSER_INVALIDID || nPos > getFields().size() )
477 return;
478 OTableFieldDescRef pEntry = getFields()[nPos-1];
479 OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::InitController : invalid FieldDescription !");
480 sal_Int32 nCellIndex = GetRealRow(nRow);
481
482 switch (nCellIndex)
483 {
484 case BROW_FIELD_ROW:
485 {
486 weld::ComboBox& rComboBox = m_pFieldCell->get_widget();
487 rComboBox.clear();
488 rComboBox.set_entry_text(OUString());
489
490 OUString aField(pEntry->GetField());
491 OUString aTable(pEntry->GetAlias());
492
493 getDesignView()->fillValidFields(aTable, rComboBox);
494
495 // replace with alias.*
496 if (o3tl::trim(aField) == u"*")
497 {
498 aField = aTable + ".*";
499 }
500 rComboBox.set_entry_text(aField);
501 } break;
502 case BROW_TABLE_ROW:
503 {
504 weld::ComboBox& rComboBox = m_pTableCell->get_widget();
505 rComboBox.clear();
507 if ( !pEntry->isCondition() )
508 {
509 for (auto const& tabWin : getDesignView()->getTableView()->GetTabWinMap())
510 rComboBox.append_text(static_cast<OQueryTableWindow*>(tabWin.second.get())->GetAliasName());
511
512 rComboBox.insert_text(0, DBA_RES(STR_QUERY_NOTABLE));
513 if (!pEntry->GetAlias().isEmpty())
514 rComboBox.set_active_text(pEntry->GetAlias());
515 else
516 rComboBox.set_active_text(DBA_RES(STR_QUERY_NOTABLE));
517 }
518 } break;
519 case BROW_VIS_ROW:
520 {
521 m_pVisibleCell->GetBox().set_active(pEntry->IsVisible());
522 m_pVisibleCell->GetBox().save_state();
523
525
526 if(!pEntry->IsVisible() && pEntry->GetOrderDir() != ORDER_NONE && !m_bOrderByUnRelated)
527 {
528 // a column has to visible in order to show up in ORDER BY
529 pEntry->SetVisible();
530 m_pVisibleCell->GetBox().set_active(pEntry->IsVisible());
531 m_pVisibleCell->GetBox().save_state();
532 m_pVisibleCell->GetBox().set_sensitive(false);
533 OUString aMessage(DBA_RES(STR_QRY_ORDERBY_UNRELATED));
534 OQueryDesignView* paDView = getDesignView();
535 std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(paDView ? paDView->GetFrameWeld() : nullptr,
536 VclMessageType::Info, VclButtonsType::Ok,
537 aMessage));
538 xInfoBox->run();
539 }
540 } break;
541 case BROW_ORDER_ROW:
542 {
543 weld::ComboBox& rComboBox = m_pOrderCell->get_widget();
544 rComboBox.set_active(
545 sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()));
547 break;
548 }
550 setTextCellContext(pEntry,pEntry->GetFieldAlias(),HID_QRYDGN_ROW_ALIAS);
551 break;
553 setFunctionCell(pEntry);
554 break;
555 default:
556 {
557 sal_uInt16 nIdx = sal_uInt16(nCellIndex - BROW_CRIT1_ROW);
558 setTextCellContext(pEntry,pEntry->GetCriteria( nIdx ),HID_QRYDGN_ROW_CRIT);
559 }
560 }
561 Controller()->SaveValue();
562}
563
564void OSelectionBrowseBox::notifyTableFieldChanged(const OUString& _sOldAlias, std::u16string_view _sAlias, bool& _bListAction, sal_uInt16 _nColumnId)
565{
566 appendUndoAction(_sOldAlias,_sAlias,BROW_TABLE_ROW,_bListAction);
569}
570
571void OSelectionBrowseBox::notifyFunctionFieldChanged(const OUString& _sOldFunctionName, std::u16string_view _sFunctionName, bool& _bListAction, sal_uInt16 _nColumnId)
572{
573 appendUndoAction(_sOldFunctionName,_sFunctionName,BROW_FUNCTION_ROW,_bListAction);
577}
578
579void OSelectionBrowseBox::clearEntryFunctionField(std::u16string_view _sFieldName,OTableFieldDescRef const & _pEntry, bool& _bListAction,sal_uInt16 _nColumnId)
580{
581 if ( !(isFieldNameAsterisk( _sFieldName ) && (!_pEntry->isNoneFunction() || _pEntry->IsGroupBy())) )
582 return;
583
584 OUString sFunctionName;
585 GetFunctionName(SQL_TOKEN_COUNT,sFunctionName);
586 OUString sOldLocalizedFunctionName = _pEntry->GetFunction();
587 if ( sOldLocalizedFunctionName != sFunctionName || _pEntry->IsGroupBy() )
588 {
589 // append undo action for the function field
590 _pEntry->SetFunctionType(FKT_NONE);
591 _pEntry->SetFunction(OUString());
592 _pEntry->SetGroupBy(false);
593 notifyFunctionFieldChanged(sOldLocalizedFunctionName,_pEntry->GetFunction(),_bListAction,_nColumnId);
594 }
595}
596
597bool OSelectionBrowseBox::fillColumnRef(const OSQLParseNode* _pColumnRef, const Reference< XConnection >& _rxConnection, OTableFieldDescRef const & _pEntry, bool& _bListAction )
598{
599 OSL_ENSURE(_pColumnRef,"No valid parsenode!");
600 OUString sColumnName,sTableRange;
601 OSQLParseTreeIterator::getColumnRange(_pColumnRef,_rxConnection,sColumnName,sTableRange);
602 return fillColumnRef(sColumnName,sTableRange,_rxConnection->getMetaData(),_pEntry,_bListAction);
603}
604
605bool OSelectionBrowseBox::fillColumnRef(const OUString& _sColumnName, std::u16string_view _sTableRange, const Reference<XDatabaseMetaData>& _xMetaData, OTableFieldDescRef const & _pEntry, bool& _bListAction)
606{
607 bool bError = false;
608 ::comphelper::UStringMixEqual bCase(_xMetaData->supportsMixedCaseQuotedIdentifiers());
609 // check if the table name is the same
610 if ( !_sTableRange.empty() && (bCase(_pEntry->GetTable(),_sTableRange) || bCase(_pEntry->GetAlias(),_sTableRange)) )
611 { // a table was already inserted and the tables contains that column name
612
613 if ( !_pEntry->GetTabWindow() )
614 { // fill tab window
615 OUString sOldAlias = _pEntry->GetAlias();
616 if ( !fillEntryTable(_pEntry,_pEntry->GetTable()) )
617 fillEntryTable(_pEntry,_pEntry->GetAlias()); // only when the first failed
618 if ( !bCase(sOldAlias,_pEntry->GetAlias()) )
619 notifyTableFieldChanged(sOldAlias,_pEntry->GetAlias(),_bListAction,GetCurColumnId());
620 }
621 }
622 // check if the table window
623 OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(_pEntry->GetTabWindow());
624 if ( !pEntryTab ) // no table found with this name so we have to travel through all tables
625 {
626 sal_uInt16 nTabCount = 0;
627 if ( !static_cast<OQueryTableView*>(getDesignView()->getTableView())->FindTableFromField(_sColumnName,_pEntry,nTabCount) ) // error occurred: column not in table window
628 {
629 OUString sErrorMsg(DBA_RES(RID_STR_FIELD_DOESNT_EXIST));
630 sErrorMsg = sErrorMsg.replaceFirst("$name$",_sColumnName);
631 OSQLErrorBox aWarning(GetFrameWeld(), sErrorMsg);
632 aWarning.run();
633 bError = true;
634 }
635 else
636 {
637 pEntryTab = static_cast<OQueryTableWindow*>(_pEntry->GetTabWindow());
638 notifyTableFieldChanged(OUString(),_pEntry->GetAlias(),_bListAction,GetCurColumnId());
639 }
640 }
641 if ( pEntryTab ) // here we got a valid table
642 _pEntry->SetField(_sColumnName);
643
644 return bError;
645}
646
647bool OSelectionBrowseBox::saveField(OUString& _sFieldName ,OTableFieldDescRef const & _pEntry, bool& _bListAction)
648{
649 bool bError = false;
650
651 OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
652
653 // first look if the name can be found in our tables
654 sal_uInt16 nTabCount = 0;
655 OUString sOldAlias = _pEntry->GetAlias();
656 if ( static_cast<OQueryTableView*>(getDesignView()->getTableView())->FindTableFromField(_sFieldName,_pEntry,nTabCount) )
657 {
658 // append undo action for the alias name
659 _pEntry->SetField(_sFieldName);
660 notifyTableFieldChanged(sOldAlias,_pEntry->GetAlias(),_bListAction,GetCurColumnId());
661 clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
662 return bError;
663 }
664
665 Reference<XConnection> xConnection( rController.getConnection() );
667 if ( xConnection.is() )
668 xMetaData = xConnection->getMetaData();
669 OSL_ENSURE( xMetaData.is(), "OSelectionBrowseBox::saveField: invalid connection/meta data!" );
670 if ( !xMetaData.is() )
671 return true;
672
673 OUString sErrorMsg;
674 // second test if the name can be set as select columns in a pseudo statement
675 // we have to look which entries we should quote
676
677 const OUString sFieldAlias = _pEntry->GetFieldAlias();
678 ::connectivity::OSQLParser& rParser( rController.getParser() );
679 {
680 // automatically add parentheses around subqueries
681 OUString devnull;
682 std::unique_ptr<OSQLParseNode> pParseNode = rParser.parseTree( devnull, _sFieldName, true );
683 if (pParseNode == nullptr)
684 pParseNode = rParser.parseTree( devnull, _sFieldName );
685 if (pParseNode != nullptr && SQL_ISRULE(pParseNode, select_statement))
686 _sFieldName = "(" + _sFieldName + ")";
687 }
688
689 std::unique_ptr<OSQLParseNode> pParseNode;
690 {
691 // 4 passes in trying to interpret the field name
692 // - don't quote the field name, parse internationally
693 // - don't quote the field name, parse en-US
694 // - quote the field name, parse internationally
695 // - quote the field name, parse en-US
696 size_t nPass = 4;
697 OUString sQuotedFullFieldName(::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), _sFieldName ));
698 OUString sFullFieldName(_sFieldName);
699
700 if ( _pEntry->isAggregateFunction() )
701 {
702 OSL_ENSURE(!_pEntry->GetFunction().isEmpty(),"No empty Function name allowed here! ;-(");
703 sQuotedFullFieldName = _pEntry->GetFunction() + "(" + sQuotedFullFieldName + ")";
704 sFullFieldName = _pEntry->GetFunction() + "(" + sFullFieldName + ")";
705 }
706
707 do
708 {
709 bool bQuote = ( nPass <= 2 );
710 bool bInternational = ( nPass % 2 ) == 0;
711
712 OUString sSql {"SELECT "};
713 if ( bQuote )
714 sSql += sQuotedFullFieldName;
715 else
716 sSql += sFullFieldName;
717
718 if ( !sFieldAlias.isEmpty() )
719 { // always quote the alias name: there cannot be a function in it
720 sSql += " " + ::dbtools::quoteName( xMetaData->getIdentifierQuoteString(), sFieldAlias );
721 }
722 sSql += " FROM x";
723
724 pParseNode = rParser.parseTree( sErrorMsg, sSql, bInternational );
725 }
726 while ( ( pParseNode == nullptr ) && ( --nPass > 0 ) );
727 }
728
729 if ( pParseNode == nullptr )
730 {
731 // something different which we have to check
732 OUString sErrorMessage( DBA_RES( STR_QRY_COLUMN_NOT_FOUND ) );
733 sErrorMessage = sErrorMessage.replaceFirst("$name$",_sFieldName);
734 OSQLErrorBox aWarning(GetFrameWeld(), sErrorMessage);
735 aWarning.run();
736
737 return true;
738 }
739
740 // we got a valid select column
741 // find what type of column has be inserted
742 ::connectivity::OSQLParseNode* pSelection = pParseNode->getChild(2);
743 if ( SQL_ISRULE(pSelection,selection) ) // we found the asterisk
744 {
745 _pEntry->SetField(_sFieldName);
746 clearEntryFunctionField(_sFieldName,_pEntry,_bListAction,_pEntry->GetColumnId());
747 }
748 else // travel through the select column parse node
749 {
750 OTableFieldDescRef aSelEntry = _pEntry;
751 sal_uInt16 nColumnId = aSelEntry->GetColumnId();
752
753 sal_uInt32 nCount = pSelection->count();
754 for (sal_uInt32 i = 0; i < nCount; ++i)
755 {
756 if ( i > 0 ) // may we have to append more than one field
757 {
758 sal_uInt16 nColumnPosition;
759 aSelEntry = FindFirstFreeCol(nColumnPosition);
760 if ( !aSelEntry.is() )
761 {
762 AppendNewCol();
763 aSelEntry = FindFirstFreeCol(nColumnPosition);
764 }
765 ++nColumnPosition;
766 nColumnId = GetColumnId(nColumnPosition);
767 }
768
769 ::connectivity::OSQLParseNode* pChild = pSelection->getChild( i );
770 OSL_ENSURE(SQL_ISRULE(pChild,derived_column), "No derived column found!");
771 // get the column alias
772 OUString sColumnAlias = OSQLParseTreeIterator::getColumnAlias(pChild);
773 if ( !sColumnAlias.isEmpty() ) // we found an as clause
774 {
775 OUString aSelectionAlias = aSelEntry->GetFieldAlias();
776 aSelEntry->SetFieldAlias( sColumnAlias );
777 // append undo
778 appendUndoAction(aSelectionAlias,aSelEntry->GetFieldAlias(),BROW_COLUMNALIAS_ROW,_bListAction);
781 }
782
783 ::connectivity::OSQLParseNode* pColumnRef = pChild->getChild(0);
784 if (
785 pColumnRef->getKnownRuleID() != OSQLParseNode::subquery &&
786 pColumnRef->count() == 3 &&
787 SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") &&
788 SQL_ISPUNCTUATION(pColumnRef->getChild(2),")")
789 )
790 pColumnRef = pColumnRef->getChild(1);
791
792 if ( SQL_ISRULE(pColumnRef,column_ref) ) // we found a valid column name or more column names
793 {
794 // look if we can find the corresponding table
795 bError = fillColumnRef( pColumnRef, xConnection, aSelEntry, _bListAction );
796
797 // we found a simple column so we must clear the function fields but only when the column name is '*'
798 // and the function is different to count
799 clearEntryFunctionField(_sFieldName,aSelEntry,_bListAction,nColumnId);
800 }
801 // do we have an aggregate function and only a function?
802 else if ( SQL_ISRULE(pColumnRef,general_set_fct) )
803 {
804 OUString sLocalizedFunctionName;
805 if ( GetFunctionName(pColumnRef->getChild(0)->getTokenID(),sLocalizedFunctionName) )
806 {
807 OUString sOldLocalizedFunctionName = aSelEntry->GetFunction();
808 aSelEntry->SetFunction(sLocalizedFunctionName);
809 sal_uInt32 nFunCount = pColumnRef->count() - 1;
810 sal_Int32 nFunctionType = FKT_AGGREGATE;
811 bool bQuote = false;
812 // may be there exists only one parameter which is a column, fill all information into our fields
813 if ( nFunCount == 4 && SQL_ISRULE(pColumnRef->getChild(3),column_ref) )
814 bError = fillColumnRef( pColumnRef->getChild(3), xConnection, aSelEntry, _bListAction );
815 else if ( nFunCount == 3 ) // we have a COUNT(*) here, so take the first table
816 bError = fillColumnRef( "*", std::u16string_view(), xMetaData, aSelEntry, _bListAction );
817 else
818 {
819 nFunctionType |= FKT_NUMERIC;
820 bQuote = true;
821 aSelEntry->SetDataType(DataType::DOUBLE);
822 aSelEntry->SetFieldType(TAB_NORMAL_FIELD);
823 }
824
825 // now parse the parameters
826 OUString sParameters;
827 for(sal_uInt32 function = 2; function < nFunCount; ++function) // we only want to parse the parameters of the function
828 pColumnRef->getChild(function)->parseNodeToStr( sParameters, xConnection, &rParser.getContext(), true, bQuote );
829
830 aSelEntry->SetFunctionType(nFunctionType);
831 aSelEntry->SetField(sParameters);
832 if ( aSelEntry->IsGroupBy() )
833 {
834 sOldLocalizedFunctionName = m_aFunctionStrings.copy(m_aFunctionStrings.lastIndexOf(';')+1);
835 aSelEntry->SetGroupBy(false);
836 }
837
838 // append undo action
839 notifyFunctionFieldChanged(sOldLocalizedFunctionName,sLocalizedFunctionName,_bListAction, nColumnId);
840 }
841 else
842 OSL_FAIL("Unsupported function inserted!");
843
844 }
845 else
846 {
847 // so we first clear the function field
848 clearEntryFunctionField(_sFieldName,aSelEntry,_bListAction,nColumnId);
849 OUString sFunction;
850 pColumnRef->parseNodeToStr( sFunction,
851 xConnection,
852 &rController.getParser().getContext(),
853 true); // quote is to true because we need quoted elements inside the function
854
855 getDesignView()->fillFunctionInfo(pColumnRef,sFunction,aSelEntry);
856
857 if( SQL_ISRULEOR3(pColumnRef, position_exp, extract_exp, fold) ||
858 SQL_ISRULEOR3(pColumnRef, char_substring_fct, length_exp, char_value_fct) )
859 // a calculation has been found ( can be calc and function )
860 {
861 // now parse the whole statement
862 sal_uInt32 nFunCount = pColumnRef->count();
863 OUString sParameters;
864 for(sal_uInt32 function = 0; function < nFunCount; ++function)
865 pColumnRef->getChild(function)->parseNodeToStr( sParameters, xConnection, &rParser.getContext(), true );
866
867 sOldAlias = aSelEntry->GetAlias();
868 sal_Int32 nNewFunctionType = aSelEntry->GetFunctionType() | FKT_NUMERIC | FKT_OTHER;
869 aSelEntry->SetFunctionType(nNewFunctionType);
870 aSelEntry->SetField(sParameters);
871 }
872 else
873 {
874 aSelEntry->SetFieldAlias(sColumnAlias);
875 if ( SQL_ISRULE(pColumnRef,set_fct_spec) )
876 aSelEntry->SetFunctionType(/*FKT_NUMERIC | */FKT_OTHER);
877 else
878 aSelEntry->SetFunctionType(FKT_NUMERIC | FKT_OTHER);
879 }
880
881 aSelEntry->SetAlias(OUString());
882 notifyTableFieldChanged(sOldAlias,aSelEntry->GetAlias(),_bListAction, nColumnId);
883 }
884
885 if ( i > 0 && !InsertField(aSelEntry,BROWSER_INVALIDID,true,false).is() ) // may we have to append more than one field
886 { // the field could not be inserted
887 OUString sErrorMessage( DBA_RES( RID_STR_FIELD_DOESNT_EXIST ) );
888 sErrorMessage = sErrorMessage.replaceFirst("$name$",aSelEntry->GetField());
889 OSQLErrorBox aWarning(GetFrameWeld(), sErrorMessage);
890 aWarning.run();
891 bError = true;
892 }
893 }
894 }
895
896 return bError;
897}
898
900{
901 OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
902 OTableFieldDescRef pEntry;
903 sal_uInt16 nCurrentColumnPos = GetColumnPos(GetCurColumnId());
904 if(getFields().size() > o3tl::make_unsigned(nCurrentColumnPos - 1))
905 pEntry = getEntry(nCurrentColumnPos - 1);
906
907 bool bWasEmpty = pEntry.is() && pEntry->IsEmpty();
908 bool bError = false;
909 bool bListAction = false;
910
911 if (pEntry.is() && Controller().is() && Controller()->IsValueChangedFromSaved())
912 {
913 // for the Undo-action
914 OUString strOldCellContents,sNewValue;
915 sal_Int32 nRow = GetRealRow(GetCurRow());
916 bool bAppendRow = false;
917 switch (nRow)
918 {
919 case BROW_VIS_ROW:
920 {
921 bool bOldValue = m_pVisibleCell->GetBox().get_saved_state() != TRISTATE_FALSE;
922 strOldCellContents
923 = bOldValue ? std::u16string_view(u"1") : std::u16string_view(u"0");
924 sNewValue
925 = !bOldValue ? std::u16string_view(u"1") : std::u16string_view(u"0");
926 }
927 if((m_bOrderByUnRelated || pEntry->GetOrderDir() == ORDER_NONE) &&
928 (m_bGroupByUnRelated || !pEntry->IsGroupBy()))
929 {
930 pEntry->SetVisible(m_pVisibleCell->GetBox().get_active());
931 }
932 else
933 {
934 pEntry->SetVisible();
935 m_pVisibleCell->GetBox().set_active(true);
936 }
937 break;
938
939 case BROW_FIELD_ROW:
940 {
941 weld::ComboBox& rComboBox = m_pFieldCell->get_widget();
942 OUString aFieldName(rComboBox.get_active_text());
943 try
944 {
945 if (aFieldName.isEmpty())
946 {
947 OTableFieldDescRef pNewEntry = new OTableFieldDesc();
948 pNewEntry->SetColumnId( pEntry->GetColumnId() );
949 std::replace(getFields().begin(),getFields().end(),pEntry,pNewEntry);
950 sal_uInt16 nCol = GetCurColumnId();
951 for (int i = 0; i < m_nVisibleCount; i++) // redraw column
952 RowModified(i,nCol);
953 }
954 else
955 {
956 strOldCellContents = pEntry->GetField();
957 bListAction = true;
958 if ( !m_bInUndoMode )
959 rController.GetUndoManager().EnterListAction(OUString(),OUString(),0,ViewShellId(-1));
960
961 sal_Int32 nPos = rComboBox.find_text(aFieldName);
962 OUString aAliasName = pEntry->GetAlias();
963 if ( nPos != -1 && aAliasName.isEmpty() && aFieldName.indexOf('.') >= 0 )
964 { // special case, we have a table field so we must cut the table name
965 OUString sTableAlias = aFieldName.getToken(0,'.');
966 pEntry->SetAlias(sTableAlias);
967 OUString sColumnName = aFieldName.copy(sTableAlias.getLength()+1);
968 const Reference<XConnection>& xConnection = rController.getConnection();
969 if ( !xConnection.is() )
970 return false;
971 bError = fillColumnRef( sColumnName, sTableAlias, xConnection->getMetaData(), pEntry, bListAction );
972 }
973 else
974 bError = true;
975
976 if ( bError )
977 bError = saveField(aFieldName,pEntry,bListAction);
978 }
979 }
980 catch(Exception&)
981 {
982 bError = true;
983 }
984 if ( bError )
985 {
986 sNewValue = aFieldName;
987 if ( !m_bInUndoMode )
988 static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
989 bListAction = false;
990 }
991 else
992 sNewValue = pEntry->GetField();
993 rController.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
994 }
995 break;
996
997 case BROW_TABLE_ROW:
998 {
999 weld::ComboBox& rComboBox = m_pTableCell->get_widget();
1000 OUString aAliasName = rComboBox.get_active_text();
1001 strOldCellContents = pEntry->GetAlias();
1002 if (rComboBox.get_active() != 0)
1003 {
1004 pEntry->SetAlias(aAliasName);
1005 // we have to set the table name as well as the table window
1007 OJoinTableView::OTableWindowMap::const_iterator aIter = rTabWinList.find(aAliasName);
1008 if(aIter != rTabWinList.end())
1009 {
1010 OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(aIter->second.get());
1011 if (pEntryTab)
1012 {
1013 pEntry->SetTable(pEntryTab->GetTableName());
1014 pEntry->SetTabWindow(pEntryTab);
1015 }
1016 }
1017 }
1018 else
1019 {
1020 pEntry->SetAlias(OUString());
1021 pEntry->SetTable(OUString());
1022 pEntry->SetTabWindow(nullptr);
1023 }
1024 sNewValue = pEntry->GetAlias();
1025
1026 } break;
1027
1028 case BROW_ORDER_ROW:
1029 {
1030 strOldCellContents = OUString::number(static_cast<sal_uInt16>(pEntry->GetOrderDir()));
1031 weld::ComboBox& rComboBox = m_pOrderCell->get_widget();
1032 sal_Int32 nIdx = rComboBox.get_active();
1033 if (nIdx == -1)
1034 nIdx = 0;
1035 pEntry->SetOrderDir(EOrderDir(nIdx));
1037 {
1038 pEntry->SetVisible();
1039 m_pVisibleCell->GetBox().set_active(true);
1041 }
1042 sNewValue = OUString::number(static_cast<sal_uInt16>(pEntry->GetOrderDir()));
1043 } break;
1044
1046 strOldCellContents = pEntry->GetFieldAlias();
1047 pEntry->SetFieldAlias(m_pTextCell->get_widget().get_text());
1048 sNewValue = pEntry->GetFieldAlias();
1049 break;
1050 case BROW_FUNCTION_ROW:
1051 {
1052 strOldCellContents = pEntry->GetFunction();
1053 weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
1054 sal_Int32 nPos = rComboBox.get_active();
1055 // these functions are only available in CORE
1056 OUString sFunctionName = rComboBox.get_text(nPos);
1057 std::u16string_view sGroupFunctionName = m_aFunctionStrings.subView(m_aFunctionStrings.lastIndexOf(';')+1);
1058 bool bGroupBy = false;
1059 if ( sGroupFunctionName == sFunctionName ) // check if the function name is GROUP
1060 {
1061 bGroupBy = true;
1062
1063 if ( !m_bGroupByUnRelated && !pEntry->IsVisible() )
1064 {
1065 // we have to change the visible flag, so we must append also an undo action
1066 pEntry->SetVisible();
1067 m_pVisibleCell->GetBox().set_active(true);
1068 appendUndoAction("0",u"1",BROW_VIS_ROW,bListAction);
1070 }
1071
1072 pEntry->SetFunction(OUString());
1073 pEntry->SetFunctionType(pEntry->GetFunctionType() & ~FKT_AGGREGATE );
1074 }
1075 else if ( nPos ) // we found an aggregate function
1076 {
1077 pEntry->SetFunctionType(pEntry->GetFunctionType() | FKT_AGGREGATE );
1078 pEntry->SetFunction(sFunctionName);
1079 }
1080 else
1081 {
1082 sFunctionName.clear();
1083 pEntry->SetFunction(OUString());
1084 pEntry->SetFunctionType(pEntry->GetFunctionType() & ~FKT_AGGREGATE );
1085 }
1086
1087 pEntry->SetGroupBy(bGroupBy);
1088
1089 sNewValue = sFunctionName;
1090 }
1091 break;
1092 default:
1093 {
1095 if(!xConnection.is())
1096 break;
1097
1098 sal_uInt16 nIdx = sal_uInt16(nRow - BROW_CRIT1_ROW);
1099 OUString aText = comphelper::string::stripStart(m_pTextCell->get_widget().get_text(), ' ');
1100
1101 OUString aCrit;
1102 if(!aText.isEmpty())
1103 {
1104 OUString aErrorMsg;
1106 std::unique_ptr<OSQLParseNode> pParseNode = getDesignView()->getPredicateTreeFromEntry(pEntry,aText,aErrorMsg,xColumn);
1107
1108 if (pParseNode)
1109 {
1110 pParseNode->parseNodeToPredicateStr(aCrit,
1111 xConnection,
1112 static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
1113 xColumn,
1114 pEntry->GetAlias(),
1116 getDesignView()->getDecimalSeparator(),
1117 &(static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext()));
1118 }
1119 else
1120 {
1121 if(xColumn.is())
1122 {
1123 sal_Int32 nType = 0;
1124 xColumn->getPropertyValue(PROPERTY_TYPE) >>= nType;
1125 switch(nType)
1126 {
1127 case DataType::CHAR:
1128 case DataType::VARCHAR:
1129 case DataType::LONGVARCHAR:
1130 case DataType::CLOB:
1131 if(!aText.startsWith("'") || !aText.endsWith("'"))
1132 {
1133 aText = aText.replaceAll("'", "''");
1134 aText = "'" + aText + "'";
1135 }
1136 break;
1137 default:
1138 ;
1139 }
1140 ::connectivity::OSQLParser& rParser = static_cast<OQueryController&>(getDesignView()->getController()).getParser();
1141 pParseNode = rParser.predicateTree(aErrorMsg,
1142 aText,
1143 static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
1144 xColumn);
1145 if (pParseNode)
1146 {
1147 pParseNode->parseNodeToPredicateStr(aCrit,
1148 xConnection,
1149 static_cast<OQueryController&>(getDesignView()->getController()).getNumberFormatter(),
1150 xColumn,
1151 pEntry->GetAlias(),
1154 &(static_cast<OQueryController&>(getDesignView()->getController()).getParser().getContext()));
1155 }
1156 else
1157 {
1158 if ( !m_bDisableErrorBox )
1159 {
1160 OSQLWarningBox aWarning(GetFrameWeld(), aErrorMsg);
1161 aWarning.run();
1162 }
1163 bError = true;
1164 }
1165 }
1166 else
1167 {
1168 if ( !m_bDisableErrorBox )
1169 {
1170 OSQLWarningBox aWarning(GetFrameWeld(), aErrorMsg);
1171 aWarning.run();
1172 }
1173 bError = true;
1174 }
1175 }
1176 }
1177 strOldCellContents = pEntry->GetCriteria(nIdx);
1178 pEntry->SetCriteria(nIdx, aCrit);
1179 sNewValue = pEntry->GetCriteria(nIdx);
1180 if(!aCrit.isEmpty() && nRow >= (GetRowCount()-1))
1181 bAppendRow = true;
1182 }
1183 }
1184 if( !bError && Controller().is() )
1185 Controller()->SaveValue();
1186
1188
1189 if ( bAppendRow )
1190 {
1191 RowInserted( GetRowCount()-1 );
1192 m_bVisibleRow.push_back(true);
1194 }
1195
1196 if(!bError)
1197 {
1198 // and now the undo-action for the total
1199 appendUndoAction(strOldCellContents,sNewValue,nRow);
1200
1201 }
1202 }
1203
1204 // did I store data in a FieldDescription which was empty before and which is not empty anymore after the changes?
1205 if ( pEntry.is() && bWasEmpty && !pEntry->IsEmpty() && !bError )
1206 {
1207 // Default to visible
1208 pEntry->SetVisible();
1209 appendUndoAction("0",u"1",BROW_VIS_ROW,bListAction);
1211
1212 // if required add empty columns
1213 sal_uInt16 nDummy;
1214 CheckFreeColumns(nDummy);
1215 }
1216
1217 if ( bListAction && !m_bInUndoMode )
1218 static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().LeaveListAction();
1219
1220 return pEntry != nullptr && !bError;
1221}
1222
1224{
1225 m_nSeekRow = nRow;
1226 return nRow < m_nVisibleCount;
1227}
1228
1229void OSelectionBrowseBox::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect, sal_uInt16 nColumnId) const
1230{
1231 rDev.SetClipRegion(vcl::Region(rRect));
1232
1233 OTableFieldDescRef pEntry;
1234 sal_uInt16 nPos = GetColumnPos(nColumnId);
1235 if(getFields().size() > o3tl::make_unsigned(nPos - 1))
1236 pEntry = getFields()[nPos - 1];
1237
1238 if (!pEntry.is())
1239 return;
1240
1241 sal_Int32 nRow = GetRealRow(m_nSeekRow);
1242 if (nRow == BROW_VIS_ROW)
1243 PaintTristate(rRect, pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE);
1244 else
1245 rDev.DrawText(rRect, GetCellText(nRow, nColumnId),DrawTextFlags::VCenter);
1246
1247 rDev.SetClipRegion( );
1248}
1249
1251{
1252 tools::Rectangle aRect(rRect);
1253 aRect.TopLeft().AdjustY( -2 );
1254 OUString aLabel(DBA_RES(STR_QUERY_HANDLETEXT));
1255
1256 // from BROW_CRIT2_ROW onwards all rows are shown "or"
1259 rDev.DrawText(aRect, aLabel.getToken(nToken, ';'),DrawTextFlags::VCenter);
1260}
1261
1262void OSelectionBrowseBox::RemoveColumn(sal_uInt16 _nColumnId)
1263{
1264 OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
1265
1266 sal_uInt16 nPos = GetColumnPos(_nColumnId);
1267 // the control should always have exactly one more column: the HandleColumn
1268 OSL_ENSURE((nPos == 0) || (nPos <= getFields().size()), "OSelectionBrowseBox::RemoveColumn : invalid parameter nColId");
1269 // ColId is synonymous to Position, and the condition should be valid
1270
1271 sal_uInt16 nCurCol = GetCurColumnId();
1272 sal_Int32 nCurrentRow = GetCurRow();
1273
1275
1276 getFields().erase( getFields().begin() + (nPos - 1) );
1277 OTableFieldDescRef pEntry = new OTableFieldDesc();
1278 pEntry->SetColumnId(_nColumnId);
1279 getFields().push_back(pEntry);
1280
1281 EditBrowseBox::RemoveColumn( _nColumnId );
1282 InsertDataColumn( _nColumnId , OUString(), DEFAULT_SIZE );
1283
1284 // redraw
1285 tools::Rectangle aInvalidRect = GetInvalidRect( _nColumnId );
1286 Invalidate( aInvalidRect );
1287
1288 ActivateCell( nCurrentRow, nCurCol );
1289
1290 rController.setModified( true );
1291
1293}
1294
1295void OSelectionBrowseBox::RemoveField(sal_uInt16 nColumnId )
1296{
1297 OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
1298
1299 sal_uInt16 nPos = GetColumnPos(nColumnId);
1300 OSL_ENSURE(getFields().size() > o3tl::make_unsigned(nPos-1),"ID is to great!");
1301
1302 OTableFieldDescRef pDesc = getEntry(static_cast<sal_uInt32>(nPos - 1)) ;
1303 pDesc->SetColWidth( static_cast<sal_uInt16>(GetColumnWidth(nColumnId)) ); // was not stored this before
1304
1305 // trigger UndoAction
1306 if ( !m_bInUndoMode )
1307 {
1308 std::unique_ptr<OTabFieldDelUndoAct> pUndoAction(new OTabFieldDelUndoAct( this ));
1309 pUndoAction->SetTabFieldDescr(pDesc);
1310 pUndoAction->SetColumnPosition(nPos);
1311 rController.addUndoActionAndInvalidate( std::move(pUndoAction) );
1312 }
1313
1314 RemoveColumn(nColumnId);
1315
1317}
1318
1319void OSelectionBrowseBox::adjustSelectionMode( bool _bClickedOntoHeader, bool _bClickedOntoHandleCol )
1320{
1321 // if a Header has been selected it should be shown otherwise not
1322 if ( _bClickedOntoHeader )
1323 {
1324 if (0 == GetSelectColumnCount() )
1325 // I am in the correct mode if a selected column exists
1326 if ( BrowserMode::HIDESELECT == ( m_nMode & BrowserMode::HIDESELECT ) )
1327 {
1328 m_nMode &= ~BrowserMode::HIDESELECT;
1329 m_nMode |= BrowserMode::MULTISELECTION;
1330 SetMode( m_nMode );
1331 }
1332 }
1333 else if ( BrowserMode::HIDESELECT != ( m_nMode & BrowserMode::HIDESELECT ) )
1334 {
1335 if ( GetSelectColumnCount() != 0 )
1337
1338 if ( _bClickedOntoHandleCol )
1339 {
1340 m_nMode |= BrowserMode::HIDESELECT;
1341 m_nMode &= ~BrowserMode::MULTISELECTION;
1342 SetMode( m_nMode );
1343 }
1344 }
1345}
1346
1348{
1349 if( rEvt.IsLeft() )
1350 {
1351 bool bOnHandle = HANDLE_ID == rEvt.GetColumnId();
1352 bool bOnHeader = ( rEvt.GetRow() < 0 ) && !bOnHandle;
1353 adjustSelectionMode( bOnHeader, bOnHandle );
1354 }
1356}
1357
1359{
1361 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
1362}
1363
1365{
1367 {
1368 if (rEvt.GetKeyCode().GetCode() == KEY_DELETE && // Delete rows
1369 !rEvt.GetKeyCode().IsShift() &&
1370 !rEvt.GetKeyCode().IsMod1())
1371 {
1373 return;
1374 }
1375 }
1377}
1378
1380{
1381 sal_Int8 nDropAction = DND_ACTION_NONE;
1382 if ( rEvt.GetRow() >= -1 )
1383 {
1384 if ( IsEditing() )
1385 {
1386 // allow the asterisk again
1387 m_bDisableErrorBox = true;
1388 SaveModified();
1389 m_bDisableErrorBox = false;
1391 }
1392 // check if the format is already supported, if not deactivate the current cell and try again
1394 nDropAction = DND_ACTION_LINK;
1395 }
1396
1397 return nDropAction;
1398}
1399
1401{
1402
1403 TransferableDataHelper aDropped(_rEvt.maDropEvent.Transferable);
1405 {
1406 OSL_FAIL("OSelectionBrowseBox::ExecuteDrop: this should never have passed AcceptDrop!");
1407 return DND_ACTION_NONE;
1408 }
1409
1410 // insert the field at the selected position
1411 OJoinExchangeData jxdSource = OJoinExchObj::GetSourceDescription(_rEvt.maDropEvent.Transferable);
1412 InsertField(jxdSource);
1413
1414 return DND_ACTION_LINK;
1415}
1416
1418{
1419 // one or more can be created, but the first one will is not returned
1420 sal_uInt32 nCount = getFields().size();
1421 for (sal_uInt16 i=0 ; i<nCnt ; i++)
1422 {
1423 OTableFieldDescRef pEmptyEntry = new OTableFieldDesc();
1424 getFields().push_back(pEmptyEntry);
1425 sal_uInt16 nColumnId = sal::static_int_cast< sal_uInt16 >(getFields().size());
1426 pEmptyEntry->SetColumnId( nColumnId );
1427
1428 InsertDataColumn( nColumnId , OUString(), DEFAULT_SIZE );
1429 }
1430
1431 return getFields()[nCount];
1432}
1433
1434void OSelectionBrowseBox::DeleteFields(const OUString& rAliasName)
1435{
1436 if (getFields().empty())
1437 return;
1438
1439 sal_uInt16 nColId = GetCurColumnId();
1440 sal_uInt32 nRow = GetCurRow();
1441
1442 bool bWasEditing = IsEditing();
1443 if (bWasEditing)
1445
1446 auto aIter = std::find_if(getFields().rbegin(), getFields().rend(),
1447 [&rAliasName](const OTableFieldDescRef pEntry) { return pEntry->GetAlias() == rAliasName; });
1448 if (aIter != getFields().rend())
1449 {
1450 sal_uInt16 nPos = sal::static_int_cast<sal_uInt16>(std::distance(aIter, getFields().rend()));
1452 }
1453
1454 if (bWasEditing)
1455 ActivateCell(nRow , nColId);
1456}
1457
1458void OSelectionBrowseBox::SetColWidth(sal_uInt16 nColId, tools::Long nNewWidth)
1459{
1460 bool bWasEditing = IsEditing();
1461 if (bWasEditing)
1463
1464 // create the BaseClass
1465 SetColumnWidth(nColId, nNewWidth);
1466
1467 // tell it the FieldDescription
1468 OTableFieldDescRef pEntry = getEntry(GetColumnPos(nColId) - 1);
1469 if (pEntry.is())
1470 pEntry->SetColWidth(sal_uInt16(GetColumnWidth(nColId)));
1471
1472 if (bWasEditing)
1474}
1475
1477{
1478 // The rectangle is the full output area of the window
1479 tools::Rectangle aInvalidRect( Point(0,0), GetOutputSizePixel() );
1480
1481 // now update the left side
1482 tools::Rectangle aFieldRect(GetCellRect( 0, nColId )); // used instead of GetFieldRectPixel
1483 aInvalidRect.SetLeft( aFieldRect.Left() );
1484
1485 return aInvalidRect;
1486}
1487
1488void OSelectionBrowseBox::InsertColumn(const OTableFieldDescRef& pEntry, sal_uInt16& _nColumnPosition)
1489{
1490 // the control should have exactly one more column: the HandleColumn
1491 OSL_ENSURE(_nColumnPosition == BROWSER_INVALIDID || (_nColumnPosition <= static_cast<tools::Long>(getFields().size())), "OSelectionBrowseBox::InsertColumn : invalid parameter nColId.");
1492 // -1 means at the end. Count means at the end, others denotes a correct position
1493
1494 sal_uInt16 nCurCol = GetCurColumnId();
1495 sal_Int32 nCurrentRow = GetCurRow();
1496
1498
1499 // remember the column id of the current position
1500 sal_uInt16 nColumnId = GetColumnId(_nColumnPosition);
1501 // put at the end of the list if too small or too big,
1502 if ((_nColumnPosition == BROWSER_INVALIDID) || (_nColumnPosition >= getFields().size())) // append the field
1503 {
1504 if (FindFirstFreeCol(_nColumnPosition) == nullptr) // no more free columns
1505 {
1506 AppendNewCol();
1507 _nColumnPosition = sal::static_int_cast< sal_uInt16 >(
1508 getFields().size());
1509 }
1510 else
1511 ++_nColumnPosition; // within the list
1512 nColumnId = GetColumnId(_nColumnPosition);
1513 pEntry->SetColumnId( nColumnId );
1514 getFields()[ _nColumnPosition - 1] = pEntry;
1515 }
1516
1517 // check if the column ids are identical, if not we have to move
1518 if ( pEntry->GetColumnId() != nColumnId )
1519 {
1520 sal_uInt16 nOldPosition = GetColumnPos(pEntry->GetColumnId());
1521 OSL_ENSURE( nOldPosition != 0,"Old position was 0. Not possible!");
1522 SetColumnPos(pEntry->GetColumnId(),_nColumnPosition);
1523 // we have to delete an empty field for the fields list, because the columns must have equal length
1524 if ( nOldPosition > 0 && nOldPosition <= getFields().size() )
1525 getFields()[nOldPosition - 1] = pEntry;
1526
1527 ColumnMoved(pEntry->GetColumnId(),false);
1528 }
1529
1530 if ( pEntry->GetFunctionType() & FKT_AGGREGATE )
1531 {
1532 OUString sFunctionName = pEntry->GetFunction();
1533 if ( GetFunctionName(sal_uInt32(-1),sFunctionName) )
1534 pEntry->SetFunction(sFunctionName);
1535 }
1536
1537 nColumnId = pEntry->GetColumnId();
1538
1539 SetColWidth(nColumnId,getDesignView()->getColWidth(GetColumnPos(nColumnId)-1));
1540 // redraw
1541 tools::Rectangle aInvalidRect = GetInvalidRect( nColumnId );
1542 Invalidate( aInvalidRect );
1543
1544 ActivateCell( nCurrentRow, nCurCol );
1545 static_cast<OQueryController&>(getDesignView()->getController()).setModified( true );
1546
1548}
1549
1551{
1552 OQueryTableWindow* pSourceWin = static_cast<OQueryTableWindow*>(jxdSource.pListBox->GetTabWin());
1553 if (!pSourceWin)
1554 return nullptr;
1555
1556 // name and position of the selected field
1557 weld::TreeView& rTreeView = jxdSource.pListBox->get_widget();
1558 OUString aFieldName = rTreeView.get_text(jxdSource.nEntry);
1559 sal_uInt32 nFieldIndex = jxdSource.nEntry;
1560 OTableFieldInfo* pInf = weld::fromId<OTableFieldInfo*>(rTreeView.get_id(jxdSource.nEntry));
1561
1562 // construct DragInfo, such that I use the other InsertField
1563 OTableFieldDescRef aInfo = new OTableFieldDesc(pSourceWin->GetTableName(),aFieldName);
1564 aInfo->SetTabWindow(pSourceWin);
1565 aInfo->SetFieldIndex(nFieldIndex);
1566 aInfo->SetFieldType(pInf->GetKeyType());
1567 aInfo->SetAlias(pSourceWin->GetAliasName());
1568
1569 aInfo->SetDataType(pInf->GetDataType());
1570 aInfo->SetVisible();
1571
1572 return InsertField(aInfo);
1573}
1574
1575OTableFieldDescRef OSelectionBrowseBox::InsertField(const OTableFieldDescRef& _rInfo, sal_uInt16 _nColumnPosition, bool bVis, bool bActivate)
1576{
1577
1579 return nullptr;
1580 if (bActivate)
1581 SaveModified();
1582
1583 // new column description
1584 OTableFieldDescRef pEntry = _rInfo;
1585 pEntry->SetVisible(bVis);
1586
1587 // insert column
1588 InsertColumn( pEntry, _nColumnPosition );
1589
1590 if ( !m_bInUndoMode )
1591 {
1592 // trigger UndoAction
1593 std::unique_ptr<OTabFieldCreateUndoAct> pUndoAction(new OTabFieldCreateUndoAct( this ));
1594 pUndoAction->SetTabFieldDescr( pEntry );
1595 pUndoAction->SetColumnPosition(_nColumnPosition);
1596 getDesignView()->getController().addUndoActionAndInvalidate( std::move(pUndoAction) );
1597 }
1598
1599 return pEntry;
1600}
1601
1603{
1604 sal_uInt16 nCount = 0;
1605 for (auto const& field : getFields())
1606 {
1607 if (field.is() && !field->IsEmpty())
1608 ++nCount;
1609 }
1610
1611 return nCount;
1612}
1613
1615{
1616
1617 _rColumnPosition = BROWSER_INVALIDID;
1618
1619 for (auto const& field : getFields())
1620 {
1621 ++_rColumnPosition;
1622 OTableFieldDescRef pEntry = field;
1623 if ( pEntry.is() && pEntry->IsEmpty() )
1624 return pEntry;
1625 }
1626
1627 return nullptr;
1628}
1629
1630void OSelectionBrowseBox::CheckFreeColumns(sal_uInt16& _rColumnPosition)
1631{
1632 if (FindFirstFreeCol(_rColumnPosition) == nullptr)
1633 {
1634 // it is full, so append a pack of columns
1636 OSL_VERIFY(FindFirstFreeCol(_rColumnPosition).is());
1637 }
1638}
1639
1641{
1643 if(!xConnection.is())
1644 return;
1645 OSL_ENSURE(!rInfo->IsEmpty(),"AddGroupBy:: OTableFieldDescRef should not be empty!");
1646 OTableFieldDescRef pEntry;
1647 const Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
1648 const ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
1649 //sal_Bool bAppend = sal_False;
1650
1651 bool bAllFieldsSearched = true;
1652 for (auto const& field : getFields())
1653 {
1654 pEntry = field;
1655 OSL_ENSURE(pEntry.is(),"OTableFieldDescRef was null!");
1656
1657 const OUString aField = pEntry->GetField();
1658 const OUString aAlias = pEntry->GetAlias();
1659
1660 if (bCase(aField,rInfo->GetField()) &&
1661 bCase(aAlias,rInfo->GetAlias()) &&
1662 pEntry->GetFunctionType() == rInfo->GetFunctionType() &&
1663 pEntry->GetFunction() == rInfo->GetFunction())
1664 {
1665 if ( pEntry->isNumericOrAggregateFunction() && rInfo->IsGroupBy() )
1666 {
1667 pEntry->SetGroupBy(false);
1668 // we do want to consider that bAllFieldsSearched still true here
1669 // bAllFieldsSearched = false;
1670 break;
1671 }
1672 else
1673 {
1674 if ( !pEntry->IsGroupBy() && !pEntry->HasCriteria() ) // here we have a where condition which is no having clause
1675 {
1676 pEntry->SetGroupBy(rInfo->IsGroupBy());
1677 if(!m_bGroupByUnRelated && pEntry->IsGroupBy())
1678 pEntry->SetVisible();
1679 bAllFieldsSearched = false;
1680 break;
1681 }
1682 }
1683
1684 }
1685 }
1686
1687 if (bAllFieldsSearched)
1688 {
1689 OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, false, false );
1690 if ( pTmp->isNumericOrAggregateFunction() && rInfo->IsGroupBy() ) // the GroupBy is inherited from rInfo
1691 pTmp->SetGroupBy(false);
1692 }
1693}
1694
1696{
1697 const sal_uInt16 nNewLevel = nLevel +1;
1698 for (auto const& field : getFields())
1699 {
1700 const OTableFieldDescRef& pEntry = field;
1701 OUString sValue = pEntry->GetCriteria(nLevel);
1702 if ( !sValue.isEmpty() )
1703 {
1704 pEntry->SetCriteria( nNewLevel, sValue);
1705 if ( nNewLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1) )
1706 {
1707 RowInserted( GetRowCount()-1 );
1708 m_bVisibleRow.push_back(true);
1710 }
1711 m_bVisibleRow[BROW_CRIT1_ROW + nNewLevel] = true;
1712 }
1713 }
1714}
1715
1716void OSelectionBrowseBox::AddCondition( const OTableFieldDescRef& rInfo, const OUString& rValue, const sal_uInt16 nLevel,bool _bAddOrOnOneLine )
1717{
1719 if(!xConnection.is())
1720 return;
1721 OSL_ENSURE(rInfo.is() && !rInfo->IsEmpty(),"AddCondition:: OTableFieldDescRef should not be Empty!");
1722
1723 OTableFieldDescRef pLastEntry;
1724 Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
1725 ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
1726
1727 bool bAllFieldsSearched = true;
1728 for (auto const& field : getFields())
1729 {
1730 const OTableFieldDescRef& pEntry = field;
1731 const OUString aField = pEntry->GetField();
1732 const OUString aAlias = pEntry->GetAlias();
1733
1734 if (bCase(aField,rInfo->GetField()) &&
1735 bCase(aAlias,rInfo->GetAlias()) &&
1736 pEntry->GetFunctionType() == rInfo->GetFunctionType() &&
1737 pEntry->GetFunction() == rInfo->GetFunction() &&
1738 pEntry->IsGroupBy() == rInfo->IsGroupBy() )
1739 {
1740 if ( pEntry->isNumericOrAggregateFunction() && rInfo->IsGroupBy() )
1741 pEntry->SetGroupBy(false);
1742 else
1743 {
1744 if(!m_bGroupByUnRelated && pEntry->IsGroupBy())
1745 pEntry->SetVisible();
1746 }
1747 if (pEntry->GetCriteria(nLevel).isEmpty() )
1748 {
1749 pEntry->SetCriteria( nLevel, rValue);
1750 if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
1751 {
1752 RowInserted( GetRowCount()-1 );
1753 m_bVisibleRow.push_back(true);
1755 }
1756 m_bVisibleRow[BROW_CRIT1_ROW + nLevel] = true;
1757 bAllFieldsSearched = false;
1758 break;
1759 }
1760 if ( _bAddOrOnOneLine )
1761 {
1762 pLastEntry = pEntry;
1763 }
1764 }
1765 }
1766 if ( pLastEntry.is() )
1767 {
1768 OUString sCriteria = rValue;
1769 OUString sOldCriteria = pLastEntry->GetCriteria( nLevel );
1770 if ( !sOldCriteria.isEmpty() )
1771 {
1772 sCriteria = "( " + sOldCriteria + " OR " + rValue + " )";
1773 }
1774 pLastEntry->SetCriteria( nLevel, sCriteria);
1775 if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
1776 {
1777 RowInserted( GetRowCount()-1 );
1778 m_bVisibleRow.push_back(true);
1780 }
1781 m_bVisibleRow[BROW_CRIT1_ROW + nLevel] = true;
1782 }
1783 else if (bAllFieldsSearched)
1784 {
1785 OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, false, false );
1786 if ( pTmp->isNumericOrAggregateFunction() && rInfo->IsGroupBy() ) // the GroupBy was inherited from rInfo
1787 pTmp->SetGroupBy(false);
1788 if ( pTmp.is() )
1789 {
1790 pTmp->SetCriteria( nLevel, rValue);
1791 if(nLevel == (m_nVisibleCount-BROW_CRIT1_ROW-1))
1792 {
1793 RowInserted( GetRowCount()-1 );
1794 m_bVisibleRow.push_back(true);
1796 }
1797 }
1798 }
1799}
1800
1801void OSelectionBrowseBox::AddOrder( const OTableFieldDescRef& rInfo, const EOrderDir eDir, sal_uInt32 _nCurrentPos)
1802{
1803 if (_nCurrentPos == 0)
1805
1807 if(!xConnection.is())
1808 return;
1809 OSL_ENSURE(!rInfo->IsEmpty(),"AddOrder:: OTableFieldDescRef should not be Empty!");
1810 OTableFieldDescRef pEntry;
1811 Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
1812 ::comphelper::UStringMixEqual bCase(xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
1813
1814 bool bAppend = false;
1815 sal_uInt32 nPos = 0;
1816 bool bAllFieldsSearched = true;
1817 for (auto const& field : getFields())
1818 {
1819 pEntry = field;
1820 OUString aField = pEntry->GetField();
1821 OUString aAlias = pEntry->GetAlias();
1822
1823 if (bCase(aField,rInfo->GetField()) &&
1824 bCase(aAlias,rInfo->GetAlias()))
1825 {
1827 if ( bAppend )
1828 {
1829 // we do want to consider that bAllFieldsSearched still true here
1830 // bAllFieldsSearched = false;
1831 break;
1832 }
1833 else
1834 {
1835 if ( !m_bOrderByUnRelated )
1836 pEntry->SetVisible();
1837 pEntry->SetOrderDir( eDir );
1839 }
1840 bAllFieldsSearched = false;
1841 break;
1842 }
1843 ++nPos;
1844 }
1845
1846 if (bAllFieldsSearched)
1847 {
1848 OTableFieldDescRef pTmp = InsertField(rInfo, BROWSER_INVALIDID, false, false );
1849 if(pTmp.is())
1850 {
1851 m_nLastSortColumn = pTmp->GetColumnId() - 1;
1852 if ( !m_bOrderByUnRelated && !bAppend )
1853 pTmp->SetVisible();
1854 pTmp->SetOrderDir( eDir );
1855 }
1856 }
1857}
1858
1860{
1861 bool bRet = true;
1862 if (IsModified())
1863 bRet = SaveModified();
1864 return bRet;
1865}
1866
1868{
1869 sal_Int32 nRow = GetRealRow(GetCurRow());
1870 switch (nRow)
1871 {
1872 case BROW_VIS_ROW:
1873 {
1875
1876 weld::ComboBox& rComboBox = m_pOrderCell->get_widget();
1877 sal_Int32 nIdx = rComboBox.get_active();
1878 if(!m_bOrderByUnRelated && nIdx > 0 &&
1879 nIdx != -1 &&
1880 !pEntry->IsEmpty() &&
1881 pEntry->GetOrderDir() != ORDER_NONE)
1882 {
1883 m_pVisibleCell->GetBox().set_active(true);
1884 pEntry->SetVisible();
1885 }
1886 else
1887 pEntry->SetVisible(m_pVisibleCell->GetBox().get_active());
1888 }
1889 break;
1890 }
1891 static_cast<OQueryController&>(getDesignView()->getController()).setModified( true );
1892}
1893
1895{
1896 OSL_ENSURE(ColCount() >= 1, "OSelectionBrowseBox::Fill : please call only after inserting the handle column !");
1897
1898 sal_uInt16 nColCount = ColCount() - 1;
1899 if (nColCount < DEFAULT_QUERY_COLS)
1900 AppendNewCol(DEFAULT_QUERY_COLS - nColCount);
1901}
1902
1904{
1905 Size aReturn( _rAvailable.Width(), GetTitleHeight() );
1906
1908 aReturn.AdjustHeight(40 ); // just some space
1909
1910 return aReturn;
1911}
1912
1914{
1915 switch (rEvt.GetCommand())
1916 {
1917 case CommandEventId::ContextMenu:
1918 {
1919 Point aMenuPos( rEvt.GetMousePosPixel() );
1920
1921 if (!rEvt.IsMouseEvent())
1922 {
1923 if ( 1 == GetSelectColumnCount() )
1924 {
1925 sal_uInt16 nSelId = GetColumnId(
1926 sal::static_int_cast< sal_uInt16 >(
1927 FirstSelectedColumn() ) );
1928 ::tools::Rectangle aColRect( GetFieldRectPixel( 0, nSelId, false ) );
1929
1930 aMenuPos = aColRect.TopCenter();
1931 }
1932 else
1933 {
1935 return;
1936 }
1937 }
1938
1939 sal_uInt16 nColId = GetColumnId(GetColumnAtXPosPixel( aMenuPos.X() ));
1940 sal_Int32 nRow = GetRowAtYPosPixel( aMenuPos.Y() );
1941
1942 if (nRow < 0 && nColId > HANDLE_ID )
1943 {
1944 if ( !IsColumnSelected( nColId ) )
1945 {
1946 adjustSelectionMode( true /* clicked onto a header */ , false /* not onto the handle col */ );
1947 SelectColumnId( nColId );
1948 }
1949
1950 if (!static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
1951 {
1952 ::tools::Rectangle aRect(aMenuPos, Size(1, 1));
1953 weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
1954 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "dbaccess/ui/querycolmenu.ui"));
1955 std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu"));
1956 OUString sIdent = xContextMenu->popup_at_rect(pPopupParent, aRect);
1957 if (sIdent == "delete")
1958 RemoveField(nColId);
1959 else if (sIdent == "width")
1960 adjustBrowseBoxColumnWidth( this, nColId );
1961 }
1962 }
1963 else if(nRow >= 0 && nColId <= HANDLE_ID)
1964 {
1965 if (!static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
1966 {
1967 ::tools::Rectangle aRect(aMenuPos, Size(1, 1));
1968 weld::Window* pPopupParent = weld::GetPopupParent(*this, aRect);
1969 std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "dbaccess/ui/queryfuncmenu.ui"));
1970 std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu("menu"));
1971 xContextMenu->set_active("functions", m_bVisibleRow[BROW_FUNCTION_ROW]);
1972 xContextMenu->set_active("tablename", m_bVisibleRow[BROW_TABLE_ROW]);
1973 xContextMenu->set_active("alias", m_bVisibleRow[BROW_COLUMNALIAS_ROW]);
1974 xContextMenu->set_active("distinct", static_cast<OQueryController&>(getDesignView()->getController()).isDistinct());
1975
1976 OUString sIdent = xContextMenu->popup_at_rect(pPopupParent, aRect);
1977 if (sIdent == "functions")
1978 {
1980 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_FUNCTIONS );
1981 }
1982 else if (sIdent == "tablename")
1983 {
1985 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_TABLES );
1986 }
1987 else if (sIdent == "alias")
1988 {
1990 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_VIEW_ALIASES );
1991 }
1992 else if (sIdent == "distinct")
1993 {
1994 static_cast<OQueryController&>(getDesignView()->getController()).setDistinct(!static_cast<OQueryController&>(getDesignView()->getController()).isDistinct());
1995 static_cast<OQueryController&>(getDesignView()->getController()).setModified( true );
1996 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature( SID_QUERY_DISTINCT_VALUES );
1997 }
1998
1999 static_cast<OQueryController&>(getDesignView()->getController()).setModified( true );
2000 }
2001 }
2002 else
2003 {
2005 return;
2006 }
2007
2008 [[fallthrough]];
2009 }
2010 default:
2012 }
2013}
2014
2015bool OSelectionBrowseBox::IsRowVisible(sal_uInt16 _nWhich) const
2016{
2017 OSL_ENSURE(_nWhich<(m_bVisibleRow.size()), "OSelectionBrowseBox::IsRowVisible : invalid parameter !");
2018 return m_bVisibleRow[_nWhich];
2019}
2020
2021void OSelectionBrowseBox::SetRowVisible(sal_uInt16 _nWhich, bool _bVis)
2022{
2023 OSL_ENSURE(_nWhich<m_bVisibleRow.size(), "OSelectionBrowseBox::SetRowVisible : invalid parameter !");
2024
2025 bool bWasEditing = IsEditing();
2026 if (bWasEditing)
2028
2029 // do this before removing or inserting rows, as this triggers ActivateCell-calls, which rely on m_bVisibleRow
2030 m_bVisibleRow[_nWhich] = !m_bVisibleRow[_nWhich];
2031
2032 tools::Long nId = GetBrowseRow(_nWhich);
2033 if (_bVis)
2034 {
2037 }
2038 else
2039 {
2040 RowRemoved(nId);
2042 }
2043
2044 if (bWasEditing)
2045 ActivateCell();
2046}
2047
2048sal_Int32 OSelectionBrowseBox::GetBrowseRow(sal_Int32 nRowId) const
2049{
2050 sal_Int32 nCount(0);
2051 for(sal_Int32 i = 0 ; i < nRowId ; ++i)
2052 {
2053 if ( m_bVisibleRow[i] )
2054 ++nCount;
2055 }
2056 return nCount;
2057}
2058
2059sal_Int32 OSelectionBrowseBox::GetRealRow(sal_Int32 nRowId) const
2060{
2061 sal_Int32 nErg=0,i;
2062 const sal_Int32 nCount = m_bVisibleRow.size();
2063 for(i=0;i < nCount; ++i)
2064 {
2065 if(m_bVisibleRow[i] && nErg++ == nRowId)
2066 break;
2067 }
2068 OSL_ENSURE(nErg <= tools::Long(m_bVisibleRow.size()),"nErg cannot be greater than BROW_ROW_CNT!");
2069 return i;
2070}
2071
2073 {
2074 0x0001,
2075 0x0002,
2076 0x0004,
2077 0x0008,
2078 0x0010,
2079 0x0020,
2080 0x0040,
2081 0x0080,
2082 0x0100,
2083 0x0200,
2084 0x0400,
2085 0x0800
2086 };
2088{
2089 sal_Int32 nErg(0);
2090 // only the first 11 rows are interesting
2091 std::size_t const nSize = std::size(nVisibleRowMask);
2092 for(std::size_t i=0;i<nSize;i++)
2093 {
2094 if(!m_bVisibleRow[i])
2095 nErg |= nVisibleRowMask[i];
2096 }
2097 return nErg;
2098}
2099
2101{
2102 // only the first 11 rows are interesting
2103 std::size_t const nSize = std::size(nVisibleRowMask);
2104 for(std::size_t i=0;i< nSize;i++)
2105 m_bVisibleRow[i] = !(nRows & nVisibleRowMask[i]);
2106}
2107
2108OUString OSelectionBrowseBox::GetCellText(sal_Int32 nRow, sal_uInt16 nColId) const
2109{
2110
2111 sal_uInt16 nPos = GetColumnPos(nColId);
2112 if ( nPos == 0 || nPos == BROWSER_INVALIDID || nPos > getFields().size() )
2113 return OUString();
2114
2115 OTableFieldDescRef pEntry = getFields()[nPos-1];
2116 OSL_ENSURE(pEntry != nullptr, "OSelectionBrowseBox::GetCellText : invalid column id, prepare for GPF ... ");
2117 if ( pEntry->IsEmpty() )
2118 return OUString();
2119
2120 OUString aText;
2121 switch (nRow)
2122 {
2123 case BROW_TABLE_ROW:
2124 aText = pEntry->GetAlias();
2125 break;
2126 case BROW_FIELD_ROW:
2127 {
2128 OUString aField = pEntry->GetField();
2129 if (!aField.isEmpty() && aField[0] == '*') // * replace with alias.*
2130 {
2131 aField = pEntry->GetAlias();
2132 if(!aField.isEmpty())
2133 aField += ".";
2134 aField += "*";
2135 }
2136 aText = aField;
2137 } break;
2138 case BROW_ORDER_ROW:
2139 if (pEntry->GetOrderDir() != ORDER_NONE)
2140 aText = DBA_RES(STR_QUERY_SORTTEXT).getToken(sal::static_int_cast< sal_uInt16 >(pEntry->GetOrderDir()), ';');
2141 break;
2142 case BROW_VIS_ROW:
2143 break;
2145 aText = pEntry->GetFieldAlias();
2146 break;
2147 case BROW_FUNCTION_ROW:
2148 // we always show the group function at first
2149 if ( pEntry->IsGroupBy() )
2150 aText = m_aFunctionStrings.copy(m_aFunctionStrings.lastIndexOf(';')+1);
2151 else if ( pEntry->isNumericOrAggregateFunction() )
2152 aText = pEntry->GetFunction();
2153 break;
2154 default:
2155 aText = pEntry->GetCriteria(sal_uInt16(nRow - BROW_CRIT1_ROW));
2156 }
2157 return aText;
2158}
2159
2160bool OSelectionBrowseBox::GetFunctionName(sal_uInt32 _nFunctionTokenId, OUString& rFkt)
2161{
2162 weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
2163 switch(_nFunctionTokenId)
2164 {
2165 case SQL_TOKEN_COUNT:
2166 rFkt = (rComboBox.get_count() < 3) ? rComboBox.get_text(1) : rComboBox.get_text(2);
2167 break;
2168 case SQL_TOKEN_AVG:
2169 rFkt = rComboBox.get_text(1);
2170 break;
2171 case SQL_TOKEN_MAX:
2172 rFkt = rComboBox.get_text(3);
2173 break;
2174 case SQL_TOKEN_MIN:
2175 rFkt = rComboBox.get_text(4);
2176 break;
2177 case SQL_TOKEN_SUM:
2178 rFkt = rComboBox.get_text(5);
2179 break;
2180 case SQL_TOKEN_EVERY:
2181 rFkt = rComboBox.get_text(6);
2182 break;
2183 case SQL_TOKEN_ANY:
2184 rFkt = rComboBox.get_text(7);
2185 break;
2186 case SQL_TOKEN_SOME:
2187 rFkt = rComboBox.get_text(8);
2188 break;
2189 case SQL_TOKEN_STDDEV_POP:
2190 rFkt = rComboBox.get_text(9);
2191 break;
2192 case SQL_TOKEN_STDDEV_SAMP:
2193 rFkt = rComboBox.get_text(10);
2194 break;
2195 case SQL_TOKEN_VAR_SAMP:
2196 rFkt = rComboBox.get_text(11);
2197 break;
2198 case SQL_TOKEN_VAR_POP:
2199 rFkt = rComboBox.get_text(12);
2200 break;
2201 case SQL_TOKEN_COLLECT:
2202 rFkt = rComboBox.get_text(13);
2203 break;
2204 case SQL_TOKEN_FUSION:
2205 rFkt = rComboBox.get_text(14);
2206 break;
2207 case SQL_TOKEN_INTERSECTION:
2208 rFkt = rComboBox.get_text(15);
2209 break;
2210 default:
2211 {
2212 const sal_Int32 nStopIdx = m_aFunctionStrings.lastIndexOf(';'); // grouping is not counted
2213 for (sal_Int32 nIdx {0}; nIdx<nStopIdx;)
2214 {
2215 const OUString sFunc {m_aFunctionStrings.getToken(0, ';', nIdx)};
2216 if (rFkt.equalsIgnoreAsciiCase(sFunc))
2217 {
2218 rFkt = sFunc;
2219 return true;
2220 }
2221 }
2222 return false;
2223 }
2224 }
2225
2226 return true;
2227}
2228
2229OUString OSelectionBrowseBox::GetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId)
2230{
2231 if ( GetCurColumnId() == nColId && !m_bInUndoMode )
2232 SaveModified();
2233
2234 sal_uInt16 nPos = GetColumnPos(nColId);
2235 OTableFieldDescRef pEntry = getFields()[nPos - 1];
2236 OSL_ENSURE(pEntry != nullptr, "OSelectionBrowseBox::GetCellContents : invalid column id, prepare for GPF ... ");
2237
2238 switch (nCellIndex)
2239 {
2240 case BROW_VIS_ROW :
2241 return OUString(pEntry->IsVisible() ? std::u16string_view(u"1") : std::u16string_view(u"0"));
2242 case BROW_ORDER_ROW:
2243 {
2244 sal_Int32 nIdx = m_pOrderCell->get_widget().get_active();
2245 if (nIdx == -1)
2246 nIdx = 0;
2247 return OUString::number(nIdx);
2248 }
2249 default:
2250 return GetCellText(nCellIndex, nColId);
2251 }
2252}
2253
2254void OSelectionBrowseBox::SetCellContents(sal_Int32 nRow, sal_uInt16 nColId, const OUString& strNewText)
2255{
2256 bool bWasEditing = IsEditing() && (GetCurColumnId() == nColId) && IsRowVisible(static_cast<sal_uInt16>(nRow)) && (GetCurRow() == static_cast<sal_uInt16>(GetBrowseRow(nRow)));
2257 if (bWasEditing)
2259
2260 sal_uInt16 nPos = GetColumnPos(nColId);
2261 OTableFieldDescRef pEntry = getEntry(nPos - 1);
2262 OSL_ENSURE(pEntry != nullptr, "OSelectionBrowseBox::SetCellContents : invalid column id, prepare for GPF ... ");
2263
2264 switch (nRow)
2265 {
2266 case BROW_VIS_ROW:
2267 pEntry->SetVisible(strNewText == "1");
2268 break;
2269 case BROW_FIELD_ROW:
2270 pEntry->SetField(strNewText);
2271 break;
2272 case BROW_TABLE_ROW:
2273 pEntry->SetAlias(strNewText);
2274 break;
2275 case BROW_ORDER_ROW:
2276 {
2277 sal_uInt16 nIdx = static_cast<sal_uInt16>(strNewText.toInt32());
2278 pEntry->SetOrderDir(EOrderDir(nIdx));
2279 } break;
2281 pEntry->SetFieldAlias(strNewText);
2282 break;
2283 case BROW_FUNCTION_ROW:
2284 {
2285 std::u16string_view sGroupFunctionName = m_aFunctionStrings.subView(m_aFunctionStrings.lastIndexOf(';')+1);
2286 pEntry->SetFunction(strNewText);
2287 // first reset this two member
2288 sal_Int32 nFunctionType = pEntry->GetFunctionType();
2289 nFunctionType &= ~FKT_AGGREGATE;
2290 pEntry->SetFunctionType(nFunctionType);
2291 if ( pEntry->IsGroupBy() && !o3tl::equalsIgnoreAsciiCase(sGroupFunctionName, strNewText) )
2292 pEntry->SetGroupBy(false);
2293
2294 if ( o3tl::equalsIgnoreAsciiCase(sGroupFunctionName, strNewText) )
2295 pEntry->SetGroupBy(true);
2296 else if ( !strNewText.isEmpty() )
2297 {
2298 nFunctionType |= FKT_AGGREGATE;
2299 pEntry->SetFunctionType(nFunctionType);
2300 }
2301 } break;
2302 default:
2303 pEntry->SetCriteria(sal_uInt16(nRow - BROW_CRIT1_ROW), strNewText);
2304 }
2305
2306 tools::Long nCellIndex = GetRealRow(nRow);
2307 if(IsRowVisible(static_cast<sal_uInt16>(nRow)))
2308 RowModified(nCellIndex, nColId);
2309
2310 // the appropriate field-description is now empty -> set Visible to sal_False (now it is consistent to normal empty rows)
2311 if (pEntry->IsEmpty())
2312 pEntry->SetVisible(false);
2313
2314 if (bWasEditing)
2315 ActivateCell(nCellIndex, nColId);
2316
2317 static_cast<OQueryController&>(getDesignView()->getController()).setModified( true );
2318}
2319
2321{
2322 if (static_cast<OQueryController&>(getDesignView()->getController()).isReadOnly())
2323 return;
2324 // The resizing of columns can't be suppressed (BrowseBox doesn't support that) so we have to do this
2325 // fake. It's not _that_ bad : the user may change column widths while in read-only mode to see all details
2326 // but the changes aren't permanent ...
2327
2328 sal_uInt16 nPos = GetColumnPos(nColId);
2329 OSL_ENSURE(nPos <= getFields().size(),"ColumnResized:: nColId should not be greater than List::count!");
2330 OTableFieldDescRef pEntry = getEntry(nPos-1);
2331 OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::ColumnResized : invalid FieldDescription !");
2332 static_cast<OQueryController&>(getDesignView()->getController()).setModified( true );
2334
2335 if ( pEntry.is())
2336 {
2337 if ( !m_bInUndoMode )
2338 {
2339 // create the undo action
2340 std::unique_ptr<OTabFieldSizedUndoAct> pUndo(new OTabFieldSizedUndoAct(this));
2341 pUndo->SetColumnPosition( nPos );
2342 pUndo->SetOriginalWidth(pEntry->GetColWidth());
2344 }
2345 pEntry->SetColWidth(sal_uInt16(GetColumnWidth(nColId)));
2346 }
2347}
2348
2349sal_uInt32 OSelectionBrowseBox::GetTotalCellWidth(sal_Int32 nRowId, sal_uInt16 nColId)
2350{
2351 sal_uInt16 nPos = GetColumnPos(nColId);
2352 OSL_ENSURE((nPos == 0) || (nPos <= getFields().size()), "OSelectionBrowseBox::GetTotalCellWidth : invalid parameter nColId");
2353
2354 OTableFieldDescRef pEntry = getFields()[nPos-1];
2355 OSL_ENSURE(pEntry.is(), "OSelectionBrowseBox::GetTotalCellWidth : invalid FieldDescription !");
2356
2357 sal_Int32 nRow = GetRealRow(nRowId);
2358 OUString strText(GetCellText(nRow, nColId));
2359 return GetDataWindow().LogicToPixel(Size(GetDataWindow().GetTextWidth(strText),0)).Width();
2360}
2361
2363{
2364 bool bCutAllowed = false;
2365 sal_Int32 nRow = GetRealRow(GetCurRow());
2366 switch (nRow)
2367 {
2368 case BROW_VIS_ROW:
2369 case BROW_ORDER_ROW:
2370 case BROW_TABLE_ROW:
2371 case BROW_FUNCTION_ROW:
2372 break;
2373 case BROW_FIELD_ROW:
2374 {
2375 weld::ComboBox& rComboBox = m_pFieldCell->get_widget();
2376 int nStartPos, nEndPos;
2377 bCutAllowed = rComboBox.get_entry_selection_bounds(nStartPos, nEndPos);
2378 break;
2379 }
2380 default:
2381 {
2382 weld::Entry& rEntry = m_pTextCell->get_widget();
2383 int nStartPos, nEndPos;
2384 bCutAllowed = rEntry.get_selection_bounds(nStartPos, nEndPos);
2385 break;
2386 }
2387 }
2388 return bCutAllowed;
2389}
2390
2392{
2393 sal_Int32 nRow = GetRealRow(GetCurRow());
2394 switch (nRow)
2395 {
2396 case BROW_FIELD_ROW:
2397 {
2398 weld::ComboBox& rComboBox = m_pFieldCell->get_widget();
2399 rComboBox.cut_entry_clipboard();
2400 break;
2401 }
2402 default:
2403 {
2404 weld::Entry& rEntry = m_pTextCell->get_widget();
2405 rEntry.cut_clipboard();
2406 }
2407 }
2408 SaveModified();
2410
2412}
2413
2415{
2416 sal_Int32 nRow = GetRealRow(GetCurRow());
2417 switch (nRow)
2418 {
2419 case BROW_FIELD_ROW:
2420 {
2421 weld::ComboBox& rComboBox = m_pFieldCell->get_widget();
2422 rComboBox.paste_entry_clipboard();
2423 break;
2424 }
2425 default:
2426 {
2427 weld::Entry& rEntry = m_pTextCell->get_widget();
2428 rEntry.paste_clipboard();
2429 break;
2430 }
2431 }
2434}
2435
2437{
2438 bool bPasteAllowed = true;
2439 sal_Int32 nRow = GetRealRow(GetCurRow());
2440 switch (nRow)
2441 {
2442 case BROW_VIS_ROW:
2443 case BROW_ORDER_ROW:
2444 case BROW_TABLE_ROW:
2445 case BROW_FUNCTION_ROW:
2446 bPasteAllowed = false;
2447 break;
2448 }
2449 return bPasteAllowed;
2450}
2451
2453{
2454 return isCutAllowed();
2455}
2456
2458{
2459 sal_Int32 nRow = GetRealRow(GetCurRow());
2460 switch (nRow)
2461 {
2462 case BROW_FIELD_ROW:
2463 {
2464 weld::ComboBox& rComboBox = m_pFieldCell->get_widget();
2465 rComboBox.copy_entry_clipboard();
2466 break;
2467 }
2468 default:
2469 {
2470 weld::Entry& rEntry = m_pTextCell->get_widget();
2471 rEntry.copy_clipboard();
2472 break;
2473 }
2474 }
2475}
2476
2477void OSelectionBrowseBox::appendUndoAction(const OUString& _rOldValue, std::u16string_view _rNewValue, sal_Int32 _nRow, bool& _bListAction)
2478{
2479 if ( !m_bInUndoMode && _rNewValue != _rOldValue )
2480 {
2481 if ( !_bListAction )
2482 {
2483 _bListAction = true;
2484 static_cast<OQueryController&>(getDesignView()->getController()).GetUndoManager().EnterListAction(OUString(),OUString(),0,ViewShellId(-1));
2485 }
2486 appendUndoAction(_rOldValue,_rNewValue,_nRow);
2487 }
2488}
2489
2490void OSelectionBrowseBox::appendUndoAction(const OUString& _rOldValue,std::u16string_view _rNewValue,sal_Int32 _nRow)
2491{
2492 if ( !m_bInUndoMode && _rNewValue != _rOldValue )
2493 {
2494 std::unique_ptr<OTabFieldCellModifiedUndoAct> pUndoAct(new OTabFieldCellModifiedUndoAct(this));
2495 pUndoAct->SetCellIndex(_nRow);
2496 OSL_ENSURE(GetColumnPos(GetCurColumnId()) != BROWSER_INVALIDID,"Current position isn't valid!");
2497 pUndoAct->SetColumnPosition( GetColumnPos(GetCurColumnId()) );
2498 pUndoAct->SetCellContents(_rOldValue);
2499 getDesignView()->getController().addUndoActionAndInvalidate(std::move(pUndoAct));
2500 }
2501}
2502
2503IMPL_LINK_NOARG(OSelectionBrowseBox, OnInvalidateTimer, Timer *, void)
2504{
2505 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_CUT);
2506 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_COPY);
2507 static_cast<OQueryController&>(getDesignView()->getController()).InvalidateFeature(SID_PASTE);
2508 if(!m_bStopTimer)
2509 m_timerInvalidate.Start();
2510}
2511
2513{
2514 m_bStopTimer = true;
2517}
2518
2520{
2521 m_bStopTimer = false;
2524}
2525
2527{
2528 OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
2529 return rController.getTableFieldDesc();
2530}
2531
2533{
2534 bool bEnable = !_rEntry->isCondition();
2535 _pControl->Enable(bEnable);
2536 _pControl->EnableInput(bEnable);
2537}
2538
2539void OSelectionBrowseBox::setTextCellContext(const OTableFieldDescRef& _rEntry,const OUString& _sText,const OUString& _sHelpId)
2540{
2541 weld::Entry& rEntry = m_pTextCell->get_widget();
2542 rEntry.set_text(_sText);
2543 rEntry.save_value();
2544 if (!m_pTextCell->HasFocus())
2545 m_pTextCell->GrabFocus();
2546
2547 enableControl(_rEntry,m_pTextCell);
2548
2549 if (m_pTextCell->GetHelpId() != _sHelpId)
2550 // as TextCell is used in various contexts I will delete the cached HelpText
2551 m_pTextCell->SetHelpText(OUString());
2552 m_pTextCell->SetHelpId(_sHelpId);
2553}
2554
2556{
2557 OQueryController& rController = static_cast<OQueryController&>(getDesignView()->getController());
2558 rController.InvalidateFeature( ID_BROWSER_UNDO );
2559 rController.InvalidateFeature( ID_BROWSER_REDO );
2560 rController.InvalidateFeature( ID_BROWSER_QUERY_EXECUTE );
2561}
2562
2564{
2565 // we have to check if we need a new entry at this position
2566 OTableFields& aFields = getFields();
2567 OSL_ENSURE(aFields.size() > _nPos,"ColID is to great!");
2568
2569 OTableFieldDescRef pEntry = aFields[_nPos];
2570 OSL_ENSURE(pEntry.is(),"Invalid entry!");
2571 if ( !pEntry.is() )
2572 {
2573 pEntry = new OTableFieldDesc();
2574 pEntry->SetColumnId(
2575 GetColumnId(sal::static_int_cast< sal_uInt16 >(_nPos+1)));
2576 aFields[_nPos] = pEntry;
2577 }
2578 return pEntry;
2579}
2580
2582{
2583 if(!IsEditing() && !m_bWasEditing)
2584 ActivateCell();
2586}
2587
2589{
2590 m_bWasEditing = true;
2592 m_bWasEditing = false;
2593}
2594
2595OUString OSelectionBrowseBox::GetRowDescription( sal_Int32 _nRow ) const
2596{
2597 OUString aLabel(DBA_RES(STR_QUERY_HANDLETEXT));
2598
2599 // from BROW_CRIT2_ROW onwards all rows are shown as "or"
2600 sal_Int32 nToken = (_nRow >= GetBrowseRow(BROW_CRIT2_ROW))
2601 ? BROW_CRIT2_ROW : GetRealRow(_nRow);
2602 return aLabel.getToken(nToken, ';');
2603}
2604
2606{
2607 OUString sRetText;
2608 switch( _eObjType )
2609 {
2610 case AccessibleBrowseBoxObjType::RowHeaderCell:
2611 sRetText = GetRowDescription(_nPosition);
2612 break;
2613 default:
2614 sRetText = EditBrowseBox::GetAccessibleObjectDescription(_eObjType,_nPosition);
2615 }
2616 return sRetText;
2617}
2618
2619bool OSelectionBrowseBox::fillEntryTable(OTableFieldDescRef const & _pEntry,const OUString& _sTableName)
2620{
2621 bool bRet = false;
2623 OJoinTableView::OTableWindowMap::const_iterator aIter = rTabWinList.find(_sTableName);
2624 if(aIter != rTabWinList.end())
2625 {
2626 OQueryTableWindow* pEntryTab = static_cast<OQueryTableWindow*>(aIter->second.get());
2627 if (pEntryTab)
2628 {
2629 _pEntry->SetTable(pEntryTab->GetTableName());
2630 _pEntry->SetTabWindow(pEntryTab);
2631 bRet = true;
2632 }
2633 }
2634 return bRet;
2635}
2636
2638{
2640 if ( !xConnection.is() )
2641 return;
2642
2643 // Aggregate functions in general only available with Core SQL
2644 if ( lcl_SupportsCoreSQLGrammar(xConnection) )
2645 {
2646 sal_Int32 nIdx {0};
2647 // if we have an asterisk, no other function than count is allowed
2648 weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
2649 rComboBox.clear();
2650 rComboBox.append_text(m_aFunctionStrings.getToken(0, ';', nIdx));
2651 if ( isFieldNameAsterisk(_pEntry->GetField()) )
2652 rComboBox.append_text(m_aFunctionStrings.getToken(1, ';', nIdx)); // 2nd token: COUNT
2653 else
2654 {
2655 const bool bSkipLastToken {_pEntry->isNumeric()};
2656 while (nIdx>0)
2657 {
2658 const OUString sTok {m_aFunctionStrings.getToken(0, ';', nIdx)};
2659 if (bSkipLastToken && nIdx<0)
2660 break;
2661 rComboBox.append_text(sTok);
2662 }
2663 }
2664
2665 if ( _pEntry->IsGroupBy() )
2666 {
2667 OSL_ENSURE(!_pEntry->isNumeric(),"Not allowed to combine group by and numeric values!");
2668 rComboBox.set_active_text(rComboBox.get_text(rComboBox.get_count() - 1));
2669 }
2670 else if (rComboBox.find_text(_pEntry->GetFunction()) != -1)
2671 rComboBox.set_active_text(_pEntry->GetFunction());
2672 else
2673 rComboBox.set_active(0);
2674
2676 }
2677 else
2678 {
2679 // only COUNT(*) and COUNT("table".*) allowed
2680 bool bCountRemoved = !isFieldNameAsterisk(_pEntry->GetField());
2681 weld::ComboBox& rComboBox = m_pFunctionCell->get_widget();
2682 if ( bCountRemoved )
2683 rComboBox.remove(1);
2684
2685 if ( !bCountRemoved && rComboBox.get_count() < 2)
2686 rComboBox.append_text(m_aFunctionStrings.getToken(2, ';')); // 2 -> COUNT
2687
2688 if (rComboBox.find_text(_pEntry->GetFunction()) != -1)
2689 rComboBox.set_active_text(_pEntry->GetFunction());
2690 else
2691 rComboBox.set_active(0);
2692 }
2693}
2694
2696{
2697 OTableFieldDescRef pEntry;
2698 if ( _nColumnPos != 0 && _nColumnPos != BROWSER_INVALIDID && _nColumnPos <= getFields().size() )
2699 pEntry = getFields()[_nColumnPos - 1];
2700
2701 if ( _nRow == BROW_VIS_ROW && pEntry.is() )
2702 return EditBrowseBox::CreateAccessibleCheckBoxCell( _nRow, _nColumnPos,pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE );
2703
2704 return EditBrowseBox::CreateAccessibleCell( _nRow, _nColumnPos );
2705}
2706
2707bool OSelectionBrowseBox::HasFieldByAliasName(std::u16string_view rFieldName, OTableFieldDescRef const & rInfo) const
2708{
2709 for (auto const& field : getFields())
2710 {
2711 if ( field->GetFieldAlias() == rFieldName )
2712 {
2713 *rInfo = *field;
2714 return true;
2715 }
2716 }
2717 return false;
2718}
2719
2720/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AccessibleBrowseBoxObjType
#define DEFAULT_QUERY_COLS
#define HANDLE_COLUMN_WIDTH
const tools::Long nVisibleRowMask[]
#define DEFAULT_SIZE
#define HANDLE_ID
#define SORT_COLUMN_NONE
#define BROW_COLUMNALIAS_ROW
#define BROW_FUNCTION_ROW
#define BROW_CRIT2_ROW
#define BROW_ROW_CNT
#define BROW_FIELD_ROW
#define BROW_ORDER_ROW
#define BROW_TABLE_ROW
#define BROW_CRIT1_ROW
#define BROW_VIS_ROW
#define ID_BROWSER_UNDO
Definition: browserids.hxx:35
#define ID_BROWSER_REDO
Definition: browserids.hxx:31
#define ID_BROWSER_QUERY_EXECUTE
Definition: browserids.hxx:90
#define BROWSER_INVALIDID
BrowserMode
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
void RowRemoved(sal_Int32 nRow, sal_Int32 nNumRows=1, bool bDoPaint=true)
tools::Long GetDataRowHeight() const
sal_uInt16 GetColumnId(sal_uInt16 nPos) const
void SetUpdateMode(bool bUpdate)
virtual void Command(const CommandEvent &rEvt) override
BrowserDataWin & GetDataWindow() const
void InsertDataColumn(sal_uInt16 nItemId, const OUString &rText, tools::Long nSize, HeaderBarItemBits nBits=HeaderBarItemBits::STDSTYLE, sal_uInt16 nPos=HEADERBAR_APPEND)
tools::Long GetTitleHeight() const
sal_Int32 FirstSelectedColumn() const
void SetTitleFont(const vcl::Font &rNewFont)
bool GoToRow(sal_Int32 nRow)
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessibleCell(sal_Int32 nRow, sal_uInt16 nColumnPos) override
sal_Int32 GetCurRow() const
sal_uInt16 GetSelectColumnCount() const
void SetColumnPos(sal_uInt16 nColumnId, sal_uInt16 nPos)
sal_Int32 GetRowAtYPosPixel(tools::Long nY, bool bRelToBrowser=true) const
sal_uInt16 ColCount() const
void InsertHandleColumn(sal_uLong nWidth)
void RowModified(sal_Int32 nRow, sal_uInt16 nColId=BROWSER_INVALIDID)
void SetMode(BrowserMode nMode)
void SetColumnWidth(sal_uInt16 nColumnId, sal_uLong nWidth)
sal_uInt16 GetColumnPos(sal_uInt16 nColumnId) const
void RemoveColumn(sal_uInt16 nColumnId)
void SelectColumnId(sal_uInt16 nColId)
const DataFlavorExVector & GetDataFlavors() const
virtual OUString GetAccessibleObjectDescription(AccessibleBrowseBoxObjType eObjType, sal_Int32 _nPosition=-1) const override
sal_uInt16 GetCurColumnId() const
tools::Rectangle GetFieldRectPixel(sal_Int32 nRow, sal_uInt16 nColId, bool bRelToBrowser=true) const
const vcl::Font & GetFont() const
void SetDataRowHeight(tools::Long nPixel)
void RowInserted(sal_Int32 nRow, sal_Int32 nNumRows=1, bool bDoPaint=true, bool bKeepSelection=false)
sal_uInt16 GetColumnAtXPosPixel(tools::Long nX) const
virtual sal_Int32 GetRowCount() const override
virtual void SetNoSelection() override
void SetTitleLines(sal_uInt16 nLines)
bool IsColumnSelected(sal_uInt16 nColumnId) const
sal_uLong GetColumnWidth(sal_uInt16 nColumnId) const
void RemoveColumns()
void SetHeaderBar(BrowserHeader *)
sal_Int32 GetRow() const
sal_uInt16 GetColumnId() const
virtual void dispose() override
CommandEventId GetCommand() const
const Point & GetMousePosPixel() const
bool IsMouseEvent() const
const vcl::KeyCode & GetKeyCode() const
void SetClipRegion()
static vcl::Font GetDefaultFont(DefaultFontType nType, LanguageType eLang, GetDefaultFontFlags nFlags, const OutputDevice *pOutDev=nullptr)
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
constexpr tools::Long Y() const
tools::Long AdjustY(tools::Long nVertMove)
constexpr tools::Long X() const
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
constexpr tools::Long Height() const
tools::Long AdjustHeight(tools::Long n)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
bool IsActive() const
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
const DataFlavorExVector & GetDataFlavorExVector() const
void clear()
static VclPtr< reference_type > Create(Arg &&... arg)
virtual OString getIntlKeywordAscii(InternationalKeyCode _eKey) const=0
void parseNodeToStr(OUString &rString, const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, const IParseContext *pContext=nullptr, bool _bIntl=false, bool _bQuote=true) const
sal_uInt32 getTokenID() const
OSQLParseNode * getChild(sal_uInt32 nPos) const
static OUString getColumnAlias(const OSQLParseNode *_pDerivedColumn)
void getColumnRange(const OSQLParseNode *_pColumnRef, OUString &_rColumnName, OUString &_rTableRange) const
std::unique_ptr< OSQLParseNode > predicateTree(OUString &rErrorMessage, const OUString &rStatement, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const css::uno::Reference< css::beans::XPropertySet > &xField, bool bUseRealName=true)
std::unique_ptr< OSQLParseNode > parseTree(OUString &rErrorMessage, const OUString &rStatement, bool bInternational=false)
const IParseContext & getContext() const
OJoinTableView * getTableView() const
OJoinController & getController() const
static bool isFormatAvailable(const DataFlavorExVector &_rFormats, SotClipboardFormatId _nSlotID=SotClipboardFormatId::SBA_JOIN)
static OJoinExchangeData GetSourceDescription(const css::uno::Reference< css::datatransfer::XTransferable > &_rxObject)
std::map< OUString, VclPtr< OTableWindow > > OTableWindowMap
OTableWindowMap & GetTabWinMap()
::connectivity::OSQLParser & getParser()
OTableFields & getTableFieldDesc()
void fillFunctionInfo(const ::connectivity::OSQLParseNode *pNode, const OUString &sFunctionTerm, OTableFieldDescRef &aInfo)
const OUString & getDecimalSeparator() const
std::unique_ptr<::connectivity::OSQLParseNode > getPredicateTreeFromEntry(const OTableFieldDescRef &pEntry, const OUString &_sCriteria, OUString &_rsErrorMessage, css::uno::Reference< css::beans::XPropertySet > &_rxColumn) const
const css::lang::Locale & getLocale() const
void fillValidFields(std::u16string_view strTableName, weld::ComboBox &rFieldList)
bool FindTableFromField(const OUString &rFieldName, OTableFieldDescRef const &rInfo, sal_uInt16 &rCnt)
OUString const & GetAliasName() const
bool saveField(OUString &_sFieldName, OTableFieldDescRef const &_pEntry, bool &_bListAction)
save the field change in save modified
sal_Int32 GetBrowseRow(sal_Int32 nRowId) const
tools::Rectangle GetInvalidRect(sal_uInt16 nColId)
void SetColWidth(sal_uInt16 nColId, tools::Long lNewWidth)
virtual VclPtr< BrowserHeader > imp_CreateHeaderBar(BrowseBox *pParent) override
OTableFieldDescRef InsertField(const OJoinExchangeData &jxdSource)
virtual ::svt::CellController * GetController(sal_Int32 nRow, sal_uInt16 nCol) override
virtual void CellModified() override
void SetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId, const OUString &strNewText)
void RemoveColumn(sal_uInt16 _nColumnId)
OTableFieldDescRef FindFirstFreeCol(sal_uInt16 &_rColumnPosition)
virtual OUString GetCellText(sal_Int32 _nRow, sal_uInt16 _nColId) const override
GetCellText returns the text at the given position.
void AddCondition(const OTableFieldDescRef &rInfo, const OUString &rValue, const sal_uInt16 nLevel, bool _bAddOrOnOneLine)
void AddGroupBy(const OTableFieldDescRef &rInfo)
virtual OUString GetAccessibleObjectName(AccessibleBrowseBoxObjType eObjType, sal_Int32 _nPosition=-1) const override
return the name of the specified object.
OQueryDesignView * getDesignView()
virtual sal_uInt32 GetTotalCellWidth(sal_Int32 nRow, sal_uInt16 nColId) override
void DuplicateConditionLevel(const sal_uInt16 nLevel)
void CheckFreeColumns(sal_uInt16 &_rColumnPosition)
bool fillColumnRef(const ::connectivity::OSQLParseNode *_pColumnRef, const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, OTableFieldDescRef const &_pEntry, bool &_bListAction)
uses the parse node to fill all information into the field
virtual void Command(const CommandEvent &rEvt) override
VclPtr< ::svt::CheckBoxControl > m_pVisibleCell
bool GetFunctionName(sal_uInt32 _nFunctionTokenId, OUString &rFkt)
void DeleteFields(const OUString &rAliasName)
void appendUndoAction(const OUString &_rOldValue, std::u16string_view _rNewValue, sal_Int32 _nRow, bool &_bListAction)
virtual void KeyInput(const KeyEvent &rEvt) override
OTableFields & getFields() const
virtual void GetFocus() override
void InsertColumn(const OTableFieldDescRef &pEntry, sal_uInt16 &_nColumnPosition)
virtual void ColumnResized(sal_uInt16 nColId) override
void setFunctionCell(OTableFieldDescRef const &_pEntry)
remove or insert the necessary function types
VclPtr< ::svt::ListBoxControl > m_pTableCell
virtual bool SeekRow(sal_Int32 nRow) override
VclPtr< ::svt::ComboBoxControl > m_pFieldCell
bool HasFieldByAliasName(std::u16string_view rFieldName, OTableFieldDescRef const &rInfo) const
static void enableControl(const OTableFieldDescRef &_rEntry, Window *_pControl)
void setTextCellContext(const OTableFieldDescRef &_rEntry, const OUString &_sText, const OUString &_sHelpId)
virtual void MouseButtonUp(const BrowserMouseEvent &rEvt) override
virtual sal_Int8 AcceptDrop(const BrowserAcceptDropEvent &rEvt) override
virtual void dispose() override
virtual void PaintStatusCell(OutputDevice &rDev, const tools::Rectangle &rRect) const override
OUString GetCellContents(sal_Int32 nCellIndex, sal_uInt16 nColId)
void notifyTableFieldChanged(const OUString &_sOldAlias, std::u16string_view _sAlias, bool &_bListAction, sal_uInt16 _nColumnId)
append an undo action for the table field
void SetNoneVisibleRow(sal_Int32 nRows)
VclPtr< ::svt::ListBoxControl > m_pFunctionCell
OTableFieldDescRef const & AppendNewCol(sal_uInt16 nCnt=1)
std::vector< bool > m_bVisibleRow
VclPtr< ::svt::ListBoxControl > m_pOrderCell
virtual void InitController(::svt::CellControllerRef &rController, sal_Int32 nRow, sal_uInt16 nCol) override
virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessibleCell(sal_Int32 nRow, sal_uInt16 nColumnId) override
Creates the accessible object of a data table cell.
virtual sal_Int8 ExecuteDrop(const BrowserExecuteDropEvent &rEvt) override
virtual bool SaveModified() override
bool IsRowVisible(sal_uInt16 _nWhich) const
void adjustSelectionMode(bool _bClickedOntoHeader, bool _bClickedOntoHandleCol)
Size CalcOptimalSize(const Size &_rAvailable)
void SetRowVisible(sal_uInt16 _nWhich, bool _bVis)
VclPtr< ::svt::EditControl > m_pTextCell
void AddOrder(const OTableFieldDescRef &rInfo, const EOrderDir eDir, sal_uInt32 _nCurrentPos)
sal_Int32 GetRealRow(sal_Int32 nRow) const
virtual ~OSelectionBrowseBox() override
virtual void ColumnMoved(sal_uInt16 nColId) override
void RemoveField(sal_uInt16 nId)
virtual void MouseButtonDown(const BrowserMouseEvent &rEvt) override
void notifyFunctionFieldChanged(const OUString &_sOldFunctionName, std::u16string_view _sFunctionName, bool &_bListAction, sal_uInt16 _nColumnId)
append an undo action for the function field
bool fillEntryTable(OTableFieldDescRef const &_pEntry, const OUString &_sTableName)
sets the table window at the _pEntry
virtual OUString GetRowDescription(sal_Int32 _nRow) const override
returns the description of the row.
virtual void Init() override
virtual void DeactivateCell(bool bUpdate=true) override
void clearEntryFunctionField(std::u16string_view _sFieldName, OTableFieldDescRef const &_pEntry, bool &_bListAction, sal_uInt16 _nColumnId)
clears the function fields of the submitted entry if it doesn't match the SQL standard and append an ...
virtual void PaintCell(OutputDevice &rDev, const tools::Rectangle &rRect, sal_uInt16 nColumnId) const override
OTableFieldDescRef getEntry(OTableFields::size_type _nPos)
SfxUndoManager & GetUndoManager() const
need for undo's and redo's
void addUndoActionAndInvalidate(std::unique_ptr< SfxUndoAction > pAction)
addUndoActionAndInvalidate adds an undo action to the undoManager, additionally invalidates the UNDO ...
sal_Int32 GetDataType() const
ETableFieldType GetKeyType() const
OUString const & GetTableName() const
css::uno::Reference< css::accessibility::XAccessible > CreateAccessibleCheckBoxCell(sal_Int32 _nRow, sal_uInt16 _nColumnPos, const TriState &eState)
virtual void ColumnResized(sal_uInt16 nColId) override
tools::Rectangle GetCellRect(sal_Int32 nRow, sal_uInt16 nColId, bool bRelToBrowser=true) const
bool IsEditing() const
virtual void DeactivateCell(bool bUpdate=true)
virtual void MouseButtonDown(const BrowserMouseEvent &rEvt) override
const CellControllerRef & Controller() const
virtual void KeyInput(const KeyEvent &rEvt) override
virtual VclPtr< BrowserHeader > CreateHeaderBar(BrowseBox *pParent) override
virtual void ColumnMoved(sal_uInt16 nId) override
void PaintTristate(const tools::Rectangle &rRect, const TriState &eState, bool _bEnabled=true) const
virtual void Init()
virtual void MouseButtonUp(const BrowserMouseEvent &rEvt) override
virtual bool IsModified() const
virtual void GetFocus() override
virtual void dispose() override
constexpr void SetLeft(tools::Long v)
constexpr Point TopLeft() const
constexpr Point TopCenter() const
constexpr tools::Long Left() const
void SetFontSize(const Size &)
void SetWeight(FontWeight)
bool IsMod1() const
sal_uInt16 GetCode() const
bool IsShift() const
void Enable(bool bEnable=true, bool bChild=true)
const AllSettings & GetSettings() const
weld::Window * GetFrameWeld() const
void EnableInput(bool bEnable=true, bool bChild=true)
virtual int find_text(const OUString &rStr) const=0
virtual void copy_entry_clipboard()=0
virtual OUString get_active_text() const=0
virtual void clear()=0
virtual void set_entry_text(const OUString &rStr)=0
virtual void set_active(int pos)=0
virtual OUString get_text(int pos) const=0
virtual void cut_entry_clipboard()=0
void append_text(const OUString &rStr)
void insert_text(int pos, const OUString &rStr)
virtual void remove(int pos)=0
virtual int get_active() const=0
virtual int get_count() const=0
virtual void paste_entry_clipboard()=0
void set_active_text(const OUString &rStr)
virtual bool get_entry_selection_bounds(int &rStartPos, int &rEndPos)=0
virtual short run()
virtual void cut_clipboard()=0
virtual void set_text(const OUString &rText)=0
void save_value()
virtual bool get_selection_bounds(int &rStartPos, int &rEndPos)=0
virtual void copy_clipboard()=0
virtual void paste_clipboard()=0
virtual OUString get_text(int row, int col=-1) const=0
virtual OUString get_id(int pos) const=0
#define DBA_RES(id)
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
virtual void SetHelpId(const OUString &) override
float u
EditBrowseBoxFlags
WEIGHT_NORMAL
Reference< XColumn > xColumn
TRISTATE_FALSE
TRISTATE_TRUE
#define WB_BUTTONSTYLE
constexpr OUStringLiteral HID_QRYDGN_ROW_FUNCTION
Definition: helpids.h:39
constexpr OUStringLiteral HID_CTL_QRYDGNCRIT
Definition: helpids.h:34
constexpr OUStringLiteral HID_QRYDGN_ROW_ORDER
Definition: helpids.h:38
constexpr OUStringLiteral HID_QRYDGN_ROW_VISIBLE
Definition: helpids.h:35
constexpr OUStringLiteral HID_QRYDGN_ROW_ALIAS
Definition: helpids.h:40
constexpr OUStringLiteral HID_QRYDGN_ROW_TABLE
Definition: helpids.h:36
constexpr OUStringLiteral HID_QRYDGN_ROW_FIELD
Definition: helpids.h:37
constexpr OUStringLiteral HID_QRYDGN_ROW_CRIT
Definition: helpids.h:41
constexpr sal_uInt16 KEY_DELETE
sal_uInt16 nPos
size
@ Exception
const LanguageTag & getLocale()
OString stripStart(const OString &rIn, char c)
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
::rtl::Reference< OTableFieldDesc > OTableFieldDescRef
IMPL_LINK_NOARG(OApplicationController, OnClipboardChanged, TransferableDataHelper *, void)
void adjustBrowseBoxColumnWidth(::svt::EditBrowseBox *_pBox, sal_uInt16 _nColId)
Definition: UITools.cxx:928
css::uno::Reference< css::util::XNumberFormatter > getNumberFormatter(const css::uno::Reference< css::sdbc::XConnection > &_rxConnection, const css::uno::Reference< css::uno::XComponentContext > &_rxContext)
creates a number formatter
@ ORDER_NONE
Definition: QEnumTypes.hxx:25
@ FKT_OTHER
Definition: QEnumTypes.hxx:33
@ FKT_NONE
Definition: QEnumTypes.hxx:32
@ FKT_NUMERIC
Definition: QEnumTypes.hxx:36
@ FKT_AGGREGATE
Definition: QEnumTypes.hxx:34
@ TAB_NORMAL_FIELD
Definition: QEnumTypes.hxx:49
std::vector< OTableFieldDescRef > OTableFields
Reference< XConnection > getConnection(const Reference< XRowSet > &_rxRowSet)
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
enumrange< T >::Iterator begin(enumrange< T >)
end
void dispose()
long Long
weld::Window * GetPopupParent(vcl::Window &rOutWin, tools::Rectangle &rRect)
sal_Int16 nId
DefTokenId nToken
QPRO_FUNC_TYPE nType
#define SQL_ISRULE(pParseNode, eRule)
#define SQL_ISPUNCTUATION(pParseNode, aString)
#define SQL_ISRULEOR3(pParseNode, e1, e2, e3)
constexpr OUStringLiteral PROPERTY_TYPE(u"Type")
VclPtr< OTableWindowListBox > pListBox
#define DND_ACTION_LINK
#define DND_ACTION_NONE
signed char sal_Int8
OUString aLabel
WinBits const WB_DRAG
WinBits const WB_3DLOOK
sal_Int32 _nPos