View | Details | Raw Unified | Return to bug 61474
Collapse All | Expand All

(-)a/src/java/org/apache/poi/hssf/usermodel/helpers/HSSFRowShifter.java (-5 / +9 lines)
Lines 21-26 import org.apache.poi.hssf.usermodel.HSSFSheet; Link Here
21
import org.apache.poi.ss.formula.FormulaShifter;
21
import org.apache.poi.ss.formula.FormulaShifter;
22
import org.apache.poi.ss.formula.eval.NotImplementedException;
22
import org.apache.poi.ss.formula.eval.NotImplementedException;
23
import org.apache.poi.ss.usermodel.Row;
23
import org.apache.poi.ss.usermodel.Row;
24
import org.apache.poi.ss.usermodel.Sheet;
24
import org.apache.poi.ss.usermodel.helpers.RowShifter;
25
import org.apache.poi.ss.usermodel.helpers.RowShifter;
25
import org.apache.poi.util.Internal;
26
import org.apache.poi.util.Internal;
26
import org.apache.poi.util.NotImplemented;
27
import org.apache.poi.util.NotImplemented;
Lines 38-67 public final class HSSFRowShifter extends RowShifter { Link Here
38
    public HSSFRowShifter(HSSFSheet sh) {
39
    public HSSFRowShifter(HSSFSheet sh) {
39
        super(sh);
40
        super(sh);
40
    }
41
    }
42
    public HSSFRowShifter(Sheet sh, FormulaShifter shifter) {
43
        super(sh, shifter);
44
    }
41
45
42
    @NotImplemented
46
    @NotImplemented
43
    public void updateNamedRanges(FormulaShifter shifter) {
47
    public void updateNamedRanges() {
44
        throw new NotImplementedException("HSSFRowShifter.updateNamedRanges");
48
        throw new NotImplementedException("HSSFRowShifter.updateNamedRanges");
45
    }
49
    }
46
50
47
    @NotImplemented
51
    @NotImplemented
48
    public void updateFormulas(FormulaShifter shifter) {
52
    public void updateFormulas() {
49
        throw new NotImplementedException("updateFormulas");
53
        throw new NotImplementedException("updateFormulas");
50
    }
54
    }
51
55
52
    @Internal
56
    @Internal
53
    @NotImplemented
57
    @NotImplemented
54
    public void updateRowFormulas(Row row, FormulaShifter shifter) {
58
    public void updateRowFormulas(Row row) {
55
        throw new NotImplementedException("updateRowFormulas");
59
        throw new NotImplementedException("updateRowFormulas");
56
    }
60
    }
57
61
58
    @NotImplemented
62
    @NotImplemented
59
    public void updateConditionalFormatting(FormulaShifter shifter) {
63
    public void updateConditionalFormatting() {
60
        throw new NotImplementedException("updateConditionalFormatting");
64
        throw new NotImplementedException("updateConditionalFormatting");
61
    }
65
    }
62
    
66
    
63
    @NotImplemented
67
    @NotImplemented
64
    public void updateHyperlinks(FormulaShifter shifter) {
68
    public void updateHyperlinks() {
65
        throw new NotImplementedException("updateHyperlinks");
69
        throw new NotImplementedException("updateHyperlinks");
66
    }
70
    }
67
71
(-)a/src/java/org/apache/poi/ss/usermodel/helpers/RowShifter.java (-5 / +11 lines)
Lines 37-47 import org.apache.poi.util.POILogger; Link Here
37
 */
37
 */
38
public abstract class RowShifter {
38
public abstract class RowShifter {
39
    protected final Sheet sheet;
39
    protected final Sheet sheet;
40
    protected FormulaShifter shifter;
40
41
41
    public RowShifter(Sheet sh) {
42
    public RowShifter(Sheet sh) {
42
        sheet = sh;
43
        sheet = sh;
43
    }
44
    }
44
45
46
    public RowShifter(Sheet sh, FormulaShifter shifter) {
47
        sheet = sh;
48
        this.shifter = shifter;
49
    }
50
45
    /**
51
    /**
46
     * Shifts, grows, or shrinks the merged regions due to a row shift.
52
     * Shifts, grows, or shrinks the merged regions due to a row shift.
47
     * Merged regions that are completely overlaid by shifting will be deleted.
53
     * Merged regions that are completely overlaid by shifting will be deleted.
Lines 97-108 public abstract class RowShifter { Link Here
97
    /**
103
    /**
98
     * Updated named ranges
104
     * Updated named ranges
99
     */
105
     */
100
    public abstract void updateNamedRanges(FormulaShifter shifter);
106
    public abstract void updateNamedRanges();
101
107
102
    /**
108
    /**
103
     * Update formulas.
109
     * Update formulas.
104
     */
110
     */
105
    public abstract void updateFormulas(FormulaShifter shifter);
111
    public abstract void updateFormulas();
106
112
107
    /**
113
    /**
108
     * Update the formulas in specified row using the formula shifting policy specified by shifter
114
     * Update the formulas in specified row using the formula shifting policy specified by shifter
Lines 111-119 public abstract class RowShifter { Link Here
111
     * @param shifter the formula shifting policy
117
     * @param shifter the formula shifting policy
112
     */
118
     */
113
    @Internal
119
    @Internal
114
    public abstract void updateRowFormulas(Row row, FormulaShifter shifter);
120
    public abstract void updateRowFormulas(Row row);
115
121
116
    public abstract void updateConditionalFormatting(FormulaShifter shifter);
122
    public abstract void updateConditionalFormatting();
117
    
123
    
118
    /**
124
    /**
119
     * Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink
125
     * Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink
Lines 122-127 public abstract class RowShifter { Link Here
122
     *
128
     *
123
     * @param shifter the formula shifting policy
129
     * @param shifter the formula shifting policy
124
     */
130
     */
125
    public abstract void updateHyperlinks(FormulaShifter shifter);
131
    public abstract void updateHyperlinks();
126
132
127
}
133
}
(-)a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java (-2 / +2 lines)
Lines 640-653 public class XSSFRow implements Row, Comparable<XSSFRow> { Link Here
640
                destCell.copyCellFrom(srcCell, policy);
640
                destCell.copyCellFrom(srcCell, policy);
641
            }
641
            }
