OSDN Git Service

CSV形式でエクスポートする部分を改修。
[gokigen/MeMoMa.git] / app / src / main / java / jp / sourceforge / gokigen / memoma / io / MeMoMaFileImportCsvProcess.java
1 package jp.sourceforge.gokigen.memoma.io;
2
3 import java.io.BufferedReader;
4 import java.io.FileReader;
5
6 import android.app.ProgressDialog;
7 import android.content.Context;
8 import android.content.SharedPreferences;
9 import android.net.Uri;
10 import android.os.AsyncTask;
11 import android.preference.PreferenceManager;
12 import android.util.Log;
13
14 import jp.sourceforge.gokigen.memoma.Main;
15 import jp.sourceforge.gokigen.memoma.R;
16 import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder;
17 import jp.sourceforge.gokigen.memoma.holders.PositionObject;
18
19 /**
20  *  データをファイルに保存するとき用 アクセスラッパ (非同期処理を実行)
21  *  
22  *  AsyncTask
23  *    MeMoMaObjectHolder : 実行時に渡すクラス(Param)
24  *    Integer    : 途中経過を伝えるクラス(Progress)
25  *    String     : 処理結果を伝えるクラス(Result)
26  *    
27  * @author MRSa
28  *
29  */
30 public class MeMoMaFileImportCsvProcess extends AsyncTask<MeMoMaObjectHolder, Integer, String> implements MeMoMaFileSavingProcess.ISavingStatusHolder, MeMoMaFileSavingProcess.IResultReceiver
31 {
32     private final String TAG = toString();
33         private final Context context;
34         private IResultReceiver receiver = null;
35
36         private String targetFileName = null;
37     private String fileSavedResult = "";
38         private ProgressDialog importingDialog = null;
39
40         private String backgroundUri = null;
41         private String userCheckboxString = null;
42         
43         /**
44          *   コンストラクタ
45          */
46     public MeMoMaFileImportCsvProcess(Context context, IResultReceiver resultReceiver, String fileName)
47     {
48         this.context = context;
49         receiver = resultReceiver;
50         targetFileName = fileName;
51
52         //  プログレスダイアログ(「データインポート中...」)を表示する。
53         importingDialog = new ProgressDialog(context);
54         importingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
55         importingDialog.setMessage(context.getString(R.string.dataImporting));
56         importingDialog.setIndeterminate(true);
57         importingDialog.setCancelable(false);
58         importingDialog.show();
59
60         //  設定読み出し用...あらかじめ、UIスレッドで読みだしておく。         
61         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
62         backgroundUri = preferences.getString("backgroundUri","");
63         userCheckboxString = preferences.getString("userCheckboxString","");
64     }
65         
66     /**
67      *  非同期処理実施前の前処理
68      * 
69      */
70     @Override
71     protected void onPreExecute()
72     {
73     }
74
75     /**
76      *    1レコード分のデータを読み込む。 
77      * 
78      * @param buf
79      * @return
80      */
81     private String readRecord(BufferedReader buf )
82     {
83         String oneRecord = null;
84         try
85         {
86                 String oneLine = buf.readLine();
87             while (oneLine != null)
88             {
89                 oneRecord = (oneRecord == null) ? oneLine : oneRecord + oneLine;
90                 if (oneRecord.indexOf(",;!<_$") > 0)
91                 {
92                         // レコード末尾が見つかったので break する。
93                         break;
94                 }
95                 // 次の行を読みだす。
96                 oneLine = buf.readLine();
97             }
98         }
99         catch (Exception ex)
100         {
101             //
102                 Log.v(TAG, "CSV:readRecord() ex : " + ex.toString());
103                 oneRecord = null;
104         }
105         return (oneRecord);
106     }
107
108     /**
109      *   1レコード分のデータを区切る
110      * 
111      * 
112      * @param dataLine
113      */
114     private void parseRecord(String dataLine,  MeMoMaObjectHolder objectHolder)
115     {
116         int detailIndex = 0;
117         int userCheckIndexTrue = 0;
118         int userCheckIndexFalse = 0;
119         int nextIndex = 0;
120         String label = "";
121         String detail = "";
122         boolean userChecked = false;
123         try
124         {
125             detailIndex = dataLine.indexOf("\",\"");
126             if (detailIndex < 0)
127             {
128                 Log.v(TAG, "parseRecord() : label wrong : " + dataLine);
129                 return;
130             }
131             label = dataLine.substring(1, detailIndex);
132             userCheckIndexTrue = dataLine.indexOf("\",True,", detailIndex);
133             userCheckIndexFalse = dataLine.indexOf("\",False,", detailIndex);
134             if (userCheckIndexFalse > detailIndex)
135             {
136                 //
137                 detail = dataLine.substring(detailIndex + 3, userCheckIndexFalse);
138                 userChecked = false;
139                 nextIndex = userCheckIndexFalse + 8; // 8は、 ",False, を足した数
140             }
141             else if (userCheckIndexTrue > detailIndex)
142             {
143                 //
144                 detail = dataLine.substring(detailIndex + 3, userCheckIndexTrue);
145                 userChecked = true;
146                 nextIndex = userCheckIndexTrue + 7; // 7は、 ",True,  を足した数
147             }
148             else // if ((userCheckIndexTrue <= detailIndex)&&(userCheckIndexFalse <= detailIndex))
149             {
150                 Log.v(TAG, "parseRecord() : detail wrong : " + dataLine);
151                 return;                 
152             }
153             
154             //  残りのデータを切り出す。
155             String[] datas = (dataLine.substring(nextIndex)).split(",");
156             if (datas.length < 6)
157             {
158                 Log.v(TAG, "parseRecord() : data size wrong : " + datas.length);
159                 return;
160             }
161             int drawStyle = Integer.parseInt(datas[0]);
162             String paintStyle = datas[1];
163             float centerX = Float.parseFloat(datas[2]);
164             float centerY = Float.parseFloat(datas[3]);
165             float width = Float.parseFloat(datas[4]);
166             float height = Float.parseFloat(datas[5]);
167
168             float left = centerX - (width / 2.0f);
169             float top = centerY - (height / 2.0f);
170
171             // オブジェクトのデータを作成する
172             PositionObject pos = objectHolder.createPosition(left, top, drawStyle);
173             if (pos == null)
174             {
175                 Log.v(TAG, "parseRecord() : object create failure.");
176                 return;                 
177             }
178             pos.setRectRight(left + width);
179             pos.setRectBottom(top + height);
180             pos.setLabel(label);
181             pos.setDetail(detail);
182             pos.setPaintStyle(paintStyle);
183             pos.setUserChecked(userChecked);
184             Log.v(TAG, "OBJECT CREATED: " + label + "(" + left + "," + top + ") [" +drawStyle + "]");
185         }
186         catch (Exception ex)
187         {
188                 Log.v(TAG, "parseRecord() " + ex.toString());
189         }
190         
191     }
192
193     
194     /**
195      *    (CSV形式の)データを読み込んで格納する。
196      * 
197      * @param fileName
198      * @param objectHolder
199      * @return
200      */
201     private String importFromCsvFile(String fileName, MeMoMaObjectHolder objectHolder)
202     {
203         String resultMessage = "";
204         try
205         {
206             Log.v(TAG, "CSV(import)>> " + fileName);
207                 BufferedReader buf = new BufferedReader(new FileReader(fileName));
208             String dataLine = readRecord(buf);
209             while (dataLine != null)
210             {
211                         if (dataLine.startsWith(";") != true)
212                         {
213                                 // データ行だった。ログに出力する!
214                     parseRecord(dataLine, objectHolder);
215                         }
216                 // 次のデータ行を読み出す
217                         dataLine = readRecord(buf);
218             }
219         }
220         catch (Exception e)
221         {
222                 resultMessage = " ERR(import)>" + e.toString();
223             Log.v(TAG, resultMessage);
224             e.printStackTrace();
225         } 
226         return (resultMessage);
227     }
228
229     /**
230      *  非同期処理
231      *  (バックグラウンドで実行する(このメソッドは、UIスレッドと別のところで実行する))
232      * 
233      */
234     @Override
235     protected String doInBackground(MeMoMaObjectHolder... datas)
236     {           
237         // ファイル名の設定 ... (拡張子なし)
238         String fileName = context.getFilesDir() + "/exported/" + targetFileName;
239
240         // データを読み込む
241         String result = importFromCsvFile(fileName, datas[0]);
242
243         // データを保存する
244         MeMoMaFileSavingEngine savingEngine = new MeMoMaFileSavingEngine(context, backgroundUri, userCheckboxString);
245         String message = savingEngine.saveObjects(datas[0]);
246
247         System.gc();
248
249                 return (result + " " + message);
250     }
251
252     /**
253      *  非同期処理の進捗状況の更新
254      * 
255      */
256         @Override
257         protected void onProgressUpdate(Integer... values)
258         {
259         // 今回は何もしない
260         }
261
262     /**
263      *  非同期処理の後処理
264      *  (結果を応答する)
265      */
266     @Override
267     protected void onPostExecute(String result)
268     {
269         try
270         {
271             if (receiver != null)
272             {
273                 receiver.onImportedResult(result + "  " + fileSavedResult);
274             }
275             fileSavedResult = "";
276         }
277         catch (Exception ex)
278         {
279                 Log.v(TAG, "MeMoMaFileImportCsvProcess::onPostExecute() : " + ex.toString());
280         }
281         // プログレスダイアログを消す
282         importingDialog.dismiss();
283
284         return;
285     }
286     
287     public void onSavedResult(String detail)
288     {
289         fileSavedResult = detail;
290     }
291
292     public void setSavingStatus(boolean isSaving)
293     {
294         
295     }
296
297     public boolean getSavingStatus()
298     {
299         return (false);
300     }
301
302     /**
303      *    結果報告用のインタフェース(積極的に使う予定はないけど...)
304      *    
305      * @author MRSa
306      *
307      */
308     public interface IResultReceiver
309     {
310         /**  保存結果の報告 **/
311         void onImportedResult(String fileName);
312     }
313 }