blob: 680abff626b82336b823f8286bf3d1f59140bef9 [file] [log] [blame]
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.ss.usermodel.helpers;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
/**
* Helper for shifting rows up or down
*
* This abstract class exists to consolidate duplicated code between XSSFRowShifter and HSSFRowShifter (currently methods sprinkled throughout HSSFSheet)
*/
public abstract class RowShifter {
protected final Sheet sheet;
public RowShifter(Sheet sh) {
sheet = sh;
}
/**
* Shifts, grows, or shrinks the merged regions due to a row shift.
* Merged regions that are completely overlaid by shifting will be deleted.
*
* @param startRow the row to start shifting
* @param endRow the row to end shifting
* @param n the number of rows to shift
* @return an array of affected merged regions, doesn't contain deleted ones
*/
public List<CellRangeAddress> shiftMergedRegions(int startRow, int endRow, int n) {
List<CellRangeAddress> shiftedRegions = new ArrayList<CellRangeAddress>();
Set<Integer> removedIndices = new HashSet<Integer>();
//move merged regions completely if they fall within the new region boundaries when they are shifted
int size = sheet.getNumMergedRegions();
for (int i = 0; i < size; i++) {
CellRangeAddress merged = sheet.getMergedRegion(i);
// remove merged region that overlaps shifting
if (startRow + n <= merged.getFirstRow() && endRow + n >= merged.getLastRow()) {
removedIndices.add(i);
continue;
}
boolean inStart = (merged.getFirstRow() >= startRow || merged.getLastRow() >= startRow);
boolean inEnd = (merged.getFirstRow() <= endRow || merged.getLastRow() <= endRow);
//don't check if it's not within the shifted area
if (!inStart || !inEnd) {
continue;
}
//only shift if the region outside the shifted rows is not merged too
if (!merged.containsRow(startRow - 1) && !merged.containsRow(endRow + 1)) {
merged.setFirstRow(merged.getFirstRow() + n);
merged.setLastRow(merged.getLastRow() + n);
//have to remove/add it back
shiftedRegions.add(merged);
removedIndices.add(i);
}
}
if(!removedIndices.isEmpty()) {
sheet.removeMergedRegions(removedIndices);
}
//read so it doesn't get shifted again
for (CellRangeAddress region : shiftedRegions) {
sheet.addMergedRegion(region);
}
return shiftedRegions;
}
/**
* Updated named ranges
*/
public abstract void updateNamedRanges(FormulaShifter shifter);
/**
* Update formulas.
*/
public abstract void updateFormulas(FormulaShifter shifter);
/**
* Update the formulas in specified row using the formula shifting policy specified by shifter
*
* @param row the row to update the formulas on
* @param shifter the formula shifting policy
*/
@Internal
public abstract void updateRowFormulas(Row row, FormulaShifter shifter);
public abstract void updateConditionalFormatting(FormulaShifter shifter);
/**
* Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink
* is of type LINK_DOCUMENT and refers to a cell that was shifted). Hyperlinks
* do not track the content they point to.
*
* @param shifter the formula shifting policy
*/
public abstract void updateHyperlinks(FormulaShifter shifter);
}