642
642
643
            final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet);
644
            final int sheetIndex = _sheet.getWorkbook().getSheetIndex(_sheet);
643
            final int sheetIndex = _sheet.getWorkbook().getSheetIndex(_sheet);
645
            final String sheetName = _sheet.getWorkbook().getSheetName(sheetIndex);
644
            final String sheetName = _sheet.getWorkbook().getSheetName(sheetIndex);
646
            final int srcRowNum = srcRow.getRowNum();
645
            final int srcRowNum = srcRow.getRowNum();
647
            final int destRowNum = getRowNum();
646
            final int destRowNum = getRowNum();
648
            final int rowDifference = destRowNum - srcRowNum;
647
            final int rowDifference = destRowNum - srcRowNum;
649
            final FormulaShifter shifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007);
648
            final FormulaShifter shifter = FormulaShifter.createForRowCopy(sheetIndex, sheetName, srcRowNum, srcRowNum, rowDifference, SpreadsheetVersion.EXCEL2007);
650
            rowShifter.updateRowFormulas(this, shifter);
649
            final XSSFRowShifter rowShifter = new XSSFRowShifter(_sheet, shifter);
650
            rowShifter.updateRowFormulas(this);
651
651
652
            // Copy merged regions that are fully contained on the row
652
            // Copy merged regions that are fully contained on the row
653
            // FIXME: is this something that rowShifter could be doing?
653
            // FIXME: is this something that rowShifter could be doing?
