OSDN Git Service

69f2bef92498018e8f7cd7cf134d9ad6419017f4
[gokigen/MeMoMa.git] / app / src / main / java / jp / sourceforge / gokigen / memoma / MeMoMaListener.java
1 package jp.sourceforge.gokigen.memoma;
2
3 import android.app.Activity;
4 import android.app.AlertDialog;
5 import android.app.Dialog;
6 import android.content.DialogInterface;
7 import android.content.Intent;
8 import android.content.SharedPreferences;
9 import android.graphics.Color;
10 import android.graphics.PorterDuff.Mode;
11 import android.graphics.drawable.BitmapDrawable;
12 import android.net.Uri;
13 import android.os.Build;
14 import android.os.Bundle;
15 import android.preference.PreferenceManager;
16 import android.support.v7.app.AppCompatActivity;
17 import android.util.Log;
18 import android.view.KeyEvent;
19 import android.view.Menu;
20 import android.view.MenuItem;
21 import android.view.MotionEvent;
22 import android.view.View;
23 import android.view.View.OnClickListener;
24 import android.view.View.OnKeyListener;
25 import android.view.View.OnTouchListener;
26 import android.widget.ImageButton;
27 import android.widget.SeekBar;
28
29 import jp.sourceforge.gokigen.memoma.dialogs.ConfirmationDialog;
30 import jp.sourceforge.gokigen.memoma.dialogs.CreditDialog;
31 import jp.sourceforge.gokigen.memoma.dialogs.ItemSelectionDialog;
32 import jp.sourceforge.gokigen.memoma.dialogs.TextEditDialog;
33 import jp.sourceforge.gokigen.memoma.drawers.GokigenSurfaceView;
34 import jp.sourceforge.gokigen.memoma.drawers.MeMoMaCanvasDrawer;
35 import jp.sourceforge.gokigen.memoma.extension.ExtensionActivity;
36 import jp.sourceforge.gokigen.memoma.holders.OperationHistoryHolder;
37 import jp.sourceforge.gokigen.memoma.io.MeMoMaDataInOutManager;
38 import jp.sourceforge.gokigen.memoma.holders.LineStyleHolder;
39 import jp.sourceforge.gokigen.memoma.holders.MeMoMaConnectLineHolder;
40 import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder;
41 import jp.sourceforge.gokigen.memoma.holders.OperationModeHolder;
42 import jp.sourceforge.gokigen.memoma.operations.IObjectSelectionReceiver;
43 import jp.sourceforge.gokigen.memoma.operations.ObjectAligner;
44 import jp.sourceforge.gokigen.memoma.operations.ObjectDataInputDialog;
45 import jp.sourceforge.gokigen.memoma.operations.ObjectOperationCommandHolder;
46 import jp.sourceforge.gokigen.memoma.operations.SelectLineShapeDialog;
47 import jp.sourceforge.gokigen.memoma.preference.Preference;
48
49 /**
50  *   メモま! のメイン画面処理
51  *   
52  * @author MRSa
53  */
54 public class MeMoMaListener implements OnClickListener, OnTouchListener, OnKeyListener, IObjectSelectionReceiver, ConfirmationDialog.IResultReceiver, ObjectDataInputDialog.IResultReceiver, ItemSelectionDialog.ISelectionItemReceiver, TextEditDialog.ITextEditResultReceiver, ObjectAligner.IAlignCallback, SelectLineShapeDialog.IResultReceiver
55 {
56     private static final int MENU_ID_PREFERENCES = (Menu.FIRST + 1);    // 設定画面の表示
57     private static final int MENU_ID_ABOUT_GOKIGEN = (Menu.FIRST + 2);  // アプリケーションの情報表示
58     private static final int MENU_ID_NEW = (Menu.FIRST + 3);                     // 新規作成
59     private static final int MENU_ID_EXTEND= (Menu.FIRST + 4);                   // 拡張機能
60     private static final int MENU_ID_ALIGN = (Menu.FIRST + 5);                     // オブジェクトの整列
61     private static final int MENU_ID_INSERT_PICTURE = (Menu.FIRST + 6);   // 画像の指定
62     private static final int MENU_ID_OPERATION = (Menu.FIRST + 7);           // 操作コマンド
63     private static final int MENU_ID_RENAME = (Menu.FIRST + 8);                // リネーム
64     private static final int MENU_ID_CAPTURE = (Menu.FIRST + 9);              // 画像のキャプチャ
65     private static final int MENU_ID_SHARE = (Menu.FIRST + 10);              // 画像の共有
66     private static final int MENU_ID_UNDO = (Menu.FIRST + 11);              // 処理の UNDO
67
68     private AppCompatActivity parent;  // 親分
69     private TextEditDialog editTextDialog;   // テキスト編集用ダイアログ
70     private MeMoMaCanvasDrawer objectDrawer; // 画像の表示
71     private MeMoMaObjectHolder objectHolder;  // オブジェクトの保持クラス
72     private MeMoMaConnectLineHolder lineHolder;  // オブジェクト間の接続状態保持クラス
73     private OperationHistoryHolder historyHolder;  // 操作履歴保持クラス
74     //private SelectFeatureListener featureListener = null;  // 機能選択用のリスナ
75
76     private MeMoMaDataInOutManager dataInOutManager;
77
78     private OperationModeHolder drawModeHolder;
79     private LineStyleHolder lineStyleHolder;
80
81     private ConfirmationDialog confirmationDialog;
82
83     private ObjectDataInputDialog objectDataInputDialog;
84
85     private SelectLineShapeDialog lineSelectionDialog;
86
87     private ItemSelectionDialog itemSelectionDialog;
88     private ObjectOperationCommandHolder commandHolder;
89
90     private boolean isEditing = false;
91     private Integer  selectedObjectKey = 0;
92     private Integer  objectKeyToDelete = 0;
93     private Integer selectedContextKey = 0;
94
95     /**
96      *  コンストラクタ
97      *
98      */
99     MeMoMaListener(AppCompatActivity argument, MeMoMaDataInOutManager inoutManager)
100     {
101         parent = argument;
102         dataInOutManager = inoutManager;
103         historyHolder = new OperationHistoryHolder();
104         lineHolder = new MeMoMaConnectLineHolder(historyHolder);
105         objectHolder = new MeMoMaObjectHolder(argument, lineHolder, historyHolder);
106         editTextDialog = new TextEditDialog(parent, R.drawable.icon);
107         //lineHolder = new MeMoMaConnectLineHolder();
108         //featureListener = new SelectFeatureListener(parent);
109         drawModeHolder = new OperationModeHolder(parent);
110
111         lineStyleHolder = new LineStyleHolder(parent);
112         lineStyleHolder.prepare();
113
114         // 新規作成時の確認ダイアログについて
115         confirmationDialog = new ConfirmationDialog(argument);
116         confirmationDialog.prepare(this, android.R.drawable.ic_dialog_alert, parent.getString(R.string.createnew_title), parent.getString(R.string.createnew_message));
117
118         // オブジェクトのデータ入力ダイアログを生成
119         objectDataInputDialog = new ObjectDataInputDialog(argument, objectHolder);
120         objectDataInputDialog.setResultReceiver(this);
121
122         // 接続線の形状と太さを選択するダイアログを生成
123         lineSelectionDialog = new SelectLineShapeDialog(argument, lineStyleHolder);
124         lineSelectionDialog.setResultReceiver(this);
125
126         // アイテム選択ダイアログを生成
127         commandHolder = new ObjectOperationCommandHolder(argument);
128         itemSelectionDialog = new ItemSelectionDialog(argument);
129         itemSelectionDialog.prepare(this,  commandHolder, parent.getString(R.string.object_operation));
130
131         // 描画クラスの生成
132         objectDrawer = new MeMoMaCanvasDrawer(argument, objectHolder, lineStyleHolder, this);
133
134         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
135         String colorString = preferences.getString("backgroundColor", "0xff004000");
136         objectDrawer.setBackgroundColor(colorString);
137
138     }
139
140     /**
141      *  がっつりこのクラスにイベントリスナを接続する
142      *
143      */
144     public void prepareListener()
145     {
146         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
147
148         // 表示位置リセットボタン
149         final ImageButton homeButton = parent.findViewById(R.id.HomeButton);
150         homeButton.setOnClickListener(this);
151
152         // 拡張ボタン
153         final ImageButton expandButton = parent.findViewById(R.id.ExpandButton);
154         expandButton.setOnClickListener(this);
155
156         // 作成ボタン
157         final ImageButton createObjectButton = parent.findViewById(R.id.CreateObjectButton);
158         createObjectButton.setOnClickListener(this);
159
160         final ImageButton deleteObjectButton = parent.findViewById(R.id.DeleteObjectButton);
161         deleteObjectButton.setOnClickListener(this);
162
163         // 線の形状切り替えボタン
164         final ImageButton lineStyleButton = parent.findViewById(R.id.LineStyleButton);
165         lineStyleButton.setOnClickListener(this);
166
167         // データ保存ボタン
168         final ImageButton saveButton = parent.findViewById(R.id.SaveButton);
169         saveButton.setOnClickListener(this);
170
171         // 画面描画クラス
172         final GokigenSurfaceView surfaceView = parent.findViewById(R.id.GraphicView);
173         surfaceView.setOnTouchListener(this);
174
175         // スライドバーが動かされた時の処理
176         final SeekBar seekbar =parent.findViewById(R.id.ZoomInOut);
177         seekbar.setOnSeekBarChangeListener(objectDrawer);
178         int progress = preferences.getInt("zoomProgress", 50);
179         seekbar.setProgress(progress);
180
181         // 「実行中」の表示を消す
182         parent.setProgressBarIndeterminateVisibility(false);
183
184         //// 起動時にデータを読み出す
185         prepareMeMoMaInfo();
186     }
187
188     /**
189      *  終了準備
190      */
191     public void finishListener()
192     {
193         // 終了時に状態を保存する
194         saveData(true);
195     }
196
197     /**
198      *  スタート準備
199      */
200     public void prepareToStart()
201     {
202         //  設定に記録されているデータを画面に反映させる
203         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
204
205         // 描画オブジェクトの形状を設定する
206         //int objectStyle = Integer.parseInt(preferences.getString("drawStyle", "0"));
207
208         // ラインの形状を取得し、設定する
209         setLineStyle();
210
211         // 操作モードを画面に反映させる
212         updateButtons(Integer.parseInt(preferences.getString("operationMode", "0")));
213
214         // 条件に合わせて、描画クラスを変更する
215         final GokigenSurfaceView surfaceView = parent.findViewById(R.id.GraphicView);
216         surfaceView.setCanvasDrawer(objectDrawer);
217
218         // 背景画像(の名前)を設定しておく
219         String backgroundString = preferences.getString("backgroundUri", "");
220         objectDrawer.setBackgroundUri(backgroundString);
221     }
222
223     /**
224      *  終了準備
225      */
226     public void shutdown()
227     {
228
229     }
230
231     /**
232      *  他画面から戻ってきたとき...
233      *
234      */
235     public void onActivityResult(int requestCode, int resultCode, Intent data)
236     {
237         if ((requestCode == MENU_ID_INSERT_PICTURE)&&(resultCode == Activity.RESULT_OK))
238         {
239             try
240             {
241                 // 取得したuri を preferenceに記録する
242                 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
243                 Uri backgroundUri = data.getData();
244                 if (backgroundUri != null)
245                 {
246                     try
247                     {
248                         if (Build.VERSION.SDK_INT >= 19) {
249                             final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION);
250                             parent.getContentResolver().takePersistableUriPermission(backgroundUri, takeFlags);
251                         }
252                         SharedPreferences.Editor editor = preferences.edit();
253                         editor.putString("backgroundUri", backgroundUri.toString());
254                         editor.apply();
255                     }
256                     catch (Exception e)
257                     {
258                         e.printStackTrace();
259                     }
260                     // 背景画像イメージの更新処理
261                     updateBackgroundImage(backgroundUri.toString());
262                 }
263                 System.gc();
264             }
265             catch (Exception ex)
266             {
267                 Log.v(Main.APP_IDENTIFIER, "Ex:" + ex.toString() + " " + ex.getMessage());
268             }
269             return;
270         }
271         else if (requestCode == MENU_ID_PREFERENCES)
272         {
273             // 背景色、背景画像の設定を行う。
274             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
275             String colorString = preferences.getString("backgroundColor", "0xff004000");
276             objectDrawer.setBackgroundColor(colorString);
277
278             // 背景画像イメージの更新処理
279             String backgroundString = preferences.getString("backgroundUri", "");
280             updateBackgroundImage(backgroundString);
281
282             Log.v(Main.APP_IDENTIFIER, "RETURENED PREFERENCES " + backgroundString);
283
284         }
285         else if (requestCode == MENU_ID_EXTEND)
286         {
287             // その他...今開いているファイルを読みなおす
288             dataInOutManager.loadFile((String) parent.getTitle());
289         }
290         else
291         {
292             // 画面表示の準備を実行...
293             //prepareToStart();
294             return;
295         }
296         // 画面の再描画を指示する
297         redrawSurfaceview();
298     }
299
300     /**
301      *    背景画像イメージの更新処理
302      *
303      */
304     private void updateBackgroundImage(String uri)
305     {
306         // 背景画像イメージの更新処理
307         GokigenSurfaceView graphView = parent.findViewById(R.id.GraphicView);
308
309         // ビットマップを設定する
310         objectDrawer.updateBackgroundBitmap(uri, graphView.getWidth(), graphView.getHeight());
311
312         // 画面の再描画指示
313         graphView.doDraw();
314     }
315
316
317     /**
318      *   クリックされたときの処理
319      */
320     public void onClick(View v)
321     {
322         int id = v.getId();
323
324         //Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::onClick() " + id);
325         if (id == R.id.MeMoMaInfo)
326         {
327             // テキスト編集ダイアログを表示する
328             showInfoMessageEditDialog();
329         }
330         else if (id == R.id.LineStyleButton)
331         {
332             // ライン形状を変えるダイアログで変更するように変更する
333             selectLineShapeDialog();
334         }
335         else if (id == R.id.ExpandButton)
336         {
337             // 拡張メニューを呼び出す
338             callExtendMenu();
339         }
340         else if ((id == R.id.DeleteObjectButton)||(id == R.id.CreateObjectButton))
341         {
342             // 削除ボタン or 作成ボタンが押された時の処理
343             updateButtons(drawModeHolder.updateOperationMode(id));
344         }
345         else if (id == R.id.HomeButton)
346         {
347             //  表示位置をリセットする
348             // 表示倍率と並行移動についてリセットする
349             objectDrawer.resetScaleAndLocation((SeekBar) parent.findViewById(R.id.ZoomInOut));
350
351             // 画面の再描画を指示する
352             redrawSurfaceview();
353         }
354         else if (id == R.id.SaveButton)
355         {
356             // データ保存が指示された!
357             saveData(true);
358         }
359     }
360
361     /**
362      *   触られたときの処理
363      *
364      */
365     public boolean onTouch(View v, MotionEvent event)
366     {
367         int id = v.getId();
368         // int action = event.getAction();
369
370         //Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::onTouch() " + id);
371
372         if (id == R.id.GraphicView)
373         {
374             // 画面をタッチした!
375             v.onTouchEvent(event);
376             return (true);
377         }
378         return (false);
379     }
380
381     /**
382      *  キーを押したときの操作
383      */
384     public boolean onKey(View v, int keyCode, KeyEvent event)
385     {
386         int action = event.getAction();
387         if ((action == KeyEvent.ACTION_DOWN)&&(keyCode == KeyEvent.KEYCODE_DPAD_CENTER))
388         {
389             //
390             Log.v(Main.APP_IDENTIFIER, "KEY ENTER");
391         }
392
393         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::onKey() ");
394         return (false);
395     }
396
397     /**
398      *   メニューへのアイテム追加
399      *
400      */
401     public Menu onCreateOptionsMenu(Menu menu)
402     {
403         // 新規作成
404         MenuItem menuItem = menu.add(Menu.NONE, MENU_ID_NEW, Menu.NONE, parent.getString(R.string.createnew));
405         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);   /*  for Android 3.1  */
406         menuItem.setIcon(android.R.drawable.ic_menu_add);    // 丸プラス
407
408         // 画像の共有
409         menuItem = menu.add(Menu.NONE, MENU_ID_SHARE, Menu.NONE, parent.getString(R.string.shareContent));
410         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);   /*  for Android 3.1  */
411         menuItem.setIcon(android.R.drawable.ic_menu_share);
412
413         // 画像のキャプチャ
414         menuItem = menu.add(Menu.NONE, MENU_ID_CAPTURE, Menu.NONE, parent.getString(R.string.capture_data));
415         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);   /*  for Android 3.1  */
416         menuItem.setIcon(android.R.drawable.ic_menu_crop);    // オブジェクトのキャプチャ
417
418         // 処理のUNDO
419         menuItem = menu.add(Menu.NONE, MENU_ID_UNDO, Menu.NONE, parent.getString(R.string.undo_operation));
420         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
421         menuItem.setIcon(android.R.drawable.ic_menu_revert);
422
423         // オブジェクトの整列
424         menuItem = menu.add(Menu.NONE, MENU_ID_ALIGN, Menu.NONE, parent.getString(R.string.align_data));
425         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
426         menuItem.setIcon(android.R.drawable.ic_menu_rotate);    // オブジェクトの整列
427
428         // タイトルの変更
429         menuItem = menu.add(Menu.NONE, MENU_ID_RENAME, Menu.NONE, parent.getString(R.string.rename_title));
430         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
431         menuItem.setIcon(android.R.drawable.ic_menu_edit);    // タイトルの変更
432
433         // 壁紙の選択
434         menuItem = menu.add(Menu.NONE, MENU_ID_INSERT_PICTURE, Menu.NONE, parent.getString(R.string.background_data));
435         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
436         menuItem.setIcon(android.R.drawable.ic_menu_gallery);    // 壁紙の選択
437
438         // 拡張メニュー
439         menuItem = menu.add(Menu.NONE, MENU_ID_EXTEND, Menu.NONE, parent.getString(R.string.extend_menu));
440         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
441         menuItem.setIcon(android.R.drawable.ic_menu_share);    // 拡張メニュー...
442
443         // 設定
444         menuItem = menu.add(Menu.NONE, MENU_ID_PREFERENCES, Menu.NONE, parent.getString(R.string.preference_name));
445         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
446         menuItem.setIcon(android.R.drawable.ic_menu_preferences);
447
448         // クレジット情報の表示
449         menuItem = menu.add(Menu.NONE, MENU_ID_ABOUT_GOKIGEN, Menu.NONE, parent.getString(R.string.about_gokigen));
450         menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);   /*  for Android 3.1  */
451         menuItem.setIcon(android.R.drawable.ic_menu_info_details);
452
453         return (menu);
454     }
455
456     /**
457      *   メニュー表示前の処理
458      *
459      *
460      */
461     public void onPrepareOptionsMenu(Menu menu)
462     {
463         menu.findItem(MENU_ID_NEW).setVisible(true);
464         menu.findItem(MENU_ID_UNDO).setVisible(false);
465         menu.findItem(MENU_ID_SHARE).setVisible(true);
466         menu.findItem(MENU_ID_CAPTURE).setVisible(true);
467         menu.findItem(MENU_ID_ALIGN).setVisible(true);
468         menu.findItem(MENU_ID_RENAME).setVisible(true);
469         menu.findItem(MENU_ID_INSERT_PICTURE).setVisible(true);
470         menu.findItem(MENU_ID_EXTEND).setVisible(true);
471         menu.findItem(MENU_ID_PREFERENCES).setVisible(true);
472         menu.findItem(MENU_ID_ABOUT_GOKIGEN).setVisible(true);
473     }
474
475     /**
476      *   メニューのアイテムが選択されたときの処理
477      *
478      *
479      */
480     public boolean onOptionsItemSelected(MenuItem item)
481     {
482         boolean result;
483         switch (item.getItemId())
484         {
485             case MENU_ID_PREFERENCES:
486                 showPreference();
487                 result = true;
488                 break;
489
490             case MENU_ID_ABOUT_GOKIGEN:
491                 showAboutGokigen();
492                 result = true;
493                 break;
494
495             case MENU_ID_NEW:
496                 createNewScreen();
497                 result = true;
498                 break;
499
500             case MENU_ID_EXTEND:
501                 // 拡張メニューを呼び出す
502                 callExtendMenu();
503                 result = true;
504                 break;
505
506             case MENU_ID_ALIGN:
507                 // オブジェクトの整列を行う
508                 alignData();
509                 result = true;
510                 break;
511
512             case MENU_ID_RENAME:
513                 // タイトル名の変更  (テキスト編集ダイアログを表示する)
514                 showInfoMessageEditDialog();
515                 result = true;
516                 break;
517
518             case MENU_ID_INSERT_PICTURE:
519                 // 背景画像の設定を行う
520                 insertPicture();
521                 result = true;
522                 break;
523
524             case MENU_ID_CAPTURE:
525                 // 画面キャプチャを指示された場合...
526                 doCapture(false);
527                 result = true;
528                 break;
529
530             case MENU_ID_SHARE:
531                 // 画面キャプチャ&共有を指示された場合...
532                 doCapture(true);
533                 result = true;
534                 break;
535
536             case android.R.id.home:
537                 // アイコンが押された時の処理...
538                 // テキスト編集ダイアログを表示する
539                 showInfoMessageEditDialog();
540                 result = true;
541                 break;
542
543             case MENU_ID_UNDO:
544                 // UNDO処理...
545                 result = undoOperation();
546                 break;
547
548             default:
549                 result = false;
550                 break;
551         }
552         return (result);
553     }
554
555
556     /**
557      *   操作を1つ戻す(Undo 処理)
558      *
559      */
560     private boolean undoOperation()
561     {
562         return (false);
563     }
564
565     /**
566      *  画像ファイルの挿入 (データファイルの更新)
567      *
568      */
569     private void insertPicture()
570     {
571         Intent intent;
572         if (Build.VERSION.SDK_INT >= 19) {
573             intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
574             intent.addCategory(Intent.CATEGORY_OPENABLE);
575             intent.setType("image/*");
576             //intent.setAction(Intent.ACTION_GET_CONTENT);
577         } else {
578             intent = new Intent();
579             intent.setType("image/*");
580             intent.setAction(Intent.ACTION_GET_CONTENT);
581         }
582         parent.startActivityForResult(intent, MENU_ID_INSERT_PICTURE);
583     }
584
585     /**
586      *    画面キャプチャの実施
587      *
588      *
589      */
590     private void doCapture(boolean isShare)
591     {
592         // 画面のスクリーンショットをとる処理を実行する
593         dataInOutManager.doScreenCapture((String) parent.getTitle(), objectHolder, objectDrawer, isShare);
594
595         // 画面を再描画する
596         redrawSurfaceview();
597     }
598
599     /**
600      *   アプリの情報を表示する
601      *
602      */
603     private void showAboutGokigen()
604     {
605         // アプリの情報(クレジット)を表示する!
606         parent.showDialog(R.id.info_about_gokigen);
607     }
608
609     /**
610      *   拡張メニューを呼び出す
611      *
612      */
613     private void callExtendMenu()
614     {
615         // 現在表示中のデータをファイルに保存する
616         dataInOutManager.saveFile((String) parent.getTitle(), true);
617
618         // 現在読み込んでいるファイルのファイル名を生成する
619         String fullPath = dataInOutManager.getDataFileFullPath((String) parent.getTitle(), ".xml");
620
621         //  ここで拡張メニューを呼び出す
622         // (渡すデータを作って Intentとする)
623         Intent intent = new Intent();
624
625         intent.setAction(ExtensionActivity.MEMOMA_EXTENSION_LAUNCH_ACTIVITY);
626         intent.putExtra(ExtensionActivity.MEMOMA_EXTENSION_DATA_FULLPATH, fullPath);
627         intent.putExtra(ExtensionActivity.MEMOMA_EXTENSION_DATA_TITLE, (String) parent.getTitle());
628
629         // データ表示用Activityを起動する
630         parent.startActivityForResult(intent, MENU_ID_EXTEND);
631     }
632
633     /**
634      *    データの読み込みを行う
635      *
636      */
637     private void prepareMeMoMaInfo()
638     {
639         //  設定に記録されているデータを画面のタイトルに反映させる
640         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
641         String memomaInfo = preferences.getString("MeMoMaInfo", parent.getString(R.string.app_name));
642         parent.setTitle(memomaInfo);
643
644         // アクションバーとファイル名の準備
645         android.support.v7.app.ActionBar bar = parent.getSupportActionBar();
646         if (bar != null)
647         {
648             dataInOutManager.prepare(objectHolder, bar, memomaInfo);
649         }
650
651         //dataInOutManager.loadFile((String) parent.getTitle());
652     }
653
654     /**
655      *   データの保存を行う
656      *
657      *
658      *   @param forceOverwrite  trueの時は、ファイル名が確定していたときは(確認せずに)上書き保存を自動で行う。
659      *
660      */
661     private void saveData(boolean forceOverwrite)
662     {
663         dataInOutManager.saveFile((String) parent.getTitle(), forceOverwrite);
664     }
665
666     /**
667      *   データの整列を行う
668      *
669      */
670     private void alignData()
671     {
672         ObjectAligner aligner = new ObjectAligner(parent, this);
673         aligner.execute(objectHolder);
674     }
675
676     /**
677      *    メッセージ編集ダイアログを表示する
678      *
679      */
680     private void showInfoMessageEditDialog()
681     {
682         parent.showDialog(R.id.editTextArea);
683     }
684
685     /**
686      *   新規作成が指示されたとき...全部クリアして作りなおして良いか確認する。
687      *
688      */
689     private void createNewScreen()
690     {
691         parent.showDialog(R.id.confirmation);
692     }
693
694     /**
695      *    接続線の設定ダイアログを表示する
696      */
697     private void selectLineShapeDialog()
698     {
699         // 接続線の設定ダイアログを表示する...
700         parent.showDialog(R.id.selectline_dialog);
701     }
702
703     /**
704      *    メッセージ編集ダイアログの表示を準備する
705      *
706      */
707     private void prepareInfoMessageEditDialog(Dialog dialog)
708     {
709         String message = (String) parent.getTitle();
710         editTextDialog.prepare(dialog, this, parent.getString(R.string.dataTitle), message, true);
711     }
712
713     /**
714      *    メッセージ編集ダイアログの表示を準備する
715      *
716      */
717     private void prepareConfirmationDialog(Dialog dialog)
718     {
719         // Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::prepareConfirmationDialog() " );
720     }
721
722     /**
723      *    オブジェクト入力用ダイアログの表示を準備する
724      *
725      */
726     private void prepareObjectInputDialog(Dialog dialog)
727     {
728         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::prepareObjectInputDialog(), key: " + selectedObjectKey);
729
730         //  ダイアログの準備を行う
731         objectDataInputDialog.prepareObjectInputDialog(dialog, selectedObjectKey);
732
733     }
734
735     /**
736      *   アイテム選択ダイアログの表示を準備する
737      *
738      *
739      */
740     private void prepareItemSelectionDialog(Dialog dialog)
741     {
742         // アイテム選択ダイアログの表示設定
743         // (動的変更時。。。今回は固定なので何もしない)
744     }
745
746     /**
747      *    接続線選択用ダイアログの表示を準備する
748      *
749      */
750     private void prepareLineSelectionDialog(Dialog dialog)
751     {
752         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::prepareLineSelectionDialog(), key: " + selectedObjectKey);
753
754         //  ダイアログの準備を行う
755         lineSelectionDialog.prepareSelectLineShapeDialog(dialog, selectedObjectKey);
756     }
757
758     /**
759      *  設定画面を表示する処理
760      */
761     private void showPreference()
762     {
763         try
764         {
765             // 設定画面を呼び出す
766             Intent prefIntent = new Intent(parent,Preference.class);
767             parent.startActivityForResult(prefIntent, MENU_ID_PREFERENCES);
768         }
769         catch (Exception e)
770         {
771             // 例外発生...なにもしない。
772             e.printStackTrace();
773             //updater.showMessage("ERROR", MainUpdater.SHOWMETHOD_DONTCARE);
774         }
775     }
776
777     /**
778      *    接続線の形状を反映させる
779      *
780      */
781     private void setLineStyle()
782     {
783         int buttonId = LineStyleHolder.getLineShapeImageId(lineStyleHolder.getLineStyle(), lineStyleHolder.getLineShape());
784         final ImageButton lineStyleObj = parent.findViewById(R.id.LineStyleButton);
785         lineStyleObj.setImageResource(buttonId);
786     }
787
788     /**
789      *    オブジェクトが生成された!
790      *
791      */
792     public void objectCreated()
793     {
794         // ここで動作モードを移動モードに戻す。
795         drawModeHolder.changeOperationMode(OperationModeHolder.OPERATIONMODE_MOVE);
796         updateButtons(OperationModeHolder.OPERATIONMODE_MOVE);
797
798         // 画面を再描画する
799         redrawSurfaceview();
800     }
801
802     /**
803      *    空き領域がタッチされた!
804      *
805      */
806     public int touchedVacantArea()
807     {
808         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
809         return (Integer.parseInt(preferences.getString("operationMode", "0")));
810     }
811
812     /**
813      *    空き領域でタッチが離された!
814      *
815      */
816     public int touchUppedVacantArea()
817     {
818         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
819         return (Integer.parseInt(preferences.getString("operationMode", "0")));
820     }
821
822     /**
823      *    オブジェクトを本当に削除して良いか確認した後に、オブジェクトを削除する。
824      *
825      *
826      */
827     private void removeObject(Integer key)
828     {
829         // 本当に消して良いか、確認をするダイアログを表示して、OKが押されたら消す。
830         AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(parent);
831         alertDialogBuilder.setTitle(parent.getString(R.string.deleteconfirm_title));
832         alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert);
833         alertDialogBuilder.setMessage(parent.getString(R.string.deleteconfirm_message));
834
835         // 削除するオブジェクトのキーを覚えこむ。
836         objectKeyToDelete = key;
837
838         // OKボタンの生成
839         alertDialogBuilder.setPositiveButton(parent.getString(R.string.confirmYes), new DialogInterface.OnClickListener()
840         {
841             public void onClick(DialogInterface dialog, int id)
842             {
843                 //  削除モードの時... 確認後削除だけど、今は確認なしで削除を行う。
844                 objectHolder.removePosition(objectKeyToDelete);
845
846                 // 削除するオブジェクトに接続されている線もすべて削除する
847                 objectHolder.getConnectLineHolder().removeAllConnection(objectKeyToDelete);
848
849                 // ダイアログを閉じる
850                 dialog.dismiss();
851
852                 // ここで動作モードを削除モードから移動モードに戻す。
853                 drawModeHolder.changeOperationMode(OperationModeHolder.OPERATIONMODE_MOVE);
854                 updateButtons(OperationModeHolder.OPERATIONMODE_MOVE);
855
856
857                 // 画面を再描画する
858                 redrawSurfaceview();
859             }
860         });
861
862         // Cancelボタンの生成
863         alertDialogBuilder.setNegativeButton(parent.getString(R.string.confirmNo), new DialogInterface.OnClickListener()
864         {
865             public void onClick(DialogInterface dialog, int id)
866             {
867                 dialog.cancel();
868             }
869         });
870
871         // ダイアログはキャンセル可能に設定する
872         alertDialogBuilder.setCancelable(true);
873
874         // ダイアログを表示する
875         AlertDialog alertDialog = alertDialogBuilder.create();
876         alertDialog.show();
877     }
878
879     /**
880      *    オブジェクトを複製する
881      *
882      *
883      */
884     private void duplicateObject(Integer key)
885     {
886         // 選択中オブジェクトを複製する
887         objectHolder.duplicatePosition(key);
888
889         // 画面を再描画する
890         redrawSurfaceview();
891     }
892
893     /**
894      *    オブジェクトを拡大する
895      *
896      *
897      */
898     private void expandObject(Integer key)
899     {
900         // 選択中オブジェクトを拡大する
901         objectHolder.expandObjectSize(key);
902
903         // 画面を再描画する
904         redrawSurfaceview();
905     }
906     /**
907      *    オブジェクトを縮小する
908      *
909      *
910      */
911     private void shrinkObject(Integer key)
912     {
913         // 選択中オブジェクトを縮小する
914         objectHolder.shrinkObjectSize(key);
915
916         // 画面を再描画する
917         redrawSurfaceview();
918     }
919
920     private void setButtonBorder(ImageButton button, boolean isHighlight)
921     {
922         try
923         {
924             BitmapDrawable btnBackgroundShape = (BitmapDrawable)button.getBackground();
925             if (isHighlight)
926             {
927 //                              btnBackgroundShape.setColorFilter(Color.rgb(51, 181, 229), Mode.LIGHTEN);
928                 btnBackgroundShape.setColorFilter(Color.BLUE, Mode.LIGHTEN);
929             }
930             else
931             {
932                 btnBackgroundShape.setColorFilter(Color.BLACK, Mode.LIGHTEN);
933             }
934         }
935         catch (Exception ex)
936         {
937             //
938             Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::setButtonBorder(): " + ex.toString());
939         }
940     }
941
942     /**
943      *   ボタンを更新する
944      *
945      */
946     private void updateButtons(int mode)
947     {
948         final ImageButton createObjectButton = parent.findViewById(R.id.CreateObjectButton);
949         final ImageButton deleteObjectButton = parent.findViewById(R.id.DeleteObjectButton);
950
951         if (mode == OperationModeHolder.OPERATIONMODE_DELETE)
952         {
953             setButtonBorder(createObjectButton, false);
954             setButtonBorder(deleteObjectButton, true);
955         }
956         else if (mode == OperationModeHolder.OPERATIONMODE_CREATE)
957         {
958             setButtonBorder(createObjectButton, true);
959             setButtonBorder(deleteObjectButton, false);
960         }
961         else // if (mode == OperationModeHolder.OPERATIONMODE_MOVE)
962         {
963             setButtonBorder(createObjectButton, false);
964             setButtonBorder(deleteObjectButton, false);
965         }
966     }
967
968
969     /**
970      *   オブジェクトが選択された(長押しで!)
971      *
972      */
973     public void objectSelectedContext(Integer key)
974     {
975         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::objectSelectedContext(),  key:" + key);
976         selectedContextKey = key;
977
978         // オブジェクトのアイテム選択ダイアログを表示する...
979         parent.showDialog(MENU_ID_OPERATION);
980
981     }
982
983
984     /**
985      *   オブジェクトが選択された!
986      *
987      */
988     public boolean objectSelected(Integer key)
989     {
990         SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
991         int operationMode = Integer.parseInt(preferences.getString("operationMode", "0"));
992         if (operationMode == OperationModeHolder.OPERATIONMODE_DELETE)
993         {
994             // オブジェクトを削除する
995             removeObject(key);
996
997             return (true);
998         }
999         //if ((operationMode == OperationModeHolder.OPERATIONMODE_MOVE)||
1000         //              (operationMode == OperationModeHolder.OPERATIONMODE_CREATE))
1001         {
1002             // 選択されたオブジェクトを記憶する
1003             selectedObjectKey = key;
1004             Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::objectSelected() key : " + key);
1005
1006             // オブジェクトの詳細設定ダイアログを表示する...
1007             parent.showDialog(R.id.objectinput_dialog);
1008         }
1009         return (true);
1010     }
1011
1012     /**
1013      *  ダイアログの生成
1014      *
1015      */
1016     public Dialog onCreateDialog(int id)
1017     {
1018         if (id == R.id.info_about_gokigen)
1019         {
1020             // クレジットダイアログを表示
1021             CreditDialog dialog = new CreditDialog(parent);
1022             return (dialog.getDialog());
1023         }
1024         if (id == R.id.editTextArea)
1025         {
1026             // 変更するテキストを表示
1027             return (editTextDialog.getDialog());
1028         }
1029         if (id == R.id.confirmation)
1030         {
1031             // 確認するメッセージを表示する
1032             return (confirmationDialog.getDialog());
1033         }
1034         if (id == R.id.objectinput_dialog)
1035         {
1036             // オブジェクト入力のダイアログを表示する
1037             return (objectDataInputDialog.getDialog());
1038         }
1039         if (id == MENU_ID_OPERATION)
1040         {
1041             // アイテム選択ダイアログの準備を行う
1042             return (itemSelectionDialog.getDialog());
1043         }
1044         if (id == R.id.selectline_dialog)
1045         {
1046             // 接続線選択ダイアログの準備を行う
1047             return (lineSelectionDialog.getDialog());
1048         }
1049         return (null);
1050     }
1051
1052     /**
1053      *  ダイアログ表示の準備
1054      *
1055      */
1056     public void onPrepareDialog(int id, Dialog dialog)
1057     {
1058         if (id == R.id.editTextArea)
1059         {
1060             // 変更するデータを表示する
1061             prepareInfoMessageEditDialog(dialog);
1062             return;
1063         }
1064         if (id == R.id.confirmation)
1065         {
1066             // 確認ダイアログを表示する。
1067             prepareConfirmationDialog(dialog);
1068             return;
1069         }
1070         if (id == R.id.objectinput_dialog)
1071         {
1072             // オブジェクト入力のダイアログを表示する
1073             prepareObjectInputDialog(dialog);
1074         }
1075         if (id == MENU_ID_OPERATION)
1076         {
1077             // オブジェクト操作選択のダイアログを表示する
1078             prepareItemSelectionDialog(dialog);
1079         }
1080         if (id == R.id.selectline_dialog)
1081         {
1082             // 接続線選択のダイアログを表示する
1083             prepareLineSelectionDialog(dialog);
1084         }
1085     }
1086
1087     /**
1088      *    新規状態に変更する。
1089      *
1090      */
1091     public void acceptConfirmation()
1092     {
1093         //
1094         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::acceptConfirmation()");
1095
1096         // オブジェクトデータをクリアする。
1097         objectHolder.removeAllPositions();  // オブジェクトの保持クラス
1098         objectHolder.getConnectLineHolder().removeAllLines();  // オブジェクト間の接続状態保持クラス
1099
1100         // 画面の倍率と表示位置を初期状態に戻す
1101         if (objectDrawer != null)
1102         {
1103             final SeekBar zoomBar = (SeekBar) parent.findViewById(R.id.ZoomInOut);
1104             objectDrawer.resetScaleAndLocation(zoomBar);
1105         }
1106
1107                 /*
1108                 // 題名を "無題"に変更し、関係情報をクリアする
1109                 String newName = parent.getString(R.string.no_name);
1110                 parent.setTitle(newName);
1111                 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1112             SharedPreferences.Editor editor = preferences.edit();
1113             editor.putString("MeMoMaInfo", newName);
1114             editor.commit();
1115             */
1116
1117         // 画面を再描画する
1118         redrawSurfaceview();
1119
1120         // ファイル名選択ダイアログを開く
1121         showInfoMessageEditDialog();
1122
1123     }
1124
1125     /**
1126      *   画面を再描画する
1127      *
1128      */
1129     private void redrawSurfaceview()
1130     {
1131         final GokigenSurfaceView surfaceview = parent.findViewById(R.id.GraphicView);
1132         surfaceview.doDraw();
1133     }
1134
1135     /**
1136      *    不許可。何もしない。
1137      *
1138      */
1139     public  void rejectConfirmation()
1140     {
1141         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::rejectConfirmation()");
1142     }
1143
1144     /**
1145      *   オブジェクトが整列された時の処理
1146      *
1147      */
1148     public void objectAligned()
1149     {
1150         // 画面の再描画を指示する
1151         redrawSurfaceview();
1152     }
1153
1154     /**
1155      *   オブジェクト編集ダイアログが閉じられた時の処理
1156      *
1157      */
1158     public void finishObjectInput()
1159     {
1160         // 画面の再描画を指示する
1161         redrawSurfaceview();
1162     }
1163
1164     /**
1165      *   オブジェクト編集ダイアログが閉じられた時の処理
1166      *
1167      */
1168     public void cancelObjectInput()
1169     {
1170         // 何もしない
1171     }
1172
1173
1174     /**
1175      *   現在編集中かどうかを知る
1176      *
1177      *
1178      */
1179     public boolean isEditing()
1180     {
1181         return (isEditing);
1182     }
1183
1184     /**
1185      *   現在編集中のフラグを更新する
1186      *
1187      *
1188      */
1189     public void setIsEditing(boolean value)
1190     {
1191         isEditing = value;
1192     }
1193
1194     /**
1195      *   アイテムが選択された!
1196      *
1197      */
1198     public void itemSelected(int index, String itemValue)
1199     {
1200         //
1201         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::itemSelected() : " + itemValue + " [" + index + "]");
1202
1203         if (index == ObjectOperationCommandHolder.OBJECTOPERATION_DELETE)
1204         {
1205             // オブジェクト削除の確認
1206             removeObject(selectedContextKey);
1207         }
1208         else if (index == ObjectOperationCommandHolder.OBJECTOPERATION_DUPLICATE)
1209         {
1210             // オブジェクトの複製
1211             duplicateObject(selectedContextKey);
1212         }
1213         else if (index == ObjectOperationCommandHolder.OBJECTOPERATION_SIZEBIGGER)
1214         {
1215             // オブジェクトの拡大
1216             expandObject(selectedContextKey);
1217         }
1218         else if (index == ObjectOperationCommandHolder.OBJECTOPERATION_SIZESMALLER)
1219         {
1220             // オブジェクトの縮小
1221             shrinkObject(selectedContextKey);
1222         }
1223     }
1224
1225     /**
1226      *    (今回未使用)
1227      *
1228      */
1229     public void itemSelectedMulti(String[] items, boolean[] status)
1230     {
1231
1232     }
1233     public void canceledSelection()
1234     {
1235
1236     }
1237
1238     public void onSaveInstanceState(Bundle outState)
1239     {
1240         /* ここで状態を保存 */
1241         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::onSaveInstanceState() : " + outState.toString() );
1242     }
1243
1244     public void onRestoreInstanceState(Bundle savedInstanceState)
1245     {
1246         /* ここで状態を復元 */
1247         Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::onRestoreInstanceState() : " + savedInstanceState.toString());
1248     }
1249
1250     public boolean finishTextEditDialog(String message)
1251     {
1252         if ((message == null)||(message.length() == 0))
1253         {
1254             // データが入力されていなかったので、何もしない。
1255             return (false);
1256         }
1257
1258         try
1259         {
1260             // 文字列を記録
1261             SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1262             SharedPreferences.Editor editor = preferences.edit();
1263             editor.putString("MeMoMaInfo", message);
1264             editor.apply();
1265
1266             // タイトルに設定
1267             parent.setTitle(message);
1268
1269             // 保存シーケンスを一度走らせる
1270             saveData(true);
1271
1272             // ファイル選択リストの更新
1273             dataInOutManager.updateFileList(message, parent.getSupportActionBar());
1274
1275         }
1276         catch (Exception e)
1277         {
1278             e.printStackTrace();
1279         }
1280         return (true);
1281     }
1282     public boolean cancelTextEditDialog()
1283     {
1284         return (false);
1285     }
1286
1287     /**
1288      *    接続線
1289      *
1290      */
1291     public void finishSelectLineShape(int style, int shape, int thickness)
1292     {
1293         int buttonId = LineStyleHolder.getLineShapeImageId(style, shape);
1294         final ImageButton lineStyleObj =parent.findViewById(R.id.LineStyleButton);
1295         lineStyleObj.setImageResource(buttonId);
1296         //Log.v(Main.APP_IDENTIFIER, "MeMoMaListener::finishSelectLineShape() buttonId:" + buttonId);
1297     }
1298
1299     /**
1300      *
1301      *
1302      */
1303     public void cancelSelectLineShape()
1304     {
1305
1306     }
1307
1308 }