LCOV - code coverage report
Current view: top level - sc/source/ui/view - dbfunc.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 20 227 8.8 %
Date: 2015-06-13 12:38:46 Functions: 5 14 35.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "scitems.hxx"
      21             : #include <sfx2/app.hxx>
      22             : #include <sfx2/bindings.hxx>
      23             : #include <vcl/msgbox.hxx>
      24             : 
      25             : #include <com/sun/star/sdbc/XResultSet.hpp>
      26             : 
      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"
      39             : 
      40         348 : ScDBFunc::ScDBFunc( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
      41         348 :     ScViewFunc( pParent, rDocSh, pViewShell )
      42             : {
      43         348 : }
      44             : 
      45         345 : ScDBFunc::~ScDBFunc()
      46             : {
      47         345 : }
      48             : 
      49             : //      auxiliary functions
      50             : 
      51           0 : void ScDBFunc::GotoDBArea( const OUString& rDBName )
      52             : {
      53           0 :     ScDocument* pDoc = GetViewData().GetDocument();
      54           0 :     ScDBCollection* pDBCol = pDoc->GetDBCollection();
      55           0 :     ScDBData* pData = pDBCol->getNamedDBs().findByUpperName(ScGlobal::pCharClass->uppercase(rDBName));
      56           0 :     if (pData)
      57             :     {
      58           0 :         SCTAB nTab = 0;
      59           0 :         SCCOL nStartCol = 0;
      60           0 :         SCROW nStartRow = 0;
      61           0 :         SCCOL nEndCol = 0;
      62           0 :         SCROW nEndRow = 0;
      63             : 
      64           0 :         pData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
      65           0 :         SetTabNo( nTab );
      66             : 
      67             :         MoveCursorAbs( nStartCol, nStartRow, ScFollowMode( SC_FOLLOW_JUMP ),
      68           0 :                        false, false );  // bShift,bControl
      69           0 :         DoneBlockMode();
      70           0 :         InitBlockMode( nStartCol, nStartRow, nTab );
      71           0 :         MarkCursor( nEndCol, nEndRow, nTab );
      72           0 :         SelectionChanged();
      73             :     }
      74           0 : }
      75             : 
      76             : //  search current datarange for sort / filter
      77             : 
      78           0 : ScDBData* ScDBFunc::GetDBData( bool bMark, ScGetDBMode eMode, ScGetDBSelection eSel )
      79             : {
      80           0 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
      81           0 :     ScDBData* pData = NULL;
      82           0 :     ScRange aRange;
      83           0 :     ScMarkType eMarkType = GetViewData().GetSimpleArea(aRange);
      84           0 :     if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
      85             :     {
      86           0 :         bool bShrinkColumnsOnly = false;
      87           0 :         if (eSel == SC_DBSEL_ROW_DOWN)
      88             :         {
      89             :             // Don't alter row range, additional rows may have been selected on
      90             :             // purpose to append data, or to have a fake header row.
      91           0 :             bShrinkColumnsOnly = true;
      92             :             // Select further rows only if only one row or a portion thereof is
      93             :             // selected.
      94           0 :             if (aRange.aStart.Row() != aRange.aEnd.Row())
      95             :             {
      96             :                 // If an area is selected shrink that to the actual used
      97             :                 // columns, don't draw filter buttons for empty columns.
      98           0 :                 eSel = SC_DBSEL_SHRINK_TO_USED_DATA;
      99             :             }
     100           0 :             else if (aRange.aStart.Col() == aRange.aEnd.Col())
     101             :             {
     102             :                 // One cell only, if it is not marked obtain entire used data
     103             :                 // area.
     104           0 :                 const ScMarkData& rMarkData = GetViewData().GetMarkData();
     105           0 :                 if (!(rMarkData.IsMarked() || rMarkData.IsMultiMarked()))
     106           0 :                     eSel = SC_DBSEL_KEEP;
     107             :             }
     108             :         }
     109           0 :         switch (eSel)
     110             :         {
     111             :             case SC_DBSEL_SHRINK_TO_SHEET_DATA:
     112             :                 {
     113             :                     // Shrink the selection to sheet data area.
     114           0 :                     ScDocument& rDoc = pDocSh->GetDocument();
     115           0 :                     SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
     116           0 :                     SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
     117           0 :                     if (rDoc.ShrinkToDataArea( aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
     118             :                     {
     119           0 :                         aRange.aStart.SetCol(nCol1);
     120           0 :                         aRange.aEnd.SetCol(nCol2);
     121           0 :                         aRange.aStart.SetRow(nRow1);
     122           0 :                         aRange.aEnd.SetRow(nRow2);
     123             :                     }
     124             :                 }
     125           0 :                 break;
     126             :             case SC_DBSEL_SHRINK_TO_USED_DATA:
     127             :             case SC_DBSEL_ROW_DOWN:
     128             :                 {
     129             :                     // Shrink the selection to actual used area.
     130           0 :                     ScDocument& rDoc = pDocSh->GetDocument();
     131           0 :                     SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
     132           0 :                     SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
     133             :                     bool bShrunk;
     134           0 :                     rDoc.ShrinkToUsedDataArea( bShrunk, aRange.aStart.Tab(),
     135           0 :                             nCol1, nRow1, nCol2, nRow2, bShrinkColumnsOnly);
     136           0 :                     if (bShrunk)
     137             :                     {
     138           0 :                         aRange.aStart.SetCol(nCol1);
     139           0 :                         aRange.aEnd.SetCol(nCol2);
     140           0 :                         aRange.aStart.SetRow(nRow1);
     141           0 :                         aRange.aEnd.SetRow(nRow2);
     142             :                     }
     143             :                 }
     144           0 :                 break;
     145             :             default:
     146             :                 ;   // nothing
     147             :         }
     148           0 :         pData = pDocSh->GetDBData( aRange, eMode, eSel );
     149             :     }
     150           0 :     else if ( eMode != SC_DB_OLD )
     151             :         pData = pDocSh->GetDBData(
     152           0 :                     ScRange( GetViewData().GetCurX(), GetViewData().GetCurY(),
     153           0 :                              GetViewData().GetTabNo() ),
     154           0 :                     eMode, SC_DBSEL_KEEP );
     155             : 
     156           0 :     if (!pData)
     157           0 :         return NULL;
     158             : 
     159           0 :     if (bMark)
     160             :     {
     161           0 :         ScRange aFound;
     162           0 :         pData->GetArea(aFound);
     163           0 :         MarkRange( aFound, false );
     164             :     }
     165           0 :     return pData;
     166             : }
     167             : 
     168           0 : ScDBData* ScDBFunc::GetAnonymousDBData()
     169             : {
     170           0 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
     171           0 :     ScRange aRange;
     172           0 :     ScMarkType eMarkType = GetViewData().GetSimpleArea(aRange);
     173           0 :     if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
     174           0 :         return NULL;
     175             : 
     176             :     // Expand to used data area if not explicitly marked.
     177           0 :     const ScMarkData& rMarkData = GetViewData().GetMarkData();
     178           0 :     if (!rMarkData.IsMarked() && !rMarkData.IsMultiMarked())
     179             :     {
     180           0 :         SCCOL nCol1 = aRange.aStart.Col();
     181           0 :         SCCOL nCol2 = aRange.aEnd.Col();
     182           0 :         SCROW nRow1 = aRange.aStart.Row();
     183           0 :         SCROW nRow2 = aRange.aEnd.Row();
     184           0 :         pDocSh->GetDocument().GetDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2, false, false);
     185           0 :         aRange.aStart.SetCol(nCol1);
     186           0 :         aRange.aStart.SetRow(nRow1);
     187           0 :         aRange.aEnd.SetCol(nCol2);
     188           0 :         aRange.aEnd.SetRow(nRow2);
     189             :     }
     190             : 
     191           0 :     return pDocSh->GetAnonymousDBData(aRange);
     192             : }
     193             : 
     194             : //      main functions
     195             : 
     196             : // Sort
     197             : 
     198           0 : void ScDBFunc::UISort( const ScSortParam& rSortParam, bool bRecord )
     199             : {
     200           0 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
     201           0 :     ScDocument& rDoc = pDocSh->GetDocument();
     202           0 :     SCTAB nTab = GetViewData().GetTabNo();
     203             :     ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
     204           0 :                                                     rSortParam.nCol2, rSortParam.nRow2 );
     205           0 :     if (!pDBData)
     206             :     {
     207             :         OSL_FAIL( "Sort: no DBData" );
     208           0 :         return;
     209             :     }
     210             : 
     211           0 :     ScSubTotalParam aSubTotalParam;
     212           0 :     pDBData->GetSubTotalParam( aSubTotalParam );
     213           0 :     if (aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly)
     214             :     {
     215             :         //  repeat subtotals, with new sortorder
     216             : 
     217           0 :         DoSubTotals( aSubTotalParam, bRecord, &rSortParam );
     218             :     }
     219             :     else
     220             :     {
     221           0 :         Sort( rSortParam, bRecord );        // just sort
     222             :     }
     223             : }
     224             : 
     225           0 : void ScDBFunc::Sort( const ScSortParam& rSortParam, bool bRecord, bool bPaint )
     226             : {
     227           0 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
     228           0 :     SCTAB nTab = GetViewData().GetTabNo();
     229           0 :     ScDBDocFunc aDBDocFunc( *pDocSh );
     230           0 :     bool bSuccess = aDBDocFunc.Sort( nTab, rSortParam, bRecord, bPaint, false );
     231           0 :     if ( bSuccess && !rSortParam.bInplace )
     232             :     {
     233             :         //  mark target
     234             :         ScRange aDestRange( rSortParam.nDestCol, rSortParam.nDestRow, rSortParam.nDestTab,
     235             :                             rSortParam.nDestCol + rSortParam.nCol2 - rSortParam.nCol1,
     236           0 :                             rSortParam.nDestRow + rSortParam.nRow2 - rSortParam.nRow1,
     237           0 :                             rSortParam.nDestTab );
     238           0 :         MarkRange( aDestRange );
     239             :     }
     240             : 
     241           0 :     ResetAutoSpell();
     242           0 : }
     243             : 
     244             : //  filters
     245             : 
     246           3 : void ScDBFunc::Query( const ScQueryParam& rQueryParam, const ScRange* pAdvSource, bool bRecord )
     247             : {
     248           3 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
     249           3 :     SCTAB nTab = GetViewData().GetTabNo();
     250           3 :     ScDBDocFunc aDBDocFunc( *pDocSh );
     251           3 :     bool bSuccess = aDBDocFunc.Query( nTab, rQueryParam, pAdvSource, bRecord, false );
     252             : 
     253           3 :     if (bSuccess)
     254             :     {
     255           3 :         bool bCopy = !rQueryParam.bInplace;
     256           3 :         if (bCopy)
     257             :         {
     258             :             //  mark target range (data base range has been set up if applicable)
     259           0 :             ScDocument& rDoc = pDocSh->GetDocument();
     260             :             ScDBData* pDestData = rDoc.GetDBAtCursor(
     261             :                                             rQueryParam.nDestCol, rQueryParam.nDestRow,
     262           0 :                                             rQueryParam.nDestTab, true );
     263           0 :             if (pDestData)
     264             :             {
     265           0 :                 ScRange aDestRange;
     266           0 :                 pDestData->GetArea(aDestRange);
     267           0 :                 MarkRange( aDestRange );
     268             :             }
     269             :         }
     270             : 
     271           3 :         if (!bCopy)
     272             :         {
     273           3 :             UpdateScrollBars();
     274           3 :             SelectionChanged();     // for attribute states (filtered rows are ignored)
     275             :         }
     276             : 
     277           3 :         GetViewData().GetBindings().Invalidate( SID_UNFILTER );
     278           3 :     }
     279           3 : }
     280             : 
     281             : //  autofilter-buttons show / hide
     282             : 
     283           0 : void ScDBFunc::ToggleAutoFilter()
     284             : {
     285           0 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
     286           0 :     ScDocShellModificator aModificator( *pDocSh );
     287             : 
     288           0 :     ScQueryParam    aParam;
     289           0 :     ScDocument*     pDoc    = GetViewData().GetDocument();
     290           0 :     ScDBData*       pDBData = GetDBData(false, SC_DB_MAKE, SC_DBSEL_ROW_DOWN);
     291             : 
     292           0 :     pDBData->SetByRow( true );              //! undo, retrieve beforehand ??
     293           0 :     pDBData->GetQueryParam( aParam );
     294             : 
     295             :     SCCOL  nCol;
     296           0 :     SCROW  nRow = aParam.nRow1;
     297           0 :     SCTAB  nTab = GetViewData().GetTabNo();
     298             :     sal_Int16   nFlag;
     299           0 :     bool    bHasAuto = true;
     300           0 :     bool    bHeader  = pDBData->HasHeader();
     301           0 :     bool    bPaint   = false;
     302             : 
     303             :     //!     instead retrieve from DB-range?
     304             : 
     305           0 :     for (nCol=aParam.nCol1; nCol<=aParam.nCol2 && bHasAuto; nCol++)
     306             :     {
     307             :         nFlag = static_cast<const ScMergeFlagAttr*>( pDoc->
     308           0 :                 GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
     309             : 
     310           0 :         if ( (nFlag & SC_MF_AUTO) == 0 )
     311           0 :             bHasAuto = false;
     312             :     }
     313             : 
     314           0 :     if (bHasAuto)                               // remove
     315             :     {
     316             :         //  hide filter buttons
     317             : 
     318           0 :         for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
     319             :         {
     320             :             nFlag = static_cast<const ScMergeFlagAttr*>( pDoc->
     321           0 :                     GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
     322           0 :             pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
     323             :         }
     324             : 
     325             :         // use a list action for the AutoFilter buttons (ScUndoAutoFilter) and the filter operation
     326             : 
     327           0 :         OUString aUndo = ScGlobal::GetRscString( STR_UNDO_QUERY );
     328           0 :         pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo );
     329             : 
     330           0 :         ScRange aRange;
     331           0 :         pDBData->GetArea( aRange );
     332           0 :         pDocSh->GetUndoManager()->AddUndoAction(
     333           0 :             new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), false ) );
     334             : 
     335           0 :         pDBData->SetAutoFilter(false);
     336             : 
     337             :         //  remove filter (incl. Paint / Undo)
     338             : 
     339           0 :         SCSIZE nEC = aParam.GetEntryCount();
     340           0 :         for (SCSIZE i=0; i<nEC; i++)
     341           0 :             aParam.GetEntry(i).bDoQuery = false;
     342           0 :         aParam.bDuplicate = true;
     343           0 :         Query( aParam, NULL, true );
     344             : 
     345           0 :         pDocSh->GetUndoManager()->LeaveListAction();
     346             : 
     347           0 :         bPaint = true;
     348             :     }
     349             :     else                                    // show filter buttons
     350             :     {
     351           0 :         if ( !pDoc->IsBlockEmpty( nTab,
     352             :                                   aParam.nCol1, aParam.nRow1,
     353           0 :                                   aParam.nCol2, aParam.nRow2 ) )
     354             :         {
     355           0 :             if (!bHeader)
     356             :             {
     357           0 :                 if ( ScopedVclPtr<MessBox>::Create( GetViewData().GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES),
     358           0 :                         ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),       // "StarCalc"
     359           0 :                         ScGlobal::GetRscString( STR_MSSG_MAKEAUTOFILTER_0 )     // header from first row?
     360           0 :                     )->Execute() == RET_YES )
     361             :                 {
     362           0 :                     pDBData->SetHeader( true );     //! Undo ??
     363           0 :                     bHeader = true;
     364             :                 }
     365             :             }
     366             : 
     367           0 :             ScRange aRange;
     368           0 :             pDBData->GetArea( aRange );
     369           0 :             pDocSh->GetUndoManager()->AddUndoAction(
     370           0 :                 new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), true ) );
     371             : 
     372           0 :             pDBData->SetAutoFilter(true);
     373             : 
     374           0 :             for (nCol=aParam.nCol1; nCol<=aParam.nCol2; nCol++)
     375             :             {
     376             :                 nFlag = static_cast<const ScMergeFlagAttr*>( pDoc->
     377           0 :                         GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG ))->GetValue();
     378           0 :                 pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr( nFlag | SC_MF_AUTO ) );
     379             :             }
     380             :             pDocSh->PostPaint(ScRange(aParam.nCol1, nRow, nTab, aParam.nCol2, nRow, nTab),
     381           0 :                               PAINT_GRID);
     382           0 :             bPaint = true;
     383             :         }
     384             :         else
     385             :         {
     386           0 :             ScopedVclPtrInstance<MessageDialog> aErrorBox(GetViewData().GetDialogParent(),
     387           0 :                                 ScGlobal::GetRscString(STR_ERR_AUTOFILTER));
     388           0 :             aErrorBox->Execute();
     389             :         }
     390             :     }
     391             : 
     392           0 :     if ( bPaint )
     393             :     {
     394           0 :         aModificator.SetDocumentModified();
     395             : 
     396           0 :         SfxBindings& rBindings = GetViewData().GetBindings();
     397           0 :         rBindings.Invalidate( SID_AUTO_FILTER );
     398           0 :         rBindings.Invalidate( SID_AUTOFILTER_HIDE );
     399           0 :     }
     400           0 : }
     401             : 
     402             : //      just hide, no data change
     403             : 
     404           0 : void ScDBFunc::HideAutoFilter()
     405             : {
     406           0 :     ScDocShell* pDocSh = GetViewData().GetDocShell();
     407           0 :     ScDocShellModificator aModificator( *pDocSh );
     408             : 
     409           0 :     ScDocument& rDoc = pDocSh->GetDocument();
     410             : 
     411           0 :     ScQueryParam aParam;
     412           0 :     ScDBData* pDBData = GetDBData( false );
     413             : 
     414             :     SCTAB nTab;
     415             :     SCCOL nCol1, nCol2;
     416             :     SCROW nRow1, nRow2;
     417           0 :     pDBData->GetArea(nTab, nCol1, nRow1, nCol2, nRow2);
     418             : 
     419           0 :     for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
     420             :     {
     421             :         sal_Int16 nFlag = static_cast<const ScMergeFlagAttr*>( rDoc.
     422           0 :                                 GetAttr( nCol, nRow1, nTab, ATTR_MERGE_FLAG ))->GetValue();
     423           0 :         rDoc.ApplyAttr( nCol, nRow1, nTab, ScMergeFlagAttr( nFlag & ~SC_MF_AUTO ) );
     424             :     }
     425             : 
     426           0 :     ScRange aRange;
     427           0 :     pDBData->GetArea( aRange );
     428           0 :     pDocSh->GetUndoManager()->AddUndoAction(
     429           0 :         new ScUndoAutoFilter( pDocSh, aRange, pDBData->GetName(), false ) );
     430             : 
     431           0 :     pDBData->SetAutoFilter(false);
     432             : 
     433           0 :     pDocSh->PostPaint(ScRange(nCol1, nRow1, nTab, nCol2, nRow1, nTab), PAINT_GRID );
     434           0 :     aModificator.SetDocumentModified();
     435             : 
     436           0 :     SfxBindings& rBindings = GetViewData().GetBindings();
     437           0 :     rBindings.Invalidate( SID_AUTO_FILTER );
     438           0 :     rBindings.Invalidate( SID_AUTOFILTER_HIDE );
     439           0 : }
     440             : 
     441             : //      Re-Import
     442             : 
     443           0 : bool ScDBFunc::ImportData( const ScImportParam& rParam, bool bRecord )
     444             : {
     445           0 :     ScDocument* pDoc = GetViewData().GetDocument();
     446           0 :     ScEditableTester aTester( pDoc, GetViewData().GetTabNo(), rParam.nCol1,rParam.nRow1,
     447           0 :                                                             rParam.nCol2,rParam.nRow2 );
     448           0 :     if ( !aTester.IsEditable() )
     449             :     {
     450           0 :         ErrorMessage(aTester.GetMessageId());
     451           0 :         return false;
     452             :     }
     453             : 
     454           0 :     ScDBDocFunc aDBDocFunc( *GetViewData().GetDocShell() );
     455           0 :     return aDBDocFunc.DoImport( GetViewData().GetTabNo(), rParam, NULL, bRecord );
     456         156 : }
     457             : 
     458             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11