(-)a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java (-31 / +36 lines)
Lines 2943-2950 public class XSSFSheet extends POIXMLDocumentPart implements Sheet { Link Here
2943
    @Override
2943
    @Override
2944
    public void shiftRows(int startRow, int endRow, final int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
2944
    public void shiftRows(int startRow, int endRow, final int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
2945
        XSSFVMLDrawing vml = getVMLDrawing(false);
2945
        XSSFVMLDrawing vml = getVMLDrawing(false);
2946
        removeOverwritten(vml, startRow, endRow, n);
2947
        doShifting(vml, startRow, endRow, n, copyRowHeight); 
2948
        
2949
        
2950
        int sheetIndex = getWorkbook().getSheetIndex(this);
2951
        String sheetName = getWorkbook().getSheetName(sheetIndex);
2952
        FormulaShifter shifter = FormulaShifter.createForRowShift(
2953
                                   sheetIndex, sheetName, startRow, endRow, n, SpreadsheetVersion.EXCEL2007);
2954
        XSSFRowShifter rowShifter = new XSSFRowShifter(this, shifter);
2946
2955
2947
        // first remove all rows which will be overwritten
2956
        rowShifter.updateNamedRanges();
2957
        rowShifter.updateFormulas();
2958
        rowShifter.shiftMergedRegions(startRow, endRow, n);
2959
        rowShifter.updateConditionalFormatting();
2960
        rowShifter.updateHyperlinks();
2961
2962
        //rebuild the _rows map
2963
        Map<Integer, XSSFRow> map = new HashMap<Integer, XSSFRow>();
2964
        for(XSSFRow r : _rows.values()) {
2965
            // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory
2966
            final Integer rownumI = new Integer(r.getRowNum()); // NOSONAR
2967
            map.put(rownumI, r);
2968
        }
2969
        _rows.clear();
2970
        _rows.putAll(map);
2971
    }
2972
    
2973
    // remove all rows which will be overwritten
2974
    private void removeOverwritten(XSSFVMLDrawing vml, int startRow, int endRow, final int n){
2948
        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
2975
        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
2949
            XSSFRow row = (XSSFRow)it.next();
2976
            XSSFRow row = (XSSFRow)it.next();
2950
            int rownum = row.getRowNum();
2977
            int rownum = row.getRowNum();
Lines 2987-2996 public class XSSFSheet extends POIXMLDocumentPart implements Sheet { Link Here
2987
                }
3014
                }
2988
            }
3015
            }
2989
        }
3016
        }
2990
3017
    }
2991
        // then do the actual moving and also adjust comments/rowHeight
3018
    
2992
        // we need to sort it in a way so the shifting does not mess up the structures, 
3019
    // do the actual moving and also adjust comments/rowHeight
2993
        // i.e. when shifting down, start from down and go up, when shifting up, vice-versa
3020
    // we need to sort it in a way so the shifting does not mess up the structures, 
3021
    // i.e. when shifting down, start from down and go up, when shifting up, vice-versa
3022
    private void doShifting(XSSFVMLDrawing vml, int startRow, int endRow, final int n, boolean copyRowHeight){
2994
        SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<XSSFComment, Integer>(new Comparator<XSSFComment>() {
3023
        SortedMap<XSSFComment, Integer> commentsToShift = new TreeMap<XSSFComment, Integer>(new Comparator<XSSFComment>() {
2995
            @Override
3024
            @Override
2996
            public int compare(XSSFComment o1, XSSFComment o2) {
3025
            public int compare(XSSFComment o1, XSSFComment o2) {
Lines 3012-3018 public class XSSFSheet extends POIXMLDocumentPart implements Sheet { Link Here
3012
                }
3041
                }
3013
            }
3042
            }
3014
        });
3043
        });
3015
3016
        
3044
        
3017
        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
3045
        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
3018
            XSSFRow row = (XSSFRow)it.next();
3046
            XSSFRow row = (XSSFRow)it.next();
Lines 3045-3055 public class XSSFSheet extends POIXMLDocumentPart implements Sheet { Link Here
3045
            if(rownum < startRow || rownum > endRow) {
3073
            if(rownum < startRow || rownum > endRow) {
3046
                continue;
3074
                continue;
3047
            }
3075
            }
3048
3049
            if (!copyRowHeight) {
3076
            if (!copyRowHeight) {
3050
                row.setHeight((short)-1);
3077
                row.setHeight((short)-1);
3051
            }
3078
            }
3052
3053
            row.shift(n);
3079
            row.shift(n);
3054
        }
3080
        }
3055
        
3081
        
