OSDN Git Service

2405ee2308040eb48156f06def7616971a9841e7
[gokigen/MeMoMa.git] / app / src / main / java / jp / sourceforge / gokigen / memoma / extension / ExtensionActivityListener.java
1 package jp.sourceforge.gokigen.memoma.extension;
2
3 import java.io.File;
4 import java.text.SimpleDateFormat;
5 import java.util.ArrayList;
6 import java.util.Calendar;
7 import java.util.Enumeration;
8 import java.util.List;
9 import java.util.Locale;
10
11 import android.app.ActionBar;
12 import android.app.Activity;
13 import android.app.Dialog;
14 import android.content.Intent;
15 import android.net.Uri;
16 import androidx.core.content.FileProvider;
17 import android.util.Log;
18 import android.view.Menu;
19 import android.view.MenuItem;
20 import android.view.View;
21 import android.view.View.OnClickListener;
22 import android.widget.AdapterView;
23 import android.widget.ImageButton;
24 import android.widget.ListAdapter;
25 import android.widget.ListView;
26 import android.widget.Toast;
27
28 import jp.sourceforge.gokigen.memoma.holders.PositionObject;
29 import jp.sourceforge.gokigen.memoma.dialogs.FileSelectionDialog;
30 import jp.sourceforge.gokigen.memoma.Main;
31 import jp.sourceforge.gokigen.memoma.io.MeMoMaFileExportCsvProcess;
32 import jp.sourceforge.gokigen.memoma.io.MeMoMaFileImportCsvProcess;
33 import jp.sourceforge.gokigen.memoma.io.MeMoMaFileLoadingProcess;
34 import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder;
35 import jp.sourceforge.gokigen.memoma.R;
36 import jp.sourceforge.gokigen.memoma.io.SharedIntentInvoker;
37 import jp.sourceforge.gokigen.memoma.listitem.SymbolListArrayAdapter;
38 import jp.sourceforge.gokigen.memoma.listitem.SymbolListArrayItem;
39
40 /**
41  *    リスト形式で表示・エクスポート
42  * 
43  * @author MRSa
44  *
45  */
46 public class ExtensionActivityListener  implements OnClickListener, MeMoMaFileLoadingProcess.IResultReceiver, MeMoMaFileExportCsvProcess.IResultReceiver, FileSelectionDialog.IResultReceiver, MeMoMaFileImportCsvProcess.IResultReceiver
47 {
48     private final String TAG = toString();
49     private final int MENU_ID_EXPORT= (Menu.FIRST + 1);
50     private final int MENU_ID_SHARE = (Menu.FIRST + 2);
51     private final int MENU_ID_IMPORT = (Menu.FIRST + 3);
52
53     private static final String EXTENSION_DIRECTORY = "/exported";
54     
55     //private ExternalStorageFileUtility fileUtility;
56         private MeMoMaObjectHolder objectHolder;
57         private FileSelectionDialog fileSelectionDialog = null;
58         
59         private boolean isShareExportedData = false;
60
61         private List<SymbolListArrayItem> listItems = null;
62     
63     private final Activity parent;  // 親分
64         
65         /**
66      *  コンストラクタ
67      * @param argument parent activity
68      */
69         ExtensionActivityListener(Activity argument)
70     {
71         parent = argument;
72         //fileUtility = new ExternalStorageFileUtility(Main.APP_BASEDIR);
73         objectHolder = new MeMoMaObjectHolder(parent);
74     }
75     /**
76      *  起動時にデータを準備する
77      * 
78      * @param myIntent intent information
79      */
80     public void prepareExtraDatas(Intent myIntent)
81     {
82         try
83         {
84             // Intentで拾ったデータを読み出す (初期化データ)
85                 //fullPath = myIntent.getStringExtra(ExtensionActivity.MEMOMA_EXTENSION_DATA_FULLPATH);
86                 objectHolder.setDataTitle(myIntent.getStringExtra(ExtensionActivity.MEMOMA_EXTENSION_DATA_TITLE));
87
88             // Preferenceに記憶されたデータがあればそれを取得する
89             // SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
90          }
91         catch (Exception ex)
92         {
93             Log.v(TAG, "Exception :" + ex.toString());
94         }        
95     }
96
97     /**
98      *  がっつりこのクラスにイベントリスナを接続する
99      * 
100      */
101     public void prepareListener()
102     {
103         // フィルタ設定ボタン
104         final ImageButton filterButton = parent.findViewById(R.id.SetFilterButton);
105         filterButton.setOnClickListener(this);
106
107     }
108
109     /**
110      *  終了準備
111      */
112     public void finishListener()
113     {
114
115     }
116
117     /**
118      *  スタート準備
119      */
120     public void prepareToStart()
121     {
122                 Log.v(TAG, "ExtensionActivityListener::prepareToStart() : "  + objectHolder.getDataTitle());
123
124                 //  アクションバーを表示する
125         ActionBar bar = parent.getActionBar();
126         if (bar != null)
127         {
128             bar.show();
129             bar.setTitle(objectHolder.getDataTitle());
130         }
131
132         // ファイルをロードする!
133                 // (AsyncTaskを使ってデータを読み込む)
134                 MeMoMaFileLoadingProcess asyncTask = new MeMoMaFileLoadingProcess(parent, this);
135         asyncTask.execute(objectHolder);
136     }
137
138     /**
139      *    詳細データを表示する。
140      *
141      */
142     private void showDetailData(String first, String second, String third)
143     {
144         Log.v(TAG, "SELECTED: " + first + " " + second + " " + third);
145     }
146
147     /**
148      *  終了準備
149      */
150     public void shutdown()
151     {
152         
153     }
154     
155     /**
156      *  他画面から戻ってきたとき...
157      *
158      *
159      */
160     public void onActivityResult(int requestCode, int resultCode, Intent data)
161     {
162         // なにもしない...
163         Log.v(TAG, "rc: " + requestCode + " rs: " + resultCode + " it: "  + data.getDataString());
164     }
165
166     /**
167      *   クリックされたときの処理
168      */
169     public void onClick(View v)
170     {
171         int id = v.getId();
172         if (id == R.id.SetFilterButton)
173         {
174                  // フィルタ設定ボタンが押された!
175             Log.v(TAG, "Selected Filter");
176         }
177     }
178     
179 /*
180     **
181      *   触られたときの処理
182      *
183      *
184     public boolean onTouch(View v, MotionEvent event)
185     {
186         Log.v(Main.APP_IDENTIFIER, " " + v.toString() + " " + event.toString());
187         // int id = v.getId();
188         // int action = event.getAction();
189
190         return (false);
191     }
192 */
193
194     /**
195      *   メニューへのアイテム追加
196      *
197      */
198     public Menu onCreateOptionsMenu(Menu menu)
199     {
200         MenuItem menuItem = menu.add(Menu.NONE, MENU_ID_SHARE, Menu.NONE, parent.getString(R.string.export_csv));
201         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);   /*  for Android 3.1  */
202         menuItem.setIcon(android.R.drawable.ic_menu_share);
203
204         menuItem = menu.add(Menu.NONE, MENU_ID_EXPORT, Menu.NONE, parent.getString(R.string.shareContent));
205         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);   /*  for Android 3.1  */
206         menuItem.setIcon(android.R.drawable.ic_menu_save);
207
208         menuItem = menu.add(Menu.NONE, MENU_ID_IMPORT, Menu.NONE, parent.getString(R.string.import_csv));
209         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
210         menuItem.setIcon(android.R.drawable.ic_menu_edit);
211
212         return (menu);
213     }
214     
215     /**
216      *   メニュー表示前の処理
217      *
218      */
219     public void onPrepareOptionsMenu(Menu menu)
220     {
221         menu.findItem(MENU_ID_SHARE).setVisible(true);
222         menu.findItem(MENU_ID_EXPORT).setVisible(true);
223         menu.findItem(MENU_ID_IMPORT).setVisible(true);
224     }
225
226     /**
227      *   メニューのアイテムが選択されたときの処理
228      *
229      */
230     public boolean onOptionsItemSelected(MenuItem item)
231     {
232         boolean result;
233         switch (item.getItemId())
234         {
235           case MENU_ID_EXPORT:
236             // 表示中データのエクスポート
237                     export_as_csv(false);
238                 result = true;
239                 break;
240
241           case MENU_ID_SHARE:
242                 export_as_csv(true);
243                 result = true;
244                 break;
245
246           case MENU_ID_IMPORT:
247                 // データのインポート
248                 importObjectFromCsv();
249                 result = true;
250                 break;
251
252           default:
253                 result = false;
254                 break;
255         }
256         return (result);
257     }
258
259
260     /**
261      *   CSV形式でデータをインポートする
262      * 
263      */
264     private void importObjectFromCsv()
265     {
266         // データのインポート
267         parent.showDialog(R.id.listdialog);     
268     }
269
270     /**
271      *   データをCSV形式で出力する
272      * 
273      */
274     private void export_as_csv(boolean isShare)
275     {
276         isShareExportedData = isShare;
277
278         // AsyncTaskを使ってデータをエクスポートする
279         MeMoMaFileExportCsvProcess asyncTask = new MeMoMaFileExportCsvProcess(parent, this);
280         asyncTask.execute(objectHolder);
281     }
282     
283     /**
284      *  ダイアログの生成
285      * 
286      */
287     public Dialog onCreateDialog(int id)
288     {
289         if (id == R.id.listdialog)
290         {
291                 fileSelectionDialog = new FileSelectionDialog(parent, parent.getString(R.string.dialogtitle_selectcsv), ".csv",  this);
292                 return (fileSelectionDialog.getDialog());
293         }
294
295       /*
296         if (id == R.id.info_about_gokigen)
297         {
298                 CreditDialog dialog = new CreditDialog(parent);
299                 return (dialog.getDialog());
300         }
301       */
302             return (null);
303     }
304
305     /**
306      *    ファイル選択ダイアログの表示を準備する
307      * 
308      */
309     private void prepareFileSelectionDialog(Dialog dialog)
310     {
311         try
312         {
313             Log.v(TAG, " " + dialog.toString());
314             fileSelectionDialog.prepare();
315         }
316         catch (Exception e)
317         {
318             e.printStackTrace();
319         }
320     }
321
322     /**
323      *  ダイアログ表示の準備
324      * 
325      */
326     public void onPrepareDialog(int id, Dialog dialog)
327     {
328         if (id == R.id.listdialog)
329         {
330                 // CSVインポートダイアログを準備する
331                 prepareFileSelectionDialog(dialog);
332         }
333     }
334
335     /**
336      *    ファイルをロードする途中のバックグラウンド処理...
337      * 
338      */
339         public void onLoadingProcess()
340         {
341                 try
342                 {
343                 // リストに表示するアイテムを生成する
344                 listItems = null;
345                 listItems = new ArrayList<>();
346
347                 // TODO: 何らかの法則に従って並べ替えをする。
348
349                 Enumeration<Integer> keys = objectHolder.getObjectKeys();
350                 while (keys.hasMoreElements())
351                 {
352                     Integer key = keys.nextElement();
353                     PositionObject pos = objectHolder.getPosition(key);
354
355                     // アイコンの決定
356                     int objectStyleIcon = MeMoMaObjectHolder .getObjectDrawStyleIcon(pos.getDrawStyle());
357                     
358                     // ユーザチェックの有無表示
359                     int userCheckedIcon = (pos.getUserChecked()) ? R.drawable.btn_checked : R.drawable.btn_notchecked;
360
361                     // TODO: アイテム選択時の情報エリアは(ArrayItem側には)用意しているが未使用。
362                     SymbolListArrayItem listItem = new SymbolListArrayItem(userCheckedIcon, pos.getLabel(), pos.getDetail(), "", objectStyleIcon);
363
364                     listItems.add(listItem);
365                 }
366             } catch (Exception ex)
367             {
368                 // 例外発生...ログを吐く
369                 Log.v(TAG, "ExtensionActivityListener::onLoadingProcess() : " + ex.toString());
370             }   
371         }
372
373     /**
374      *    ファイルのロード結果を受け取る
375      * 
376      */
377     public void onLoadedResult(String detail)
378     {
379                 Log.v(TAG, "ExtensionActivityListener::onLoadedResult() '"  + objectHolder.getDataTitle() +"' : " + detail);
380
381                 // 読み込んだファイル名をタイトルに設定する
382                 parent.setTitle(objectHolder.getDataTitle());
383                 
384                 // オブジェクト一覧を表示する
385                 updateObjectList();
386                 
387                 // 読み込みしたことを伝達する
388                 //String outputMessage = parent.getString(R.string.load_data) + " " + objectHolder.getDataTitle() + " " + detail;
389         //Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();     
390     }
391
392     /**
393      *    ファイルのエクスポート結果を受け取る
394      * 
395      */
396     public void onExportedResult(String exportedFileName, String detail)
397     {
398                 Log.v(TAG, "ExtensionActivityListener::onExportedResult() '"  + objectHolder.getDataTitle() +"' : " + detail);
399
400                 // エクスポートしたことを伝達する
401                 String outputMessage = parent.getString(R.string.export_csv) + " " + objectHolder.getDataTitle() + " " + detail;
402         Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
403         
404         if (isShareExportedData)
405         {
406                 // エクスポートしたファイルを共有する
407             shareContent(exportedFileName);
408         }
409         isShareExportedData = false;
410     }
411     
412     /**
413      *    オブジェクト一覧を更新する
414      */
415     private void updateObjectList()
416     {
417         try
418         {
419                 // リストアダプターを生成し、設定する
420             ListView listView = parent.findViewById(R.id.ExtensionView);
421             ListAdapter adapter = new SymbolListArrayAdapter(parent,  R.layout.listarrayitems, listItems);
422             listView.setAdapter(adapter);
423
424             // アイテムを選択したときの処理
425             listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
426                 //@Override
427                 public void onItemClick(AdapterView<?> parentView, View view, int position, long id)
428                 {
429                     ListView listView = (ListView) parentView;
430                     SymbolListArrayItem item = (SymbolListArrayItem) listView.getItemAtPosition(position);
431
432                     /// リストが選択されたときの処理...データを開く
433                     showDetailData(item.getTextResource1st(), item.getTextResource2nd(), item.getTextResource3rd());
434                 }
435             });
436             System.gc();   // いらない(参照が切れた)クラスを消したい
437         }
438         catch (Exception ex)
439         {
440                 // 何もしない。
441         }
442     }
443     
444     /**
445      *    エクスポートしたファイルを共有する
446      * 
447      *
448      */
449     private void shareContent(String fileName)
450     {
451         String message = "";
452         try
453         {
454                 // 現在の時刻を取得する
455             Calendar calendar = Calendar.getInstance();
456                 SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
457             String date =  outFormat.format(calendar.getTime());
458
459             // メールタイトル
460             String title = parent.getString(R.string.app_name) + " | "+ objectHolder.getDataTitle() + " | " + date;
461
462             // メールの本文を構築する
463             message = message + "Name : " + objectHolder.getDataTitle() + "\n";
464             message = message + "exported : " + date + "\n";
465             message = message + "number of objects : " + objectHolder.getCount() + "\n";
466
467             // Share Intentを発行する。
468             Uri fileURI = FileProvider.getUriForFile(parent,"jp.sourceforge.gokigen.memoma.fileprovider", new File(fileName));
469             SharedIntentInvoker.shareContent(parent, MENU_ID_SHARE, title, message, fileURI, "text/plain");
470         }
471         catch (Exception ex)
472         {
473             Log.v(TAG, "shareContent (fileName : " + fileName + ")");
474             ex.printStackTrace();
475         }
476     }
477     
478     /**
479      *   ファイルが選択された!
480      * 
481      */
482     public void selectedFileName(String fileName)
483     {
484         // CSVファイルからオブジェクトをロードするクラスを呼び出す。
485         Log.v(TAG, "ExtensionActivityListener::selectedFileName() : " + fileName);
486         MeMoMaFileImportCsvProcess asyncTask = new MeMoMaFileImportCsvProcess(parent, this, fileName);
487         asyncTask.execute(objectHolder);
488     }
489
490     /**
491      *    インポート結果の受信
492      *
493      */
494     public void onImportedResult(String detail)
495     {
496                 Log.v(TAG, "ExtensionActivityListener::onImportedResult() '"  + objectHolder.getDataTitle() +"' : " + detail);
497
498                 // インポートしたことを伝達する
499                 String outputMessage = parent.getString(R.string.import_csv) + " " + objectHolder.getDataTitle() + " " + detail;
500         Toast.makeText(parent, outputMessage, Toast.LENGTH_SHORT).show();
501
502         // 一覧のリストを作りなおす
503         onLoadingProcess();
504         updateObjectList();
505     }    
506 }