zhao
2021-07-02 23ee356c6f260ecc1a48bbb8bd60932b979e4698
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
/* ====================================================================
   Copyright 2002-2004   Apache Software Foundation
 
   Licensed 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.
==================================================================== */
 
namespace HH.WMS.Utils.NPOI.HSSF.Record
{
 
    using System;
    using System.Text;
    using System.IO;
    using System.Collections;
    using HH.WMS.Utils.NPOI.SS.Util;
 
    using HH.WMS.Utils.NPOI.SS.Formula;
    using HH.WMS.Utils.NPOI.Util;
 
    using HH.WMS.Utils.NPOI.SS.Formula.PTG;
    
 
 
    /**
     * Title:        DATAVALIDATION Record (0x01BE)<p/>
     * Description:  This record stores data validation Settings and a list of cell ranges
     *               which contain these Settings. The data validation Settings of a sheet
     *               are stored in a sequential list of DV records. This list Is followed by
     *               DVAL record(s)
     * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
     * @version 2.0-pre
     */
    public class DVRecord : StandardRecord
    {
        private static UnicodeString NULL_TEXT_STRING = new UnicodeString("\0");
 
 
        public const short sid = 0x01BE;
        /** Option flags */
        private int _option_flags;
        /** Title of the prompt box */
        private UnicodeString _promptTitle;
        /** Title of the error box */
        private UnicodeString _errorTitle;
        /** Text of the prompt box */
        private UnicodeString _promptText;
        /** Text of the error box */
        private UnicodeString _errorText;
        /** Not used - Excel seems to always write 0x3FE0 */
        private short _not_used_1 = 0x3FE0;
        /** Formula data for first condition (RPN token array without size field) */
        private HH.WMS.Utils.NPOI.SS.Formula.Formula _formula1;
        /** Not used - Excel seems to always write 0x0000 */
        private short _not_used_2 = 0x0000;
        /** Formula data for second condition (RPN token array without size field) */
        private HH.WMS.Utils.NPOI.SS.Formula.Formula _formula2;
        /** Cell range address list with all affected ranges */
        private CellRangeAddressList _regions;
 
 
        public static int STRING_PROMPT_TITLE = 0;
        public static int STRING_ERROR_TITLE = 1;
        public static int STRING_PROMPT_TEXT = 2;
        public static int STRING_ERROR_TEXT = 3;
 
        /**
         * Option flags field
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        private BitField opt_data_type = new BitField(0x0000000F);
        private BitField opt_error_style = new BitField(0x00000070);
        private BitField opt_string_list_formula = new BitField(0x00000080);
        private BitField opt_empty_cell_allowed = new BitField(0x00000100);
        private BitField opt_suppress_dropdown_arrow = new BitField(0x00000200);
        private BitField opt_show_prompt_on_cell_selected = new BitField(0x00040000);
        private BitField opt_show_error_on_invalid_value = new BitField(0x00080000);
        private BitField opt_condition_operator = new BitField(0x00F00000);
 
        public DVRecord()
        {
        }
        public DVRecord(int validationType, int operator1, int errorStyle, bool emptyCellAllowed,
            bool suppressDropDownArrow, bool isExplicitList,
            bool showPromptBox, String promptTitle, String promptText,
            bool showErrorBox, String errorTitle, String errorText,
            Ptg[] formula1, Ptg[] formula2,
            CellRangeAddressList regions)
        {
 
            int flags = 0;
            flags = opt_data_type.SetValue(flags, validationType);
            flags = opt_condition_operator.SetValue(flags, operator1);
            flags = opt_error_style.SetValue(flags, errorStyle);
            flags = opt_empty_cell_allowed.SetBoolean(flags, emptyCellAllowed);
            flags = opt_suppress_dropdown_arrow.SetBoolean(flags, suppressDropDownArrow);
            flags = opt_string_list_formula.SetBoolean(flags, isExplicitList);
            flags = opt_show_prompt_on_cell_selected.SetBoolean(flags, showPromptBox);
            flags = opt_show_error_on_invalid_value.SetBoolean(flags, showErrorBox);
            _option_flags = flags;
            _promptTitle = ResolveTitleText(promptTitle);
            _promptText = ResolveTitleText(promptText);
            _errorTitle = ResolveTitleText(errorTitle);
            _errorText = ResolveTitleText(errorText);
            _formula1 = HH.WMS.Utils.NPOI.SS.Formula.Formula.Create(formula1);
            _formula2 = HH.WMS.Utils.NPOI.SS.Formula.Formula.Create(formula2);
            _regions = regions;
        }
 
        /**
         * Constructs a DV record and Sets its fields appropriately.
         *
         * @param in the RecordInputstream to Read the record from
         */
 
        public DVRecord(RecordInputStream in1)
        {
            _option_flags = in1.ReadInt();
 
            _promptTitle = ReadUnicodeString(in1);
            _errorTitle = ReadUnicodeString(in1);
            _promptText = ReadUnicodeString(in1);
            _errorText = ReadUnicodeString(in1);
 
            int field_size_first_formula = in1.ReadUShort();
            _not_used_1 = in1.ReadShort();
 
            //read first formula data condition
            _formula1 = HH.WMS.Utils.NPOI.SS.Formula.Formula.Read(field_size_first_formula, in1);
 
            int field_size_sec_formula = in1.ReadUShort();
            _not_used_2 = in1.ReadShort();
 
            //read sec formula data condition
            _formula2 = HH.WMS.Utils.NPOI.SS.Formula.Formula.Read(field_size_sec_formula, in1);
 
            //read cell range address list with all affected ranges
            _regions = new CellRangeAddressList(in1);
        }
        /**
     * When entered via the UI, Excel translates empty string into "\0"
     * While it is possible to encode the title/text as empty string (Excel doesn't exactly crash),
     * the resulting tool-tip text / message box looks wrong.  It is best to do the same as the 
     * Excel UI and encode 'not present' as "\0". 
     */
        private static UnicodeString ResolveTitleText(String str)
        {
            if (str == null || str.Length < 1)
            {
                return NULL_TEXT_STRING;
            }
            return new UnicodeString(str);
        }
 
        private static UnicodeString ReadUnicodeString(RecordInputStream in1)
        {
            return new UnicodeString(in1);
        }
        /**
         * Get the condition data type
         * @return the condition data type
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public int DataType
        {
            get
            {
                return this.opt_data_type.GetValue(this._option_flags);
            }
            set { this._option_flags = this.opt_data_type.SetValue(this._option_flags, value); }
        }
 
 
 
        /**
         * Get the condition error style
         * @return the condition error style
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public int ErrorStyle
        {
            get
            {
                return this.opt_error_style.GetValue(this._option_flags);
            }
            set { this._option_flags = this.opt_error_style.SetValue(this._option_flags, value); }
        }
 
 
        /**
         * return true if in list validations the string list Is explicitly given in the formula, false otherwise
         * @return true if in list validations the string list Is explicitly given in the formula, false otherwise
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public bool ListExplicitFormula
        {
            get
            {
                return (this.opt_string_list_formula.IsSet(this._option_flags));
            }
            set { this._option_flags = this.opt_string_list_formula.SetBoolean(this._option_flags, value); }
        }
 
 
 
        /**
         * return true if empty values are allowed in cells, false otherwise
         * @return if empty values are allowed in cells, false otherwise
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public bool EmptyCellAllowed
        {
            get
            {
                return (this.opt_empty_cell_allowed.IsSet(this._option_flags));
            }
            set { this._option_flags = this.opt_empty_cell_allowed.SetBoolean(this._option_flags, value); }
        }
 
 
        /**
         * return true if a prompt window should appear when cell Is selected, false otherwise
         * @return if a prompt window should appear when cell Is selected, false otherwise
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public bool ShowPromptOnCellSelected
        {
            get
            {
                return (this.opt_show_prompt_on_cell_selected.IsSet(this._option_flags));
            }
        }
 
 
        /**
         * return true if an error window should appear when an invalid value Is entered in the cell, false otherwise
         * @return if an error window should appear when an invalid value Is entered in the cell, false otherwise
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public bool ShowErrorOnInvalidValue
        {
            get
            {
                return (this.opt_show_error_on_invalid_value.IsSet(this._option_flags));
            }
            set { this._option_flags = this.opt_show_error_on_invalid_value.SetBoolean(this._option_flags, value); }
        }
 
 
 
        /**
         * Get the condition operator
         * @return the condition operator
         * @see org.apache.poi.hssf.util.HSSFDataValidation utility class
         */
        public int ConditionOperator
        {
            get
            {
                return this.opt_condition_operator.GetValue(this._option_flags);
            }
            set
            {
                this._option_flags = this.opt_condition_operator.SetValue(this._option_flags, value);
            }
        }
 
 
 
        public CellRangeAddressList CellRangeAddress
        {
            get
            {
                return this._regions;
            }
            set { this._regions = value; }
        }
 
        /**
         * Gets the option flags field.
         * @return options - the option flags field
         */
        public int OptionFlags
        {
            get
            {
                return this._option_flags;
            }
        }
 
        public override String ToString()
        {
            /* @todo DVRecord string representation */
            StringBuilder buffer = new StringBuilder();
 
            return buffer.ToString();
        }
 
        public override void Serialize(ILittleEndianOutput out1)
        {
 
            out1.WriteInt(_option_flags);
 
            SerializeUnicodeString(_promptTitle, out1);
            SerializeUnicodeString(_errorTitle, out1);
            SerializeUnicodeString(_promptText, out1);
            SerializeUnicodeString(_errorText, out1);
            out1.WriteShort(_formula1.EncodedTokenSize);
            out1.WriteShort(_not_used_1);
            _formula1.SerializeTokens(out1);
 
            out1.WriteShort(_formula2.EncodedTokenSize);
            out1.WriteShort(_not_used_2);
            _formula2.SerializeTokens(out1);
 
            _regions.Serialize(out1);
        }
        private static void SerializeUnicodeString(UnicodeString us, ILittleEndianOutput out1)
        {
            StringUtil.WriteUnicodeString(out1, us.String);
        }
 
        private static int GetUnicodeStringSize(UnicodeString us)
        {
            String str = us.String;
            return 3 + str.Length * (StringUtil.HasMultibyte(str) ? 2 : 1);
        }
        protected override int DataSize
        {
            get
            {
                int size = 4 + 2 + 2 + 2 + 2;//header+options_field+first_formula_size+first_unused+sec_formula_size+sec+unused;
                size += GetUnicodeStringSize(_promptTitle);
                size += GetUnicodeStringSize(_errorTitle);
                size += GetUnicodeStringSize(_promptText);
                size += GetUnicodeStringSize(_errorText);
                size += _formula1.EncodedTokenSize;
                size += _formula2.EncodedTokenSize;
                size += _regions.Size;
                return size;
            }
        }
 
        public override short Sid
        {
            get { return DVRecord.sid; }
        }
 
        /**
         * Clones the object. Uses serialisation, as the
         *  contents are somewhat complex
         */
        public override Object Clone()
        {
            return CloneViaReserialise();
        }
    }
}