LibreOffice Module android (master) 1
CalcHeadersController.java
Go to the documentation of this file.
1package org.libreoffice.overlay;
2
3import android.content.Context;
4import android.graphics.PointF;
5import android.graphics.RectF;
6import android.graphics.drawable.ColorDrawable;
7import com.google.android.material.snackbar.Snackbar;
8import android.util.Log;
9import android.view.KeyEvent;
10import android.view.Gravity;
11import android.view.LayoutInflater;
12import android.view.View;
13import android.view.ViewGroup.LayoutParams;
14import android.view.inputmethod.EditorInfo;
15import android.widget.EditText;
16import android.widget.Button;
17import android.widget.PopupWindow;
18import android.widget.TextView;
19
20import org.json.JSONArray;
21import org.json.JSONException;
22import org.json.JSONObject;
26import org.libreoffice.R;
28
29import java.math.BigDecimal;
30import java.util.ArrayList;
31
33
35 private static final String LOGTAG = CalcHeadersController.class.getSimpleName();
36
39
41
42 public CalcHeadersController(LibreOfficeMainActivity context, final LayerView layerView) {
43 mContext = context;
45 mCalcRowHeadersView = context.findViewById(R.id.calc_header_row);
46 mCalcColumnHeadersView = context.findViewById(R.id.calc_header_column);
47 if (mCalcColumnHeadersView == null || mCalcRowHeadersView == null) {
48 Log.e(LOGTAG, "Failed to initialize Calc headers - View is null");
49 } else {
50 mCalcRowHeadersView.initialize(layerView, true);
51 mCalcColumnHeadersView.initialize(layerView, false);
52 }
54 context.findViewById(R.id.calc_header_top_left).setOnClickListener(new View.OnClickListener() {
55 @Override
56 public void onClick(View v) {
57 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SelectAll"));
58 if (mCalcColumnHeadersView == null) return;
59 mCalcColumnHeadersView.showHeaderPopup(new PointF());
60 }
61 });
62 ((EditText)context.findViewById(R.id.calc_address)).setOnEditorActionListener(new TextView.OnEditorActionListener() {
63 @Override
64 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
65 if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_GO) {
66 String text = v.getText().toString();
67 JSONObject rootJson = new JSONObject();
68 try {
69 addProperty(rootJson, "ToPoint", "string", text);
70 } catch (JSONException e) {
71 e.printStackTrace();
72 }
73 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:GoToCell", rootJson.toString()));
75 layerView.requestFocus();
76 }
77 return true;
78 }
79 });
80 ((EditText)context.findViewById(R.id.calc_formula)).setOnEditorActionListener(new TextView.OnEditorActionListener() {
81 @Override
82 public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
83 if (actionId == EditorInfo.IME_ACTION_DONE || actionId == EditorInfo.IME_ACTION_GO) {
84 String text = v.getText().toString();
85 JSONObject rootJson = new JSONObject();
86 try {
87 addProperty(rootJson, "StringName", "string", text);
88 addProperty(rootJson, "DontCommit", "boolean", String.valueOf(false));
89 } catch (JSONException e) {
90 e.printStackTrace();
91 }
92 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:EnterString", rootJson.toString()));
94 layerView.requestFocus();
96 }
97 return true;
98 }
99 });
100 // manually select A1 for address bar and formula bar to update when calc first opens
101 JSONObject rootJson = new JSONObject();
102 try {
103 addProperty(rootJson, "ToPoint", "string", "A1");
104 } catch (JSONException e) {
105 e.printStackTrace();
106 }
107 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:GoToCell", rootJson.toString()));
108 }
109
110 public void setupHeaderPopupView() {
111 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
112 String[] rowOrColumn = {"Row","Column"};
113 CalcHeadersView[] headersViews= {mCalcRowHeadersView, mCalcColumnHeadersView};
114 for (int i = 0; i < rowOrColumn.length; i++) {
115 // create popup window
116 final String tempName = rowOrColumn[i];
117 final CalcHeadersView tempView = headersViews[i];
118 final View headerPopupView = inflater.inflate(R.layout.calc_header_popup, null);
119 final PopupWindow popupWindow = new PopupWindow(headerPopupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
120 popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
121 @Override
122 public void onDismiss() {
123 headerPopupView.findViewById(R.id.calc_header_popup_optimal_length_dialog).setVisibility(View.GONE);
124 popupWindow.setFocusable(false);
125 }
126 });
127 popupWindow.setOutsideTouchable(true);
128 popupWindow.setBackgroundDrawable(new ColorDrawable());
129 popupWindow.setAnimationStyle(android.R.style.Animation_Dialog);
130 tempView.setHeaderPopupWindow(popupWindow);
131 // set up child views in the popup window
132 headerPopupView.findViewById(R.id.calc_header_popup_insert).setOnClickListener(new View.OnClickListener() {
133 @Override
134 public void onClick(View v) {
135 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Insert"+tempName+"s"));
136 tempView.dismissPopupWindow();
137 mContext.setDocumentChanged(true);
138 }
139 });
140 headerPopupView.findViewById(R.id.calc_header_popup_delete).setOnClickListener(new View.OnClickListener() {
141 @Override
142 public void onClick(View v) {
143 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Delete"+tempName+"s"));
144 tempView.dismissPopupWindow();
145 mContext.setDocumentChanged(true);
146 }
147 });
148 headerPopupView.findViewById(R.id.calc_header_popup_hide).setOnClickListener(new View.OnClickListener() {
149 @Override
150 public void onClick(View v) {
151 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Hide"+tempName));
152 tempView.dismissPopupWindow();
153 mContext.setDocumentChanged(true);
154 }
155 });
156 headerPopupView.findViewById(R.id.calc_header_popup_show).setOnClickListener(new View.OnClickListener() {
157 @Override
158 public void onClick(View v) {
159 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Show"+tempName));
160 tempView.dismissPopupWindow();
161 mContext.setDocumentChanged(true);
162 }
163 });
164 headerPopupView.findViewById(R.id.calc_header_popup_optimal_length).setOnClickListener(new View.OnClickListener() {
165 @Override
166 public void onClick(View v) {
167 View view = headerPopupView.findViewById(R.id.calc_header_popup_optimal_length_dialog);
168 if (view.getVisibility() == View.VISIBLE) {
169 view.setVisibility(View.GONE);
170 popupWindow.setFocusable(false);
171 popupWindow.update();
172 } else {
173 popupWindow.dismiss();
174 view.setVisibility(View.VISIBLE);
175 popupWindow.setFocusable(true);
176 popupWindow.showAtLocation(tempView, Gravity.CENTER, 0, 0);
177 LOKitShell.getMainHandler().post(new Runnable() {
178 @Override
179 public void run() {
180 Snackbar.make(tempView, R.string.calc_alert_double_click_optimal_length, Snackbar.LENGTH_LONG).show();
181 }
182 });
183 }
184 }
185 });
186 headerPopupView.findViewById(R.id.calc_header_popup_optimal_length_button).setOnClickListener(new View.OnClickListener() {
187 @Override
188 public void onClick(View v) {
189 String text = ((EditText)headerPopupView.findViewById(R.id.calc_header_popup_optimal_length_text)).getText().toString();
190 tempView.sendOptimalLengthRequest(text);
191 tempView.dismissPopupWindow();
192 mContext.setDocumentChanged(true);
193 }
194 });
195 headerPopupView.findViewById(R.id.calc_header_popup_adjust_length).setOnClickListener(new View.OnClickListener() {
196 @Override
197 public void onClick(View v) {
198 mContext.getDocumentOverlay().showAdjustLengthLine(tempView == mCalcRowHeadersView, tempView);
199 tempView.dismissPopupWindow();
200 mContext.setDocumentChanged(true);
201 }
202 });
203 ((Button)headerPopupView.findViewById(R.id.calc_header_popup_adjust_length))
204 .setText(tempView == mCalcRowHeadersView ? R.string.calc_adjust_height : R.string.calc_adjust_width);
205 ((Button)headerPopupView.findViewById(R.id.calc_header_popup_optimal_length))
206 .setText(tempView == mCalcRowHeadersView ? R.string.calc_optimal_height : R.string.calc_optimal_width);
207
208 }
209 }
210
211 public void setHeaders(String headers) {
212 HeaderInfo parsedHeaders = parseHeaderInfo(headers);
213 if (parsedHeaders != null) {
214 mCalcRowHeadersView.setHeaders(parsedHeaders.rowLabels, parsedHeaders.rowDimens);
215 mCalcColumnHeadersView.setHeaders(parsedHeaders.columnLabels, parsedHeaders.columnDimens);
216 showHeaders();
217 } else {
218 Log.e(LOGTAG, "Parse header info JSON failed.");
219 }
220 }
221
222 public void showHeaders() {
223 LOKitShell.getMainHandler().post(new Runnable() {
224 @Override
225 public void run() {
226 mCalcColumnHeadersView.invalidate();
227 mCalcRowHeadersView.invalidate();
228 }
229 });
230 }
231
232 private HeaderInfo parseHeaderInfo(String headers) {
233 HeaderInfo headerInfo = new HeaderInfo();
234 try {
235 JSONObject collectiveResult = new JSONObject(headers);
236 JSONArray rowResult = collectiveResult.getJSONArray("rows");
237 for (int i = 0; i < rowResult.length(); i++) {
238 headerInfo.rowLabels.add(rowResult.getJSONObject(i).getString("text"));
239 headerInfo.rowDimens.add(BigDecimal.valueOf(rowResult.getJSONObject(i).getLong("size")).floatValue());
240 }
241 JSONArray columnResult = collectiveResult.getJSONArray("columns");
242 for (int i = 0; i < columnResult.length(); i++) {
243 headerInfo.columnLabels.add(columnResult.getJSONObject(i).getString("text"));
244 headerInfo.columnDimens.add(BigDecimal.valueOf(columnResult.getJSONObject(i).getLong("size")).floatValue());
245 }
246 return headerInfo;
247 } catch (JSONException e) {
248 e.printStackTrace();
249 }
250 return null;
251 }
252
253 public void showHeaderSelection(RectF cellCursorRect) {
254 mCalcRowHeadersView.setHeaderSelection(cellCursorRect);
255 mCalcColumnHeadersView.setHeaderSelection(cellCursorRect);
256 showHeaders();
257 }
258
260 mCalcRowHeadersView.setPendingRowOrColumnSelectionToShowUp(b);
261 mCalcColumnHeadersView.setPendingRowOrColumnSelectionToShowUp(b);
262 }
263
265 return mCalcColumnHeadersView.pendingRowOrColumnSelectionToShowUp()
266 || mCalcRowHeadersView.pendingRowOrColumnSelectionToShowUp();
267 }
268
269 private class HeaderInfo {
270 ArrayList<String> rowLabels;
271 ArrayList<Float> rowDimens;
272 ArrayList<String> columnLabels;
273 ArrayList<Float> columnDimens;
274 private HeaderInfo() {
275 rowLabels = new ArrayList<String>();
276 rowDimens = new ArrayList<Float>();
277 columnDimens = new ArrayList<Float>();
278 columnLabels = new ArrayList<String>();
279 }
280 }
281}
#define LOGTAG
@ Button
Events and data that is queued and processed by LOKitThread.
Definition: LOEvent.java:21
static final int UPDATE_CALC_HEADERS
Definition: LOEvent.java:40
Common static LOKit functions, functions to send events.
Definition: LOKitShell.java:26
static void sendEvent(LOEvent event)
Make sure LOKitThread is running and send event to it.
Definition: LOKitShell.java:72
static Handler getMainHandler()
Definition: LOKitShell.java:36
Main activity of the LibreOffice App.
void hideSoftKeyboard()
Hides software keyboard on UI thread.
static void addProperty(JSONObject json, String parentValue, String type, String value)
CalcHeadersController(LibreOfficeMainActivity context, final LayerView layerView)
void setHeaders(ArrayList< String > labels, ArrayList< Float > dimens)
void initialize(LayerView layerView, boolean isRow)
void setHeaderSelection(RectF cellCursorRect)
void setCalcHeadersController(CalcHeadersController calcHeadersController)
A view rendered by the layer compositor.
Definition: LayerView.java:41
float v
def text(shape, orig_st)
def run(arg=None, arg2=-1)
int i
const sal_uInt8 R