Commits

Anonymous committed 1c65599

itemsets: checking WhichRanges in ::Set(..)

  • Participants
  • Parent commits 2a7f1db
  • Branches new_itemsets

Comments (0)

Files changed (1)

File svtools/source/items1/itemset.cxx

         //lcl_PrintRanges(o_rWhichRanges);
 #endif
     };
+
+    static void lcl_IntersectWhichRanges(vector<sal_uInt16> rRanges1, vector<sal_uInt16> rRanges2, vector<sal_uInt16>& o_rResult)
+    {
+        o_rResult.clear();
+        vector<sal_uInt16>::const_iterator pCurrent1 = rRanges1.begin();
+        vector<sal_uInt16>::const_iterator pCurrent2 = rRanges2.begin();
+        while(*pCurrent1 && *pCurrent2)
+        {
+            sal_uInt16 nLowerBound = max(*pCurrent1, *pCurrent2);
+            sal_uInt16 nUpperBound = min(*(pCurrent1+1), *(pCurrent2+1));
+            if(nLowerBound <= nUpperBound)
+            {
+                o_rResult.push_back(nLowerBound);
+                o_rResult.push_back(nUpperBound);
+            }
+            if(*(pCurrent1+1) < *(pCurrent2+1))
+                pCurrent1 += 2;
+            else
+                pCurrent2 += 2;
+        }
+        o_rResult.push_back(0);
+    }
 }
 
 namespace sfx { namespace item {
         ClearItem();
         return false;
     }
-    const ItemEntry aFirstEntry(*m_vWhichRanges.begin());
-    const ItemEntry aLastEntry(m_vWhichRanges.end()[-2]);
     auto_ptr<vector<ItemEntry> > pSourceItems;
-    ItemVector::iterator pCandidatesBegin;
-    ItemVector::iterator pCandidatesEnd;
+    vector<ItemEntry>::iterator pCandidatesBegin;
+    vector<ItemEntry>::iterator pCandidatesEnd;
     if(bDeep && rSet.m_pParent)
     {
+        vector<sal_uInt16> vLegalWhichRange;
+        vector<sal_uInt16> vOldLegalWhichRange;
         auto_ptr<vector<ItemEntry> > pOldSourceItems(new vector<ItemEntry>());
         pSourceItems.reset(new vector<ItemEntry>());
-        for(const SfxItemSet* pCurrent = &rSet;
-            pCurrent;
-            pCurrent = pCurrent->m_pParent)
+        pSourceItems->reserve(128);
+        pOldSourceItems->reserve(128);
+        vLegalWhichRange.reserve(32);
+        vOldLegalWhichRange.reserve(32);
+        copy(m_vWhichRanges.begin(), m_vWhichRanges.end(), back_inserter(vLegalWhichRange));
+        for(const SfxItemSet* pCurrentSet = &rSet;
+            pCurrentSet;
+            pCurrentSet = pCurrentSet->m_pParent)
         {
-            swap(pSourceItems, pOldSourceItems);
-            pSourceItems->clear();
-            ItemVector::iterator pStart = lower_bound(
-                rSet.m_pItems->begin(),
-                rSet.m_pItems->end(),
-                aFirstEntry);
-            ItemVector::iterator pEnd = upper_bound(
-                pStart,
-                rSet.m_pItems->end(),
-                aLastEntry);
-            set_union(
-                pOldSourceItems->begin(), pOldSourceItems->end(),
-                pStart, pEnd,
-                back_inserter(*pSourceItems));
+            ItemVector::iterator pEnd = rSet.m_pItems->begin();
+            swap(vLegalWhichRange, vOldLegalWhichRange);
+            lcl_IntersectWhichRanges(vOldLegalWhichRange, pCurrentSet->m_vWhichRanges, vLegalWhichRange);
+            if(vLegalWhichRange.size() == 1)
+                break;
+            for(vector<sal_uInt16>::const_iterator pCurrentRange = vLegalWhichRange.begin();
+                *pCurrentRange;
+                pCurrentRange += 2)
+            {
+                swap(pSourceItems, pOldSourceItems);
+                pSourceItems->clear();
+                ItemVector::iterator pStart = lower_bound(
+                    pEnd,
+                    rSet.m_pItems->end(),
+                    ItemEntry(*pCurrentRange));
+                pEnd = upper_bound(
+                    pStart,
+                    rSet.m_pItems->end(),
+                    ItemEntry(*(pCurrentRange+1)));
+                set_union(
+                    pOldSourceItems->begin(), pOldSourceItems->end(),
+                    pStart, pEnd,
+                    back_inserter(*pSourceItems));
+            }
         }
         pCandidatesBegin = pSourceItems->begin();
         pCandidatesEnd = pSourceItems->end();
         pCandidatesBegin = lower_bound(
             rSet.m_pItems->begin(),
             rSet.m_pItems->end(),
-            aFirstEntry);
+            ItemEntry(*m_vWhichRanges.begin()));
         pCandidatesEnd = upper_bound(
             pCandidatesBegin,
             rSet.m_pItems->end(),
-            aLastEntry);
+            ItemEntry(*(m_vWhichRanges.end()-2)));
     }
+    ClearItem();
     bool isModified = false;
-    ClearItem();
     for(ItemVector::const_iterator pItemEntry = pCandidatesBegin;
         pItemEntry != pCandidatesEnd;
         ++pItemEntry)