summaryrefslogtreecommitdiff
path: root/sc/source/ui/view
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/view')
-rw-r--r--sc/source/ui/view/cellsh2.cxx15
-rw-r--r--sc/source/ui/view/dbfunc.cxx18
-rw-r--r--sc/source/ui/view/dbfunc3.cxx509
-rw-r--r--sc/source/ui/view/gridwin.cxx120
-rw-r--r--sc/source/ui/view/gridwin2.cxx320
-rw-r--r--sc/source/ui/view/gridwin4.cxx30
-rw-r--r--sc/source/ui/view/makefile.mk4
-rw-r--r--sc/source/ui/view/tabview.cxx30
8 files changed, 865 insertions, 181 deletions
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index cf64a07a2d95..47c55350f278 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -762,7 +762,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
{
// select database range or data
pTabViewShell->GetDBData( TRUE, SC_DB_OLD );
- const ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
pTabViewShell->MarkDataArea( FALSE );
@@ -828,6 +828,19 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
{
+ // Shrink the range to the data area.
+ SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
+ SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
+ {
+ aRange.aStart.SetCol(nStartCol);
+ aRange.aStart.SetRow(nStartRow);
+ aRange.aEnd.SetCol(nEndCol);
+ aRange.aEnd.SetRow(nEndRow);
+ rMark.SetMarkArea(aRange);
+ pTabViewShell->MarkRange(aRange);
+ }
+
BOOL bOK = TRUE;
if ( pDoc->HasSubTotalCells( aRange ) )
{
diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
index 0d44603b64f8..48b6d3ba11f7 100644
--- a/sc/source/ui/view/dbfunc.cxx
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -107,14 +107,30 @@ void ScDBFunc::GotoDBArea( const String& rDBName )
// aktuellen Datenbereich fuer Sortieren / Filtern suchen
-ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode )
+ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, bool bShrinkToData )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDBData* pData = NULL;
ScRange aRange;
ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
+ {
+ if (bShrinkToData)
+ {
+ // Shrink the range to only include data area.
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
+ SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
+ {
+ aRange.aStart.SetCol(nCol1);
+ aRange.aEnd.SetCol(nCol2);
+ aRange.aStart.SetRow(nRow1);
+ aRange.aEnd.SetRow(nRow2);
+ }
+ }
pData = pDocSh->GetDBData( aRange, eMode, FALSE );
+ }
else if ( eMode != SC_DB_OLD )
pData = pDocSh->GetDBData(
ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 5fd4a5f470f5..41a959409727 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -44,19 +44,17 @@
#include <vcl/waitobj.hxx>
#include <svl/zforlist.hxx>
#include <sfx2/app.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
-#include <com/sun/star/sheet/MemberResultFlags.hpp>
-
-#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
#include <com/sun/star/sheet/MemberResultFlags.hpp>
-#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
-#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
-#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
#include "global.hxx"
#include "globstr.hrc"
@@ -81,9 +79,13 @@
#include "patattr.hxx"
#include "unonames.hxx"
#include "cell.hxx"
+#include "userlist.hxx"
#include <hash_set>
+#include <hash_map>
#include <memory>
+#include <list>
+#include <vector>
using namespace com::sun::star;
using ::com::sun::star::uno::Any;
@@ -91,7 +93,16 @@ using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::sheet::XDimensionsSupplier;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::rtl::OUStringBuffer;
using ::std::auto_ptr;
+using ::std::list;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
// STATIC DATA -----------------------------------------------------------
@@ -1351,123 +1362,323 @@ void ScDBFunc::UngroupDataPilot()
}
}
+static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
+{
+ sal_Int32 n = rSubtotal.getLength();
+ const sal_Unicode* p = rSubtotal.getStr();
+ OUStringBuffer aBuf, aWordBuf;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (c == sal_Unicode(' '))
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ aBuf.append(c);
+ }
+ else if (c == sal_Unicode('\\'))
+ {
+ // Escape a backslash character.
+ aWordBuf.append(c);
+ aWordBuf.append(c);
+ }
+ else if (c == sal_Unicode('?'))
+ {
+ // A literal '?' must be escaped with a backslash ('\');
+ aWordBuf.append(sal_Unicode('\\'));
+ aWordBuf.append(c);
+ }
+ else
+ aWordBuf.append(c);
+ }
+
+ if (aWordBuf.getLength() > 0)
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString )
{
+ using namespace ::com::sun::star::sheet;
+
String aNewName( rString );
ScDocument* pDoc = GetViewData()->GetDocument();
ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() );
- if ( pDPObj )
+ if (!pDPObj)
+ return;
+
+ String aOldText;
+ pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+
+ if ( aOldText == rString )
{
- String aOldText;
- pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+ // nothing to do: silently exit
+ return;
+ }
+
+ USHORT nErrorId = 0;
+
+ pDPObj->BuildAllDimensionMembers();
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ BOOL bChange = FALSE;
- if ( aOldText == rString )
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( rPos, nOrient );
+ if ( nField >= 0 )
+ {
+ // changing a field title
+ if ( aData.GetExistingDimensionData() )
{
- // nothing to do: silently exit
- return;
- }
+ // only group dimensions can be renamed
- USHORT nErrorId = 0;
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing dimension (group or other)
+ if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) )
+ {
+ pGroupDim->Rename( aNewName );
- ScDPSaveData aData( *pDPObj->GetSaveData() );
- BOOL bChange = FALSE;
+ // also rename in SaveData to preserve the field settings
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
+ pSaveDim->SetName( aNewName );
- USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
- long nField = pDPObj->GetHeaderDim( rPos, nOrient );
- if ( nField >= 0 )
+ bChange = TRUE;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(nField, bDataLayout);
+ ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(aDimName))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ }
+ else if (pDPObj->IsDataDescriptionCell(rPos))
+ {
+ // There is only one data dimension.
+ ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA);
+ if (pDim)
{
- // changing a field title
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pDim->GetName()))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else
+ {
+ // This is not a field header.
+ sheet::DataPilotTableHeaderData aPosData;
+ pDPObj->GetHeaderPositionData(rPos, aPosData);
- if ( aData.GetExistingDimensionData() )
+ if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() )
+ {
+ if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL))
{
- // only group dimensions can be renamed
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
- ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
if ( pGroupDim )
{
- // valid name: not empty, no existing dimension (group or other)
- if ( aNewName.Len() && !pDPObj->IsDimNameInUse( aNewName ) )
+ // valid name: not empty, no existing group in this dimension
+ //! ignore case?
+ if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
{
- pGroupDim->Rename( aNewName );
+ ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
+ if ( pGroup )
+ pGroup->Rename( aNewName ); // rename the existing group
+ else
+ {
+ // create a new group to replace the automatic group
+ ScDPSaveGroupItem aGroup( aNewName );
+ aGroup.AddElement( aOldText );
+ pGroupDim->AddGroupItem( aGroup );
+ }
- // also rename in SaveData to preserve the field settings
- ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
- pSaveDim->SetName( aNewName );
+ // in both cases also adjust savedata, to preserve member settings (show details)
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
+ ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
+ if ( pSaveMember )
+ pSaveMember->SetName( aNewName );
bChange = TRUE;
}
else
nErrorId = STR_INVALIDNAME;
- }
+ }
}
- }
- else
- {
- // renaming a group (item)?
- // allow only on the item name itself - not on empty cells, not on subtotals
-
- sheet::DataPilotTableHeaderData aPosData;
- pDPObj->GetHeaderPositionData(rPos, aPosData);
- if ( ( aPosData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
- ! ( aPosData.Flags & sheet::MemberResultFlags::SUBTOTAL ) &&
- aOldText.Len() )
+ else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL))
{
- if ( aData.GetExistingDimensionData() )
+ aData.SetGrandTotalName(rString);
+ bChange = true;
+ }
+ else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout);
+ if (bDataLayout)
{
- BOOL bIsDataLayout;
- String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
+ // data dimension
+ do
+ {
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ break;
+
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName);
+ if (!pDim)
+ break;
+
+ if (!rString.Len())
+ {
+ nErrorId = STR_INVALIDNAME;
+ break;
+ }
- ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
- ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
- if ( pGroupDim )
+ if (aPosData.MemberName.equalsIgnoreAsciiCase(rString))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ while (false);
+ }
+ else
+ {
+ // field member
+ do
{
- // valid name: not empty, no existing group in this dimension
- //! ignore case?
- if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName);
+ if (!pDim)
+ break;
+
+ ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName);
+ if (!pMem)
+ break;
+
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
{
- ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
- if ( pGroup )
- pGroup->Rename( aNewName ); // rename the existing group
- else
- {
- // create a new group to replace the automatic group
- ScDPSaveGroupItem aGroup( aNewName );
- aGroup.AddElement( aOldText );
- pGroupDim->AddGroupItem( aGroup );
- }
+ // Change subtotal only when the table has one data dimension.
+ if (aData.GetDataDimensionCount() > 1)
+ break;
+
+ // display name for subtotal is allowed only if the subtotal type is 'Automatic'.
+ if (pDim->GetSubTotalsCount() != 1)
+ break;
- // in both cases also adjust savedata, to preserve member settings (show details)
- ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
- ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
- if ( pSaveMember )
- pSaveMember->SetName( aNewName );
+ if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO)
+ break;
- bChange = TRUE;
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ String aMemberName;
+ if (pLayoutName)
+ aMemberName = *pLayoutName;
+ else
+ aMemberName = aPosData.MemberName;
+
+ String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName);
+ pDim->SetSubtotalName(aNew);
+ bChange = true;
}
else
- nErrorId = STR_INVALIDNAME;
+ {
+ // Check to make sure the member name isn't
+ // already used.
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pMem->GetName()))
+ {
+ pMem->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDim->IsMemberNameInUse(rString))
+ {
+ pMem->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
}
+ while (false);
}
}
}
+ }
- if ( bChange )
- {
- // apply changes
- ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
- ScDPObject* pNewObj = new ScDPObject( *pDPObj );
- pNewObj->SetSaveData( aData );
- aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
- delete pNewObj;
- }
- else
- {
- if ( !nErrorId )
- nErrorId = STR_ERR_DATAPILOT_INPUT;
- ErrorMessage( nErrorId );
- }
+ if ( bChange )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+ }
+ else
+ {
+ if ( !nErrorId )
+ nErrorId = STR_ERR_DATAPILOT_INPUT;
+ ErrorMessage( nErrorId );
}
}
@@ -1484,6 +1695,134 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName )
// puts it to the end of the list even if it was in the list before.
}
+bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
+ if (!pDPObj)
+ return false;
+
+ // We need to run this to get all members later.
+ pDPObj->BuildAllDimensionMembers();
+
+ USHORT nOrientation;
+ long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
+ if (nDimIndex < 0)
+ // Invalid dimension index. Bail out.
+ return false;
+
+ BOOL bDataLayout;
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (!pSaveData)
+ return false;
+
+ ScDPSaveData aNewSaveData(*pSaveData);
+ String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout);
+ ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName);
+ if (!pSaveDim)
+ return false;
+
+ typedef ScDPSaveDimension::MemberList MemList;
+ const MemList& rDimMembers = pSaveDim->GetMembers();
+ list<OUString> aMembers;
+ hash_set<OUString, ::rtl::OUStringHash> aMemberSet;
+ size_t nMemberCount = 0;
+ for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ ScDPSaveMember* pMem = *itr;
+ aMembers.push_back(pMem->GetName());
+ aMemberSet.insert(pMem->GetName());
+ ++nMemberCount;
+ }
+
+ // Sort the member list in ascending order.
+ aMembers.sort();
+
+ // Collect and rank those custom sort strings that also exist in the member name list.
+
+ typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap;
+ UserSortMap aSubStrs;
+ sal_uInt16 nSubCount = 0;
+ if (pUserListId)
+ {
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (!pUserList)
+ return false;
+
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ if (!n || *pUserListId >= n)
+ return false;
+ }
+
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]);
+ if (pData)
+ {
+ sal_uInt16 n = pData->GetSubCount();
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ OUString aSub = pData->GetSubStr(i);
+ if (!aMemberSet.count(aSub))
+ // This string doesn't exist in the member name set. Don't add this.
+ continue;
+
+ aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++));
+ }
+ }
+ }
+
+ // Rank all members.
+
+ vector<OUString> aRankedNames(nMemberCount);
+ sal_uInt16 nCurStrId = 0;
+ for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ OUString aName = *itr;
+ sal_uInt16 nRank = 0;
+ UserSortMap::const_iterator itrSub = aSubStrs.find(aName);
+ if (itrSub == aSubStrs.end())
+ nRank = nSubCount + nCurStrId++;
+ else
+ nRank = itrSub->second;
+
+ if (!bAscending)
+ nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 );
+
+ aRankedNames[nRank] = aName;
+ }
+
+ // Re-order ScDPSaveMember instances with the new ranks.
+
+ for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end();
+ itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr);
+ if (!pOldMem)
+ // All members are supposed to be present.
+ continue;
+
+ ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem);
+ pSaveDim->AddMember(pNewMem);
+ }
+
+ // Set the sorting mode to manual for now. We may introduce a new sorting
+ // mode later on.
+
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ pSaveDim->SetSortInfo(&aSortInfo);
+
+ // Update the datapilot with the newly sorted field members.
+
+ auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj));
+ pNewObj->SetSaveData(aNewSaveData);
+ ScDBDocFunc aFunc(*GetViewData()->GetDocShell());
+
+ return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
+}
+
BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
{
BOOL bRet = FALSE;
@@ -1529,7 +1868,7 @@ BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
// get all member names in source order
uno::Sequence<rtl::OUString> aMemberNames;
- pDPObj->GetMembers( aDestData.Dimension, aMemberNames );
+ pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames );
bool bInserted = false;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index aca88c554317..7f78461aedb0 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -121,6 +121,7 @@
#include "validat.hxx"
#include "tabprotection.hxx"
#include "postit.hxx"
+#include "dpcontrol.hxx"
#include "drawview.hxx"
#include <svx/sdrpagewindow.hxx>
@@ -369,6 +370,8 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic
pNoteMarker( NULL ),
pFilterBox( NULL ),
pFilterFloat( NULL ),
+ mpDPFieldPopup(NULL),
+ mpFilterButton(NULL),
nCursorHideCount( 0 ),
bMarking( FALSE ),
nButtonDown( 0 ),
@@ -445,14 +448,26 @@ void __EXPORT ScGridWindow::Resize( const Size& )
void ScGridWindow::ClickExtern()
{
- // #i81298# don't delete the filter box when called from its select handler
- // (possible through row header size update)
- // #i84277# when initializing the filter box, a Basic error can deactivate the view
- if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
- return;
+ do
+ {
+ // #i81298# don't delete the filter box when called from its select handler
+ // (possible through row header size update)
+ // #i84277# when initializing the filter box, a Basic error can deactivate the view
+ if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
+ {
+ break;
+ }
- DELETEZ(pFilterBox);
- DELETEZ(pFilterFloat);
+ DELETEZ(pFilterBox);
+ DELETEZ(pFilterFloat);
+ }
+ while (false);
+
+ if (mpDPFieldPopup.get())
+ {
+ mpDPFieldPopup->close(false);
+ mpDPFieldPopup.reset();
+ }
}
IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
@@ -507,7 +522,7 @@ void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, BOOL bHasSelecti
}
}
-void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow )
+void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
{
//! merge position/size handling with DoAutoFilterMenue
@@ -658,6 +673,22 @@ void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow )
CaptureMouse();
}
+void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
+ if (!pDPObj)
+ return;
+
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
+}
+
void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
{
delete pFilterBox;
@@ -1619,52 +1650,8 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
if (pAttr->HasAutoFilter())
{
- Point aScrPos = pViewData->GetScrPos(nPosX,nPosY,eWhich);
- long nSizeX;
- long nSizeY;
- Point aDiffPix = aPos;
-
- aDiffPix -= aScrPos;
- BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
- if ( bLayoutRTL )
- aDiffPix.X() = -aDiffPix.X();
-
- pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
-
- // Breite des Buttons ist nicht von der Zellhoehe abhaengig
- Size aButSize = aComboButton.GetSizePixel();
- long nButWidth = Min( aButSize.Width(), nSizeX );
- long nButHeight = Min( aButSize.Height(), nSizeY );
-
- if ( aDiffPix.X() >= nSizeX - nButWidth &&
- aDiffPix.Y() >= nSizeY - nButHeight )
- {
- if ( DoPageFieldSelection( nPosX, nPosY ) )
- return;
-
- BOOL bFilterActive = IsAutoFilterActive( nPosX, nPosY,
- pViewData->GetTabNo() );
-
- aComboButton.SetOptSizePixel();
- DrawComboButton( aScrPos, nSizeX, nSizeY, bFilterActive, TRUE );
-
-#if 0
- if ( bWasFilterBox
- && (SCsCOL)nOldColFBox == nPosX
- && (SCsROW)nOldRowFBox == nPosY )
- {
- // Verhindern, dass an gleicher Stelle eine
- // FilterBox geoeffnet wird, wenn diese gerade
- // geloescht wurde
-
- nMouseStatus = SC_GM_FILTER; // fuer ButtonDraw im MouseButtonUp();
- return;
- }
-#endif
- DoAutoFilterMenue( nPosX, nPosY, FALSE );
-
+ if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
return;
- }
}
if (pAttr->HasButton())
{
@@ -1794,11 +1781,17 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
{
- BOOL bFilterActive = IsAutoFilterActive( pFilterBox->GetCol(), pFilterBox->GetRow(),
- pViewData->GetTabNo() );
- HideCursor();
- aComboButton.Draw( bFilterActive );
- ShowCursor();
+ if (mpFilterButton.get())
+ {
+ bool bFilterActive = IsAutoFilterActive(
+ pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );
+
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
}
nMouseStatus = SC_GM_NONE;
ReleaseMouse();
@@ -2218,9 +2211,14 @@ void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
nMouseStatus = SC_GM_NONE;
if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
{
- HideCursor();
- aComboButton.Draw( FALSE );
- ShowCursor();
+ if (mpFilterButton.get())
+ {
+ mpFilterButton->setHasHiddenMember(false);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
}
ReleaseMouse();
pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index 643928a7c8aa..e0dd63ff090e 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -55,48 +55,124 @@
#include "dpoutput.hxx" // ScDPPositionData
#include "dpshttab.hxx"
#include "dbdocfun.hxx"
+#include "dpcontrol.hxx"
+#include "dpcontrol.hrc"
+#include "strload.hxx"
+#include "userlist.hxx"
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include "scabstdlg.hxx" //CHINA001
-using namespace com::sun::star;
+#include <vector>
+#include <hash_map>
+
+using namespace com::sun::star;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::std::vector;
+using ::std::auto_ptr;
+using ::std::hash_map;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
// STATIC DATA -----------------------------------------------------------
// -----------------------------------------------------------------------
-BOOL ScGridWindow::HasPageFieldData( SCCOL nCol, SCROW nRow ) const
+DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const
{
+ using namespace ::com::sun::star::sheet;
+
ScDocument* pDoc = pViewData->GetDocument();
SCTAB nTab = pViewData->GetTabNo();
ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
- if ( pDPObj && nCol > 0 )
+ if (!pDPObj)
+ return DataPilotFieldOrientation_HIDDEN;
+
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+
+ // Check for page field first.
+ if (nCol > 0)
{
// look for the dimension header left of the drop-down arrow
- USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
- if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
+ if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
{
BOOL bIsDataLayout = FALSE;
String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
if ( aFieldName.Len() && !bIsDataLayout )
- return TRUE;
+ return DataPilotFieldOrientation_PAGE;
}
}
- return FALSE;
+
+ nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ // Now, check for row/column field.
+ long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient);
+ if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
+ {
+ BOOL bIsDataLayout = FALSE;
+ String aFieldName = pDPObj->GetDimName(nField, bIsDataLayout);
+ if (aFieldName.Len() && !bIsDataLayout)
+ return static_cast<DataPilotFieldOrientation>(nOrient);
+ }
+
+ return DataPilotFieldOrientation_HIDDEN;
}
// private method for mouse button handling
BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow )
{
- if ( HasPageFieldData( nCol, nRow ) )
+ if (GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE)
{
- DoPageFieldMenue( nCol, nRow );
+ LaunchPageFieldMenu( nCol, nRow );
return TRUE;
}
return FALSE;
}
+bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ Point aDiffPix = rMEvt.GetPosPixel();
+
+ aDiffPix -= aScrPos;
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ if ( bLayoutRTL )
+ aDiffPix.X() = -aDiffPix.X();
+
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY()));
+ mpFilterButton->setBoundingBox(aScrPos, aScrSize);
+ Point aPopupPos;
+ Size aPopupSize;
+ mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ if ( DoPageFieldSelection( nCol, nRow ) )
+ return true;
+
+ bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setDrawBaseButton(false);
+ mpFilterButton->setDrawPopupButton(true);
+ mpFilterButton->setPopupPressed(true);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ DoAutoFilterMenue(nCol, nRow, false);
+ return true;
+ }
+
+ return false;
+}
+
void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
{
ScDocument* pDoc = pViewData->GetDocument();
@@ -114,6 +190,15 @@ void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt
bDPMouse = TRUE;
nDPField = nField;
pDragDPObj = pDPObj;
+
+ if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj))
+ {
+ // field name pop up menu has been launched. Don't activate
+ // field move.
+ bDPMouse = false;
+ return;
+ }
+
DPTestMouse( rMEvt, TRUE );
StartTracking();
}
@@ -282,6 +367,223 @@ void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove )
pViewData->GetView()->ResetTimer();
}
+bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings());
+ aBtn.setBoundingBox(aScrPos, aScrSize);
+ Point aPopupPos;
+ Size aPopupSize;
+ aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ // Mouse cursor inside the popup arrow box. Launch the field menu.
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj);
+ return true;
+ }
+
+ return false;
+}
+
+namespace {
+
+struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
+{
+ ScPivotParam maDPParam;
+ ScDPObject* mpDPObj;
+ long mnDim;
+};
+
+class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
+{
+public:
+ explicit DPFieldPopupOKAction(ScGridWindow* p) :
+ mpGridWindow(p) {}
+
+ virtual void execute()
+ {
+ mpGridWindow->UpdateDPFromFieldPopupMenu();
+ }
+private:
+ ScGridWindow* mpGridWindow;
+};
+
+class PopupSortAction : public ScMenuFloatingWindow::Action
+{
+public:
+ enum SortType { ASCENDING, DESCENDING, CUSTOM };
+
+ explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
+ maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
+
+ virtual void execute()
+ {
+ switch (meType)
+ {
+ case ASCENDING:
+ mpViewShell->DataPilotSort(maPos, true);
+ break;
+ case DESCENDING:
+ mpViewShell->DataPilotSort(maPos, false);
+ break;
+ case CUSTOM:
+ mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
+ break;
+ default:
+ ;
+ }
+ }
+
+private:
+ ScAddress maPos;
+ SortType meType;
+ sal_uInt16 mnUserListIndex;
+ ScTabViewShell* mpViewShell;
+};
+
+}
+
+void ScGridWindow::DPLaunchFieldPopupMenu(
+ const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ // We need to get the list of field members.
+ auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
+ pDPObj->FillLabelData(pDPData->maDPParam);
+ pDPData->mpDPObj = pDPObj;
+
+ USHORT nOrient;
+ pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
+
+ if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
+ // out-of-bound dimension ID. This should never happen!
+ return;
+
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+
+ mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument()));
+ mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup"));
+ mpDPFieldPopup->setExtendedData(pDPData.release());
+ mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
+ {
+ // Populate field members.
+ size_t n = rLabelData.maMembers.size();
+ mpDPFieldPopup->setMemberSize(n);
+ for (size_t i = 0; i < n; ++i)
+ {
+ const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
+ mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible);
+ }
+ mpDPFieldPopup->initMembers();
+ }
+
+ vector<OUString> aUserSortNames;
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (pUserList)
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ aUserSortNames.reserve(n);
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
+ aUserSortNames.push_back(pData->GetString());
+ }
+ }
+
+ // Populate the menus.
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
+ ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
+
+ if (pSubMenu && !aUserSortNames.empty())
+ {
+ size_t n = aUserSortNames.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ pSubMenu->addMenuItem(
+ aUserSortNames[i], true,
+ new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell));
+ }
+ }
+
+ Rectangle aCellRect(rScrPos, rScrSize);
+ const Size& rPopupSize = mpDPFieldPopup->getWindowSize();
+ if (rScrSize.getWidth() > rPopupSize.getWidth())
+ {
+ // If the cell width is larger than the popup window width, launch it
+ // right-aligned with the cell.
+ long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth();
+ aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y()));
+ }
+ mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
+ mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
+}
+
+void ScGridWindow::UpdateDPFromFieldPopupMenu()
+{
+ typedef hash_map<OUString, OUString, OUStringHash> MemNameMapType;
+ typedef hash_map<OUString, bool, OUStringHash> MemVisibilityType;
+
+ if (!mpDPFieldPopup.get())
+ return;
+
+ DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
+ if (!pDPData)
+ return;
+
+ ScDPObject* pDPObj = pDPData->mpDPObj;
+ ScDPObject aNewDPObj(*pDPObj);
+ aNewDPObj.BuildAllDimensionMembers();
+ ScDPSaveData* pSaveData = aNewDPObj.GetSaveData();
+
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
+ ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
+ if (!pDim)
+ return;
+
+ // Build a map of layout names to original names.
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+ MemNameMapType aMemNameMap;
+ for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end();
+ itr != itrEnd; ++itr)
+ aMemNameMap.insert(MemNameMapType::value_type(itr->maLayoutName, itr->maName));
+
+ // The raw result may contain a mixture of layout names and original names.
+ MemVisibilityType aRawResult;
+ mpDPFieldPopup->getResult(aRawResult);
+
+ MemVisibilityType aResult;
+ for (MemVisibilityType::const_iterator itr = aRawResult.begin(), itrEnd = aRawResult.end(); itr != itrEnd; ++itr)
+ {
+ MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(itr->first);
+ if (itrNameMap == aMemNameMap.end())
+ // This is an original member name. Use it as-is.
+ aResult.insert(MemVisibilityType::value_type(itr->first, itr->second));
+ else
+ {
+ // This is a layout name. Get the original member name and use it.
+ aResult.insert(MemVisibilityType::value_type(itrNameMap->second, itr->second));
+ }
+ }
+ pDim->UpdateMemberVisibility(aResult);
+
+ ScDBDocFunc aFunc(*pViewData->GetDocShell());
+ aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false);
+}
+
void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt )
{
DPTestMouse( rMEvt, TRUE );
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index d700ee606731..7719dfcc5474 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -73,6 +73,7 @@
#include "editutil.hxx"
#include "inputopt.hxx"
#include "fillinfo.hxx"
+#include "dpcontrol.hxx"
#include "sc.hrc"
#include <vcl/virdev.hxx>
@@ -1203,6 +1204,8 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
{
aComboButton.SetOutputDevice( pContentDev );
+ ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY());
+
SCCOL nCol;
SCROW nRow;
SCSIZE nArrY;
@@ -1284,14 +1287,14 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
bool bArrowState = bSimpleQuery && bColumnFound;
long nSizeX;
long nSizeY;
-
pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
- aComboButton.SetOptSizePixel();
- DrawComboButton( pViewData->GetScrPos( nCol, nRow, eWhich ),
- nSizeX, nSizeY, bArrowState );
+ Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
- aComboButton.SetPosPixel( aOldPos ); // alten Zustand
- aComboButton.SetSizePixel( aOldSize ); // fuer MouseUp/Down
+ aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1));
+ aCellBtn.setDrawBaseButton(false);
+ aCellBtn.setDrawPopupButton(true);
+ aCellBtn.setHasHiddenMember(bArrowState);
+ aCellBtn.draw();
}
}
}
@@ -1318,13 +1321,14 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
nPosX -= nSizeX - 2;
}
- pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetLightColor() );
- pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX,nPosY+nSizeY-1) );
- pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX+nSizeX-1,nPosY) );
- pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
- pContentDev->DrawLine( Point(nPosX,nPosY+nSizeY-1), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) );
- pContentDev->DrawLine( Point(nPosX+nSizeX-1,nPosY), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) );
- pContentDev->SetLineColor( COL_BLACK );
+ String aStr;
+ pDoc->GetString(nCol, nRow, nTab, aStr);
+ aCellBtn.setText(aStr);
+ aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1));
+ aCellBtn.setDrawBaseButton(true);
+ aCellBtn.setDrawPopupButton(pInfo->bPopupButton);
+ aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
+ aCellBtn.draw();
}
}
}
diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk
index d8f45c8a754f..ed50324f68be 100644
--- a/sc/source/ui/view/makefile.mk
+++ b/sc/source/ui/view/makefile.mk
@@ -140,7 +140,6 @@ SLOFILES = \
$(SLO)$/dbfunc2.obj \
$(SLO)$/tabvwsh2.obj
.ELSE
-
NOOPTFILES=\
$(SLO)$/drawview.obj \
$(SLO)$/dbfunc2.obj \
@@ -157,7 +156,8 @@ EXCEPTIONSFILES= \
$(SLO)$/cellsh1.obj \
$(SLO)$/drawvie4.obj \
$(SLO)$/formatsh.obj \
- $(SLO)$/scextopt.obj \
+ $(SLO)$/gridwin2.obj \
+ $(SLO)$/scextopt.obj \
$(SLO)$/tabvwshb.obj \
$(SLO)$/viewdata.obj \
$(SLO)$/viewfun5.obj \
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 3077e852dbaf..c076575d4e6d 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -200,6 +200,8 @@
#include "AccessibilityHints.hxx"
#include "appoptio.hxx"
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+
#include <string>
#include <algorithm>
@@ -212,6 +214,8 @@
// fuer Rad-Maus
#define SC_DELTA_ZOOM 10
+using namespace ::com::sun::star;
+
// STATIC DATA -----------------------------------------------------------
@@ -2476,7 +2480,7 @@ sal_Bool ScTabView::HasPageFieldDataAtCursor() const
SCCOL nCol = aViewData.GetCurX();
SCROW nRow = aViewData.GetCurY();
if (pWin)
- return pWin->HasPageFieldData( nCol, nRow );
+ return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
return sal_False;
}
@@ -2486,15 +2490,23 @@ void ScTabView::StartDataSelect()
ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
SCCOL nCol = aViewData.GetCurX();
SCROW nRow = aViewData.GetCurY();
- if (pWin)
- {
- // #i36598# If the cursor is on a page field's data cell,
- // no meaningful input is possible anyway, so this function
- // can be used to select a page field entry.
- if ( pWin->HasPageFieldData( nCol, nRow ) )
- pWin->DoPageFieldMenue( nCol, nRow );
- else
+ if (!pWin)
+ return;
+
+ switch (pWin->GetDPFieldOrientation(nCol, nRow))
+ {
+ case sheet::DataPilotFieldOrientation_PAGE:
+ // #i36598# If the cursor is on a page field's data cell,
+ // no meaningful input is possible anyway, so this function
+ // can be used to select a page field entry.
+ pWin->LaunchPageFieldMenu( nCol, nRow );
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ case sheet::DataPilotFieldOrientation_ROW:
+ pWin->LaunchDPFieldMenu( nCol, nRow );
+ break;
+ default:
pWin->DoAutoFilterMenue( nCol, nRow, TRUE );
}
}