Lines 3059-3088 public class XSSFSheet extends POIXMLDocumentPart implements Sheet { Link Here
3059
        for(Map.Entry<XSSFComment, Integer> entry : commentsToShift.entrySet()) {
3085
        for(Map.Entry<XSSFComment, Integer> entry : commentsToShift.entrySet()) {
3060
            entry.getKey().setRow(entry.getValue());
3086
            entry.getKey().setRow(entry.getValue());
3061
        }
3087
        }
3062
        
3088
    	
3063
        XSSFRowShifter rowShifter = new XSSFRowShifter(this);
3064
3065
        int sheetIndex = getWorkbook().getSheetIndex(this);
3066
        String sheetName = getWorkbook().getSheetName(sheetIndex);
3067
        FormulaShifter shifter = FormulaShifter.createForRowShift(
3068
                                   sheetIndex, sheetName, startRow, endRow, n, SpreadsheetVersion.EXCEL2007);
3069
3070
        rowShifter.updateNamedRanges(shifter);
3071
        rowShifter.updateFormulas(shifter);
3072
        rowShifter.shiftMergedRegions(startRow, endRow, n);
3073
        rowShifter.updateConditionalFormatting(shifter);
3074
        rowShifter.updateHyperlinks(shifter);
3075
3076
        //rebuild the _rows map
3077
        Map<Integer, XSSFRow> map = new HashMap<Integer, XSSFRow>();
3078
        for(XSSFRow r : _rows.values()) {
3079
            // Performance optimization: explicit boxing is slightly faster than auto-unboxing, though may use more memory
3080
            final Integer rownumI = new Integer(r.getRowNum()); // NOSONAR
3081
            map.put(rownumI, r);
3082
        }
3083
        _rows.clear();
3084
        _rows.putAll(map);
3085
    }
3089
    }
3090
    
