GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / sc / source / ui / view / dbfunc.cxx
blobe5ebd37a6e9c58c1284903a864dd2e49d3107d6e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <sfx2/app.hxx>
22 #include <sfx2/bindings.hxx>
23 #include <vcl/msgbox.hxx>
25 #include <com/sun/star/sdbc/XResultSet.hpp>
27 #include "dbfunc.hxx"
28 #include "docsh.hxx"
29 #include "attrib.hxx"
30 #include "sc.hrc"
31 #include "undodat.hxx"
32 #include "dbdata.hxx"
33 #include "globstr.hrc"
34 #include "global.hxx"
35 #include "dbdocfun.hxx"
36 #include "editable.hxx"
37 #include "queryentry.hxx"
38 #include "markdata.hxx"
40 //==================================================================
42 ScDBFunc::ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
43 ScViewFunc( pParent, rDocSh, pViewShell )
47 ScDBFunc::~ScDBFunc()
52 // auxiliary functions
55 void ScDBFunc::GotoDBArea( const OUString& rDBName )
57 ScDocument* pDoc = GetViewData()->GetDocument();
58 ScDBCollection* pDBCol = pDoc->GetDBCollection();
59 ScDBData* pData = pDBCol->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(rDBName));
60 if (pData)
62 SCTAB nTab = 0;
63 SCCOL nStartCol = 0;
64 SCROW nStartRow = 0;
65 SCCOL nEndCol = 0;
66 SCROW nEndRow = 0;
68 pData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
69 SetTabNo( nTab );
71 MoveCursorAbs( nStartCol, nStartRow, ScFollowMode( SC_FOLLOW_JUMP ),
72 false, false ); // bShift,bControl
73 DoneBlockMode();
74 InitBlockMode( nStartCol, nStartRow, nTab );
75 MarkCursor( nEndCol, nEndRow, nTab );
76 SelectionChanged();
80 // search current datarange for sort / filter
82 ScDBData* ScDBFunc::GetDBData( bool bMark, ScGetDBMode eMode, ScGetDBSelection eSel )
84 ScDocShell* pDocSh = GetViewData()->GetDocShell();
85 ScDBData* pData = NULL;
86 ScRange aRange;
87 ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
88 if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
90 bool bShrinkColumnsOnly = false;
91 if (eSel == SC_DBSEL_ROW_DOWN)
93 // Don't alter row range, additional rows may have been selected on
94 // purpose to append data, or to have a fake header row.
95 bShrinkColumnsOnly = true;
96 // Select further rows only if only one row or a portion thereof is
97 // selected.
98 if (aRange.aStart.Row() != aRange.aEnd.Row())
100 // If an area is selected shrink that to the actual used
101 // columns, don't draw filter buttons for empty columns.
102 eSel = SC_DBSEL_SHRINK_TO_USED_DATA;
104 else if (aRange.aStart.Col() == aRange.aEnd.Col())
106 // One cell only, if it is not marked obtain entire used data
107 // area.
108 const ScMarkData& rMarkData = GetViewData()->GetMarkData();
109 if (!(rMarkData.IsMarked() || rMarkData.IsMultiMarked()))
110 eSel = SC_DBSEL_KEEP;
113 switch (eSel)
115 case SC_DBSEL_SHRINK_TO_SHEET_DATA:
117 // Shrink the selection to sheet data area.
118 ScDocument* pDoc = pDocSh->GetDocument();
119 SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
120 SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
121 if (pDoc->ShrinkToDataArea( aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
123 aRange.aStart.SetCol(nCol1);
124 aRange.aEnd.SetCol(nCol2);
125 aRange.aStart.SetRow(nRow1);
126 aRange.aEnd.SetRow(nRow2);
129 break;
130 case SC_DBSEL_SHRINK_TO_USED_DATA:
131 case SC_DBSEL_ROW_DOWN:
133 // Shrink the selection to actual used area.
134 ScDocument* pDoc = pDocSh->GetDocument();
135 SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
136 SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
137 bool bShrunk;
138 pDoc->ShrinkToUsedDataArea( bShrunk, aRange.aStart.Tab(),
139 nCol1, nRow1, nCol2, nRow2, bShrinkColumnsOnly);
140 if (bShrunk)
142 aRange.aStart.SetCol(nCol1);
143 aRange.aEnd.SetCol(nCol2);
144 aRange.aStart.SetRow(nRow1);
145 aRange.aEnd.SetRow(nRow2);
148 break;
149 default:
150 ; // nothing
152 pData = pDocSh->GetDBData( aRange, eMode, eSel );
154 else if ( eMode != SC_DB_OLD )
155 pData = pDocSh->GetDBData(
156 ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
157 GetViewData()->GetTabNo() ),
158 eMode, SC_DBSEL_KEEP );
160 if (!pData)
161 return NULL;
163 if (bMark)
165 ScRange aFound;
166 pData->GetArea(aFound);
167 MarkRange( aFound, false );
169 return pData;
172 ScDBData* ScDBFunc::GetAnonymousDBData()
174 ScDocShell* pDocSh = GetViewData()->GetDocShell();
175 ScRange aRange;
176 ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
177 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
178 return NULL;
180 // Expand to used data area if not explicitly marked.
181 const ScMarkData& rMarkData = GetViewData()->GetMarkData();
182 if (!rMarkData.IsMarked() && !rMarkData.IsMultiMarked())
184 SCCOL nCol1 = aRange.aStart.Col();
185 SCCOL nCol2 = aRange.aEnd.Col();
186 SCROW nRow1 = aRange.aStart.Row();
187 SCROW nRow2 = aRange.aEnd.Row();
188 pDocSh->GetDocument()->GetDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2, false, false);
189 aRange.aStart.SetCol(nCol1);
190 aRange.aStart.SetRow(nRow1);
191 aRange.aEnd.SetCol(nCol2);
192 aRange.aEnd.SetRow(nRow2);
195 return pDocSh->GetAnonymousDBData(aRange);
198 // change database range (dialog)
200 void ScDBFunc::NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const std::vector<ScRange> &rDelAreaList )
203 ScDocShell* pDocShell = GetViewData()->GetDocShell();
204 ScDocShellModificator aModificator( *pDocShell );
205 ScDocument* pDoc = pDocShell->GetDocument();
206 ScDBCollection* pOldColl = pDoc->GetDBCollection();
207 ScDBCollection* pUndoColl = NULL;
208 const sal_Bool bRecord (pDoc->IsUndoEnabled());
210 std::vector<ScRange>::const_iterator iter;
211 for (iter = rDelAreaList.begin(); iter != rDelAreaList.end(); ++iter)
213 // unregistering target in SBA no longer necessary
214 const ScAddress& rStart = iter->aStart;
215 const ScAddress& rEnd = iter->aEnd;
216 pDocShell->DBAreaDeleted( rStart.Tab(),
217 rStart.Col(), rStart.Row(),
218 rEnd.Col(), rEnd.Row() );
222 if (bRecord)
223 pUndoColl = new ScDBCollection( *pOldColl );
225 // register target in SBA no longer necessary
227 pDoc->CompileDBFormula( sal_True ); // CreateFormulaString
228 pDoc->SetDBCollection( new ScDBCollection( rNewColl ) );
229 pDoc->CompileDBFormula( false ); // CompileFormulaString
230 pOldColl = NULL;
231 pDocShell->PostPaint(ScRange(0, 0, 0, MAXCOL, MAXROW, MAXTAB), PAINT_GRID);
232 aModificator.SetDocumentModified();
233 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
235 if (bRecord)
237 ScDBCollection* pRedoColl = new ScDBCollection( rNewColl );
238 pDocShell->GetUndoManager()->AddUndoAction(
239 new ScUndoDBData( pDocShell, pUndoColl, pRedoColl ) );
244 // main functions
247 // Sort
249 void ScDBFunc::UISort( const ScSortParam& rSortParam, sal_Bool bRecord )
251 ScDocShell* pDocSh = GetViewData()->GetDocShell();
252 ScDocument* pDoc = pDocSh->GetDocument();
253 SCTAB nTab = GetViewData()->GetTabNo();
254 ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
255 rSortParam.nCol2, rSortParam.nRow2 );
256 if (!pDBData)
258 OSL_FAIL( "Sort: no DBData" );
259 return;
262 ScSubTotalParam aSubTotalParam;
263 pDBData->GetSubTotalParam( aSubTotalParam );
264 if (aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly)
266 // repeat subtotals, with new sortorder
268 DoSubTotals( aSubTotalParam, bRecord, &rSortParam );
270 else
272 Sort( rSortParam, bRecord ); // just sort
276 void ScDBFunc::Sort( const ScSortParam& rSortParam, sal_Bool bRecord, sal_Bool bPaint )
278 ScDocShell* pDocSh = GetViewData()->GetDocShell();
279 SCTAB nTab = GetViewData()->GetTabNo();
280 ScDBDocFunc aDBDocFunc( *pDocSh );
281 sal_Bool bSuccess = aDBDocFunc.Sort( nTab, rSortParam, bRecord, bPaint, false );
282 if ( bSuccess && !rSortParam.bInplace )
284 // mark target
285 ScRange aDestRange( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab,
286 rSortParam.nDestCol + rSortParam.nCol2 - rSortParam.nCol1,
287 rSortParam.nDestRow + rSortParam.nRow2 - rSortParam.nRow1,
288 rSortParam.nDestTab );
289 MarkRange( aDestRange );
292 ResetAutoSpell();
295 // filters
297 void ScDBFunc::Query( const ScQueryParam& rQueryParam, const ScRange* pAdvSource, sal_Bool bRecord )
299 ScDocShell* pDocSh = GetViewData()->GetDocShell();
300 SCTAB nTab = GetViewData()->GetTabNo();
301 ScDBDocFunc aDBDocFunc( *pDocSh );
302 sal_Bool bSuccess = aDBDocFunc.Query( nTab, rQueryParam, pAdvSource, bRecord, false );
304 if (bSuccess)
306 sal_Bool bCopy = !rQueryParam.bInplace;
307 if (bCopy)
309 // mark target range (data base range has been set up if applicable)
310 ScDocument* pDoc = pDocSh->GetDocument();
311 ScDBData* pDestData = pDoc->GetDBAtCursor(
312 rQueryParam.nDestCol, rQueryParam.nDestRow,
313 rQueryParam.nDestTab, sal_True );
314 if (pDestData)
316 ScRange aDestRange;
317 pDestData->GetArea(aDestRange);
318 MarkRange( aDestRange );
322 if (!bCopy)
324 UpdateScrollBars();
325 SelectionChanged(); // for attribute states (filtered rows are ignored)
328 GetViewData()->GetBindings().Invalidate( SID_UNFILTER );
332 // autofilter-buttons show / hide
334 void ScDBFunc::ToggleAutoFilter()
336 ScDocShell* pDocSh = GetViewData()->GetDocShell();
337 ScDocShellModificator aModificator( *pDocSh );
339 ScQueryParam aParam;
340 ScDocument* pDoc = GetViewData()->GetDocument();
341 ScDBData* pDBData = GetDBData(false, SC_DB_MAKE, SC_DBSEL_ROW_DOWN);
343 pDBData->SetByRow( sal_True ); //! undo, retrieve beforehand ??
344 pDBData->GetQueryParam( aParam );
347 SCCOL nCol;
348 SCROW nRow = aParam.nRow1;
349 SCTAB nTab = GetViewData()->GetTabNo();
350 sal_Int16 nFlag;
351 sal_Bool bHasAuto = sal_True;
352 sal_Bool bHeader = pDBData->HasHeader();
353 sal_Bool bPaint = false;
355 //! instead retrieve from DB-range?
357 for (nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAuto; nCol++)
359 nFlag = ((ScMergeFlagAttr*) pDoc->
360 GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
362 if ( (nFlag & SC_MF_AUTO) == 0 )
363 bHasAuto = false;
366 if (bHasAuto) // remove
368 // hide filter buttons
370 for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
372 nFlag = ((ScMergeFlagAttr*) pDoc->
373 GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
374 pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
377 // use a list action for the AutoFilter buttons (ScUndoAutoFilter) and the filter operation
379 OUString aUndo = ScGlobal::GetRscString( STR_UNDO_QUERY );
380 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
382 ScRange aRange;
383 pDBData->GetArea( aRange );
384 pDocSh->GetUndoManager()->AddUndoAction(
385 new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), false ) );
387 pDBData->SetAutoFilter(false);
389 // remove filter (incl. Paint / Undo)
391 SCSIZE nEC = aParam.GetEntryCount();
392 for (SCSIZE i=0; i<nEC; i++)
393 aParam.GetEntry(i).bDoQuery = false;
394 aParam.bDuplicate = sal_True;
395 Query( aParam, NULL, sal_True );
397 pDocSh->GetUndoManager()->LeaveListAction();
399 bPaint = sal_True;
401 else // show filter buttons
403 if ( !pDoc->IsBlockEmpty( nTab,
404 aParam.nCol1, aParam.nRow1,
405 aParam.nCol2, aParam.nRow2 ) )
407 if (!bHeader)
409 if ( MessBox( GetViewData()->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
410 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), // "StarCalc"
411 ScGlobal::GetRscString( STR_MSSG_MAKEAUTOFILTER_0 ) // header from first row?
412 ).Execute() == RET_YES )
414 pDBData->SetHeader( sal_True ); //! Undo ??
415 bHeader = sal_True;
419 ScRange aRange;
420 pDBData->GetArea( aRange );
421 pDocSh->GetUndoManager()->AddUndoAction(
422 new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), sal_True ) );
424 pDBData->SetAutoFilter(sal_True);
426 for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
428 nFlag = ((ScMergeFlagAttr*) pDoc->
429 GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
430 pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag | SC_MF_AUTO ) );
432 pDocSh->PostPaint(ScRange(aParam.nCol1, nRow, nTab, aParam.nCol2, nRow, nTab),
433 PAINT_GRID);
434 bPaint = sal_True;
436 else
438 ErrorBox aErrorBox( GetViewData()->GetDialogParent(), WinBits( WB_OK | WB_DEF_OK ),
439 ScGlobal::GetRscString( STR_ERR_AUTOFILTER ) );
440 aErrorBox.Execute();
444 if ( bPaint )
446 aModificator.SetDocumentModified();
448 SfxBindings& rBindings = GetViewData()->GetBindings();
449 rBindings.Invalidate( SID_AUTO_FILTER );
450 rBindings.Invalidate( SID_AUTOFILTER_HIDE );
454 // just hide, no data change
456 void ScDBFunc::HideAutoFilter()
458 ScDocShell* pDocSh = GetViewData()->GetDocShell();
459 ScDocShellModificator aModificator( *pDocSh );
461 ScDocument* pDoc = pDocSh->GetDocument();
463 ScQueryParam aParam;
464 ScDBData* pDBData = GetDBData( false );
466 SCTAB nTab;
467 SCCOL nCol1, nCol2;
468 SCROW nRow1, nRow2;
469 pDBData->GetArea(nTab, nCol1, nRow1, nCol2, nRow2);
471 for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
473 sal_Int16 nFlag = ((ScMergeFlagAttr*) pDoc->
474 GetAttr( nCol, nRow1, nTab, ATTR_MERGE_FLAG ))->GetValue();
475 pDoc->ApplyAttr( nCol, nRow1, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
478 ScRange aRange;
479 pDBData->GetArea( aRange );
480 pDocSh->GetUndoManager()->AddUndoAction(
481 new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), false ) );
483 pDBData->SetAutoFilter(false);
485 pDocSh->PostPaint(ScRange(nCol1, nRow1, nTab, nCol2, nRow1, nTab), PAINT_GRID );
486 aModificator.SetDocumentModified();
488 SfxBindings& rBindings = GetViewData()->GetBindings();
489 rBindings.Invalidate( SID_AUTO_FILTER );
490 rBindings.Invalidate( SID_AUTOFILTER_HIDE );
493 // Re-Import
495 sal_Bool ScDBFunc::ImportData( const ScImportParam& rParam, sal_Bool bRecord )
497 ScDocument* pDoc = GetViewData()->GetDocument();
498 ScEditableTester aTester( pDoc, GetViewData()->GetTabNo(), rParam.nCol1,rParam.nRow1,
499 rParam.nCol2,rParam.nRow2 );
500 if ( !aTester.IsEditable() )
502 ErrorMessage(aTester.GetMessageId());
503 return false;
506 ScDBDocFunc aDBDocFunc( *GetViewData()->GetDocShell() );
507 return aDBDocFunc.DoImport( GetViewData()->GetTabNo(), rParam, NULL, bRecord );
512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */