1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components/picker/picker_multitext_component.h"
17 
18 namespace OHOS::Ace {
19 
OnTitleBuilding()20 void PickerMultiTextComponent::OnTitleBuilding()
21 {
22     PickerBaseComponent::OnTitleBuilding();
23     SetHasTitle(false);
24 }
25 
OnColumnsBuilding()26 void PickerMultiTextComponent::OnColumnsBuilding()
27 {
28     for (uint32_t index = 0; index < columnCount_; ++index) {
29         if (index >= range_.size()) {
30             LOGW("range size is smaller than column count");
31             auto emptyColumn = GetColumn(std::to_string(index));
32             if (emptyColumn) {
33                 emptyColumn->ClearOption();
34                 emptyColumn->AppendOption("");
35                 emptyColumn->SetCurrentIndex(0);
36             } else {
37                 LOGE("the column of index[%{private}u] not exists.", index);
38             }
39             continue;
40         }
41         const auto& textRange = range_[index];
42         auto column = GetColumn(std::to_string(index));
43         if (!column) {
44             LOGE("the column of index[%{private}u] not exists.", index);
45             continue;
46         }
47         column->ClearOption();
48         for (uint32_t subIndex = 0; subIndex < textRange.size(); ++subIndex) {
49             column->AppendOption(textRange[subIndex]);
50         }
51         if (index < selectedIndexes_.size()) {
52             selectedIndexes_[index] = textRange.empty() ? 0 : selectedIndexes_[index] % textRange.size();
53             column->SetCurrentIndex(selectedIndexes_[index]);
54         } else {
55             LOGE("array size of selected is not equal range.");
56         }
57     }
58 }
59 
GetSelectedObject(bool isColumnChange,const std::string & changeColumnTag,int32_t status) const60 std::string PickerMultiTextComponent::GetSelectedObject(bool isColumnChange,
61     const std::string& changeColumnTag, int32_t status) const
62 {
63     auto container = Container::Current();
64     if (!container) {
65         return "";
66     }
67     auto context = container->GetPipelineContext();
68     if (!context) {
69         return "";
70     }
71 
72     if (isColumnChange) {
73         auto column = GetColumn(changeColumnTag);
74         if (!column) {
75             LOGE("can not get the changed column.");
76             return "";
77         }
78         if (context->GetIsDeclarative()) {
79             return std::string("{\"column\":") + changeColumnTag + ",\"value\":" + "\"" +
80                 column->GetCurrentText() + "\"" + ",\"index\":" + std::to_string(column->GetCurrentIndex()) + "}";
81         } else {
82             return std::string("{\"column\":") + changeColumnTag + ",\"newValue\":" + "\"" +
83                 column->GetCurrentText() + "\"" + ",\"newSelected\":" + std::to_string(column->GetCurrentIndex()) + "}";
84         }
85     }
86 
87     std::string result = "{\"newValue\":[";
88     if (context->GetIsDeclarative()) {
89         result = "{\"value\":[";
90     }
91     for (uint32_t index = 0; index < selectedValues_.size(); ++index) {
92         if (index == 0) {
93             result.append("\"");
94         } else {
95             result.append(",\"");
96         }
97         result.append(selectedValues_[index]);
98         result.append("\"");
99     }
100     if (context->GetIsDeclarative()) {
101         result.append("],\"index\":[");
102     } else {
103         result.append("],\"newSelected\":[");
104     }
105     for (uint32_t index = 0; index < selectedIndexes_.size(); ++index) {
106         if (index != 0) {
107             result.append(",");
108         }
109         result.append(std::to_string(selectedIndexes_[index]));
110     }
111     result.append("],\"status\":").append(std::to_string(status)).append("}");
112     return result;
113 }
114 
OnSelectedSaving()115 void PickerMultiTextComponent::OnSelectedSaving()
116 {
117     selectedIndexes_.clear();
118     selectedValues_.clear();
119     for (uint32_t index = 0; index < columnCount_; ++index) {
120         selectedIndexes_.emplace_back(0);
121         selectedValues_.emplace_back("");
122         auto column = GetColumn(std::to_string(index));
123         if (!column) {
124             LOGE("can not get column by index[%{private}u].", index);
125             continue;
126         }
127         selectedIndexes_[index] = column->GetCurrentIndex();
128         selectedValues_[index] = column->GetCurrentText();
129     }
130 }
131 
OnDataLinking(const std::string & tag,bool isAdd,uint32_t index,std::vector<std::string> & resultTags)132 void PickerMultiTextComponent::OnDataLinking(const std::string& tag, bool isAdd, uint32_t index,
133     std::vector<std::string>& resultTags)
134 {
135     for (uint32_t val = 0; val < columnCount_; ++val) {
136         resultTags.emplace_back(std::to_string(val));
137     }
138 }
139 
OnColumnsCreating()140 void PickerMultiTextComponent::OnColumnsCreating()
141 {
142     if (hasCreateColumn_) {
143         return;
144     }
145 
146     if (!columnCount_) {
147         if (range_.empty()) {
148             LOGE("did not set attribute of column count and initialize range is empty.");
149         } else {
150             columnCount_ = range_.size();
151         }
152     }
153 
154     ClearColumns();
155     for (uint32_t index = 0; index < columnCount_; ++index) {
156         auto column = AceType::MakeRefPtr<PickerColumnComponent>();
157         column->SetColumnTag(std::to_string(index));
158         column->AppendOption("");
159         AppendColumn(column);
160     }
161     hasCreateColumn_ = true;
162 }
163 
HandleRangeChange()164 void PickerMultiTextComponent::HandleRangeChange()
165 {
166     if (!GetIsDialog() || !IsDialogShowed()) {
167         return;
168     }
169 
170     auto column = GetColumn("0");
171     if (!column) {
172         LOGE("has no column now.");
173         return;
174     }
175 
176     auto backupIndexes = selectedIndexes_;
177     auto backupValues = selectedValues_;
178     OnSelectedSaving();
179     OnColumnsBuilding();
180     column->HandleChangeCallback(true, false);
181     selectedIndexes_ = backupIndexes;
182     selectedValues_ = backupValues;
183 }
184 
HandleSelectedChange()185 void PickerMultiTextComponent::HandleSelectedChange()
186 {
187     if (!GetIsDialog() || !IsDialogShowed()) {
188         return;
189     }
190 
191     auto column = GetColumn("0");
192     if (!column) {
193         LOGE("has no column now.");
194         return;
195     }
196 
197     OnColumnsBuilding();
198     column->HandleChangeCallback(true, false);
199 }
200 
IsEqualSelected(const std::vector<uint32_t> & value) const201 bool PickerMultiTextComponent::IsEqualSelected(const std::vector<uint32_t>& value) const
202 {
203     if (value.size() != selectedIndexes_.size()) {
204         return false;
205     }
206 
207     for (uint32_t index = 0; index < value.size(); ++index) {
208         if (value[index] != selectedIndexes_[index]) {
209             return false;
210         }
211     }
212 
213     return true;
214 }
215 
IsEqualRange(const std::vector<std::vector<std::string>> & value) const216 bool PickerMultiTextComponent::IsEqualRange(const std::vector<std::vector<std::string>>& value) const
217 {
218     if (value.size() != range_.size()) {
219         return false;
220     }
221 
222     for (uint32_t index = 0; index < value.size(); ++index) {
223         if (!IsEqualStrings(value[index], range_[index])) {
224             return false;
225         }
226     }
227 
228     return true;
229 }
230 
IsEqualStrings(const std::vector<std::string> & first,const std::vector<std::string> & second) const231 bool PickerMultiTextComponent::IsEqualStrings(const std::vector<std::string>& first,
232     const std::vector<std::string>& second) const
233 {
234     if (first.size() != second.size()) {
235         return false;
236     }
237 
238     for (uint32_t index = 0; index < first.size(); ++index) {
239         if (first[index] != second[index]) {
240             return false;
241         }
242     }
243 
244     return true;
245 }
246 
247 } // namespace OHOS::Ace
248