3086
3091
3087
    private int shiftedRowNum(int startRow, int endRow, int n, int rownum) {
3092
    private int shiftedRowNum(int startRow, int endRow, int n, int rownum) {
3088
        // no change if before any affected row
3093
        // no change if before any affected row
(-)a/src/ooxml/java/org/apache/poi/xssf/usermodel/helpers/XSSFRowShifter.java (-14 / +16 lines)
Lines 19-25 package org.apache.poi.xssf.usermodel.helpers; Link Here
19
19
20
import java.util.ArrayList;
20
import java.util.ArrayList;
21
import java.util.List;
21
import java.util.List;
22
23
import org.apache.poi.ss.formula.FormulaParseException;
22
import org.apache.poi.ss.formula.FormulaParseException;
24
import org.apache.poi.ss.formula.FormulaParser;
23
import org.apache.poi.ss.formula.FormulaParser;
25
import org.apache.poi.ss.formula.FormulaRenderer;
24
import org.apache.poi.ss.formula.FormulaRenderer;
Lines 63-68 public final class XSSFRowShifter extends RowShifter { Link Here
63
    public XSSFRowShifter(XSSFSheet sh) {
62
    public XSSFRowShifter(XSSFSheet sh) {
64
        super(sh);
63
        super(sh);
65
    }
64
    }
65
    public XSSFRowShifter(Sheet sh, FormulaShifter shifter) {
66
        super(sh, shifter);
67
    }
68
    
66
    
69
    
67
    /**
70
    /**
68
     * Shift merged regions
71
     * Shift merged regions
Lines 80-86 public final class XSSFRowShifter extends RowShifter { Link Here
80
    /**
83
    /**
81
     * Updated named ranges
84
     * Updated named ranges
82
     */
85
     */
83
    public void updateNamedRanges(FormulaShifter shifter) {
86
    public void updateNamedRanges() {
84
        Workbook wb = sheet.getWorkbook();
87
        Workbook wb = sheet.getWorkbook();
85
        XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
88
        XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
86
        for (Name name : wb.getAllNames()) {
89
        for (Name name : wb.getAllNames()) {
Lines 99-120 public final class XSSFRowShifter extends RowShifter { Link Here
99
    /**
102
    /**
100
     * Update formulas.
103
     * Update formulas.
101
     */
104
     */
102
    public void updateFormulas(FormulaShifter shifter) {
105
    public void updateFormulas() {
103
        //update formulas on the parent sheet
106
        //update formulas on the parent sheet
104
        updateSheetFormulas(sheet, shifter);
107
        updateSheetFormulas(sheet);
105
108
106
        //update formulas on other sheets
109
        //update formulas on other sheets
107
        Workbook wb = sheet.getWorkbook();
110
        Workbook wb = sheet.getWorkbook();
108
        for (Sheet sh : wb) {
111
        for (Sheet sh : wb) {
109
            if (sheet == sh) continue;
112
            if (sheet == sh) continue;
110
            updateSheetFormulas(sh, shifter);
113
            updateSheetFormulas(sh);
111
        }
114
        }
112
    }
115
    }
113
116
114
    private void updateSheetFormulas(Sheet sh, FormulaShifter shifter) {
117
    private void updateSheetFormulas(Sheet sh) {
115
        for (Row r : sh) {
118
        for (Row r : sh) {
116
            XSSFRow row = (XSSFRow) r;
119
            XSSFRow row = (XSSFRow) r;
117
            updateRowFormulas(row, shifter);
120
            updateRowFormulas(row);
118
        }
121
        }
119
    }
122
    }
120
123
Lines 125-131 public final class XSSFRowShifter extends RowShifter { Link Here
125
     * @param shifter the formula shifting policy
128
     * @param shifter the formula shifting policy
126
     */
129
     */
127
    @Internal
130
    @Internal
128
    public void updateRowFormulas(Row row, FormulaShifter shifter) {
131
    public void updateRowFormulas(Row row) {
129
        XSSFSheet sheet = (XSSFSheet) row.getSheet();
132
        XSSFSheet sheet = (XSSFSheet) row.getSheet();
130
        for (Cell c : row) {
133
        for (Cell c : row) {
131
            XSSFCell cell = (XSSFCell) c;
134
            XSSFCell cell = (XSSFCell) c;
Lines 142-161 public final class XSSFRowShifter extends RowShifter { Link Here
142
                            int si = (int)f.getSi();
145
                            int si = (int)f.getSi();
143
                            CTCellFormula sf = sheet.getSharedFormula(si);
146
                            CTCellFormula sf = sheet.getSharedFormula(si);
144
                            sf.setStringValue(shiftedFormula);
147
                            sf.setStringValue(shiftedFormula);
145
                            updateRefInCTCellFormula(row, shifter, sf);
148
                            updateRefInCTCellFormula(row, sf);
146
                        }
149
                        }
147
                    }
150
                    }
148
151
149
                }
152
                }
150
153
151
                //Range of cells which the formula applies to.
154
                //Range of cells which the formula applies to.
152
                updateRefInCTCellFormula(row, shifter, f);
155
                updateRefInCTCellFormula(row, f);
153
            }
156
            }
154
157
155
        }
158
        }
156
    }
159
    }
157
160
158
    private void updateRefInCTCellFormula(Row row, FormulaShifter shifter, CTCellFormula f) {
161
    private void updateRefInCTCellFormula(Row row, CTCellFormula f) {
159
        if (f.isSetRef()) { //Range of cells which the formula applies to.
162
        if (f.isSetRef()) { //Range of cells which the formula applies to.
160
            String ref = f.getRef();
163
            String ref = f.getRef();
161
            String shiftedRef = shiftFormula(row, ref, shifter);
164
            String shiftedRef = shiftFormula(row, ref, shifter);
Lines 193-199 public final class XSSFRowShifter extends RowShifter { Link Here
193
        }
196
        }
194
    }
197
    }
195
198
196
    public void updateConditionalFormatting(FormulaShifter shifter) {
199
    public void updateConditionalFormatting() {
197
        XSSFSheet xsheet = (XSSFSheet) sheet;
200
        XSSFSheet xsheet = (XSSFSheet) sheet;
198
        XSSFWorkbook wb = xsheet.getWorkbook();
201
        XSSFWorkbook wb = xsheet.getWorkbook();
199
        int sheetIndex = wb.getSheetIndex(sheet);
202
        int sheetIndex = wb.getSheetIndex(sheet);
Lines 260-266 public final class XSSFRowShifter extends RowShifter { Link Here
260
     *
263
     *
261
     * @param shifter
264
     * @param shifter
262
     */
265
     */
263
    public void updateHyperlinks(FormulaShifter shifter) {
266
    public void updateHyperlinks() {
264
        int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
267
        int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
265
        List<? extends Hyperlink> hyperlinkList = sheet.getHyperlinkList();
268
        List<? extends Hyperlink> hyperlinkList = sheet.getHyperlinkList();
266
        
269
        
267
- 

Return to bug 61474