3 import java.util.ArrayList;
4 import java.util.Collections;
7 import android.content.BroadcastReceiver;
8 import android.content.Context;
9 import android.content.Intent;
10 import android.content.IntentFilter;
11 import android.database.sqlite.SQLiteDatabase;
12 import android.graphics.Bitmap;
13 import android.graphics.PixelFormat;
14 import android.os.Bundle;
15 import android.text.Editable;
16 import android.text.TextWatcher;
17 import android.view.Gravity;
18 import android.view.Menu;
19 import android.view.MenuItem;
20 import android.view.View;
21 import android.view.View.OnClickListener;
22 import android.view.WindowManager;
23 import android.view.inputmethod.InputMethodManager;
24 import android.widget.Button;
25 import android.widget.EditText;
26 import android.widget.LinearLayout;
27 import android.widget.TextView;
29 import com.yuji.ef.common.CommonUtil;
30 import com.yuji.ef.common.Constant;
31 import com.yuji.ef.dao.DatabaseHelper;
32 import com.yuji.ef.dao.DirNode;
33 import com.yuji.ef.dao.FileNode;
34 import com.yuji.ef.dao.LockDao;
35 import com.yuji.ef.dao.Node;
36 import com.yuji.ef.dao.Node.Status;
37 import com.yuji.ef.dao.NodeCacheDao;
38 import com.yuji.ef.dao.NodeComparator;
39 import com.yuji.ef.dao.NodeDao;
40 import com.yuji.ef.dao.NodeDaoImpl;
41 import com.yuji.ef.dao.RootNode;
42 import com.yuji.ef.exception.EfError;
43 import com.yuji.ef.exception.EfException;
44 import com.yuji.ef.pref.EditPrefUtil;
45 import com.yuji.ef.utility.BaseActivity;
46 import com.yuji.ef.utility.BitmapCacheFactory;
47 import com.yuji.ef.utility.EvernoteIntentUtil;
48 import com.yuji.ef.utility.FolderUtil;
49 import com.yuji.ef.utility.LockHandler;
50 import com.yuji.ef.utility.LockListener;
51 import com.yuji.ef.utility.ScaleUtil;
53 public class EverFolderActivity extends BaseActivity implements LockListener {
54 private enum ScreenStatus {
55 Normal, AddNode, DeleteNode, RenameNode
58 private EditPrefUtil pref = new EditPrefUtil(this);
60 private LinearLayout msgLayout;
61 private LinearLayout msgButtonLayout;
62 private Button msgOkButton;
63 private Button msgCancelButton;
64 private EditText msgEditText;
66 private IconFrameLayout layout;
67 private TextView confirmMsg;
68 private IconScrollView scrollView;
69 private LinearLayout buttonLayout;
70 private Button leftButton;
71 private Button rightButton;
73 private ScreenStatus status;
74 private NodeComparator nodeComparator = new NodeComparator();
75 private BitmapCacheFactory bitmapFactory = BitmapCacheFactory.getInstance();
76 private Node top = null;
77 private int indent = 0;
78 private int bmpPaddingLeft;
81 private boolean lock = false;
82 private boolean isInit = true;
83 private boolean isInCycle = false;
84 private boolean isResult = false;
85 private LockHandler lockHandler = null;
87 private BroadcastReceiver receiver = new BroadcastReceiver() {
89 public void onReceive(Context context, Intent intent) {
90 String action = intent.getAction();
92 if (action.equals(Constant.ACTION_MESSAGE)) {
94 .getStringExtra(Constant.ACTION_MESSAGE_MESSAGE);
95 EfException.msg(EverFolderActivity.this, msg);
96 } else if (action.equals(Constant.ACTION_UPDATE)) {
97 if (isInCycle && !lock) {
98 LockDao lockDao = (LockDao) LockDao.getInstance();
99 lock = lockDao.lock(EverFolderActivity.this,
100 Constant.LOCK_UPDATE_NOTE);
103 // ほんとは、setStatus()に入れたい
104 layout.setVisibility(View.VISIBLE);
113 public void onCreate(Bundle savedInstanceState) {
114 super.onCreate(savedInstanceState);
115 setContentView(R.layout.main);
118 IntentFilter intentFilter = new IntentFilter();
119 intentFilter.addAction(Constant.ACTION_UPDATE);
120 intentFilter.addAction(Constant.ACTION_MESSAGE);
121 registerReceiver(receiver, intentFilter);
123 scrollView = (IconScrollView) findViewById(R.id.scrollView);
124 layout = (IconFrameLayout) findViewById(R.id.frameLayout);
125 layout.setActivity(this);
126 layout.setScrollView(scrollView);
128 buttonLayout = (LinearLayout) findViewById(R.id.mainButtonLayout);
129 leftButton = (Button) findViewById(R.id.leftButton);
130 rightButton = (Button) findViewById(R.id.rightButton);
132 msgLayout = (LinearLayout) findViewById(R.id.mainMsgLayout);
133 confirmMsg = (TextView) findViewById(R.id.mainConfirmMsg);
134 msgEditText = (EditText) findViewById(R.id.mainMsgEditText);
135 msgButtonLayout = (LinearLayout) findViewById(R.id.mainMsgButtonLayout);
136 msgOkButton = (Button) findViewById(R.id.mainMsgOkButton);
137 msgCancelButton = (Button) findViewById(R.id.mainMsgCancelButton);
139 leftButton.setOnClickListener(new OnClickListener() {
141 public void onClick(View v) {
145 rightButton.setOnClickListener(new OnClickListener() {
147 public void onClick(View v) {
148 rightButtonOnClick();
152 msgEditText.addTextChangedListener(new TextWatcher() {
153 public void afterTextChanged(Editable s) {
154 if (status != ScreenStatus.DeleteNode) {
155 String text = s.toString();
156 msgOkButton.setEnabled(text.length() > 0);
158 msgOkButton.setEnabled(true);
162 public void beforeTextChanged(CharSequence s, int start,
163 int count, int after) {
167 public void onTextChanged(CharSequence s, int start,
168 int before, int count) {
173 msgOkButton.setOnClickListener(new OnClickListener() {
175 public void onClick(View v) {
176 msgOkButtonOnClick(v);
179 msgCancelButton.setOnClickListener(new OnClickListener() {
181 public void onClick(View v) {
186 ScaleUtil scaleUtil = ScaleUtil.getInstance();
187 scaleUtil.init(this);
189 bitmapFactory.init(this);
190 Node node = new DirNode(null, null);
192 bmp = bitmapFactory.get(node.getStatusIconId());
193 bmpPaddingLeft = bmp.getWidth();
194 bmp = bitmapFactory.get(node.getIconId());
195 bmpWidth = bmp.getWidth();
197 float fSize = 48 * (1 / 2.0f);
198 leftButton.setTextSize(fSize);
199 rightButton.setTextSize(fSize);
200 } catch (Exception e) {
201 EfException.msg(R.string.ErrorSystem, e);
206 public boolean onCreateOptionsMenu(Menu menu) {
207 boolean ret = super.onCreateOptionsMenu(menu);
210 menu.add(Menu.NONE, Menu.FIRST + index++, Menu.NONE,
211 getString(R.string.MenuCut));
212 menu.add(Menu.NONE, Menu.FIRST + index++, Menu.NONE,
213 getString(R.string.MenuPaste));
214 menu.add(Menu.NONE, Menu.FIRST + index++, Menu.NONE,
215 getString(R.string.MenuAdd));
216 menu.add(Menu.NONE, Menu.FIRST + index++, Menu.NONE,
217 getString(R.string.MenuDelete));
218 menu.add(Menu.NONE, Menu.FIRST + index++, Menu.NONE,
219 getString(R.string.MenuRename));
220 menu.add(Menu.NONE, Menu.FIRST + index++, Menu.NONE,
221 getString(R.string.MenuSetting));
226 public boolean onMenuOpened(int featureId, Menu menu) {
227 boolean ret = super.onMenuOpened(featureId, menu);
236 boolean cutButtonFlag = false;
237 boolean pastButtonFlag = false;
238 boolean addButtonFlag = false;
239 boolean deleteButtonFlag = false;
240 boolean renameButtonFlag = false;
241 boolean confButtonFlag = true;
243 if (status == ScreenStatus.Normal) {
244 LabelIconView target = layout.getSelectedTarget();
245 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
248 if (target != null) {
249 id = target.getNodeId();
250 node = dao.searchById(id);
253 if (isDirNode(target, node, false) || isFileNode(node)) {
254 cutButtonFlag = true;
256 if (isDirNode(target, node, true) && isCut()) {
257 pastButtonFlag = true;
259 if (isDirNode(target, node, true)) {
260 addButtonFlag = true;
262 if (isDirNode(target, node, false) && !isNoteBook(node)
263 && CommonUtil.isNull(node.getChildrenString())) {
264 deleteButtonFlag = true;
266 if (isDirNode(target, node, false) && !isNoteBook(node)) {
267 renameButtonFlag = true;
272 item = menu.getItem(index++);
273 item.setVisible(cutButtonFlag);
274 item = menu.getItem(index++);
275 item.setVisible(pastButtonFlag);
276 item = menu.getItem(index++);
277 item.setVisible(addButtonFlag);
278 item = menu.getItem(index++);
279 item.setVisible(deleteButtonFlag);
280 item = menu.getItem(index++);
281 item.setVisible(renameButtonFlag);
282 item = menu.getItem(index++);
283 item.setVisible(confButtonFlag);
288 private boolean isFileNode(Node node) {
289 if (node == null || !(node instanceof FileNode)) {
295 private boolean isDirNode(LabelIconView target, Node node,
296 boolean containRoot) {
297 if (target == null) {
303 if (!containRoot && (node instanceof RootNode)) {
306 if (!(node instanceof DirNode)) {
312 private boolean isNoteBook(Node node) {
316 if (CommonUtil.isNull(node.getGuid())) {
322 private boolean isCut() {
323 LabelIconView srcTarget = layout.getCutTarget();
324 if (srcTarget == null) {
331 public boolean onOptionsItemSelected(MenuItem item) {
334 switch (item.getItemId()) {
353 intent = new Intent(this, (Class<?>) SettingActivity.class);
354 startActivityForResult(intent, 0);
359 } catch (Exception e) {
362 return super.onOptionsItemSelected(item);
365 private void dummy() {
366 NodeDaoImpl dao = (NodeDaoImpl) NodeCacheDao.getInstance();
367 List<Node> list = dao.search();
368 for (Node node : list) {
369 System.out.println(node.toString());
373 private void dummy2() {
374 LockDao dao = (LockDao) LockDao.getInstance();
378 b = dao.lock(this, "key");
379 b = dao.lock(this, "key");
380 b = dao.lock(new Object(), "key");
381 dao.unlock(this, "key");
382 b = dao.lock(new Object(), "key");
383 b = dao.lock(this, "key");
384 b = dao.lock(this, "key");
385 b = dao.lock(this, "key");
386 dao.unlock(new Object(), "key");
388 } catch (Exception e) {
394 private void selectMenuAdd() {
395 setStatus(ScreenStatus.AddNode);
398 private void selectMenuDelete() {
399 setStatus(ScreenStatus.DeleteNode);
402 private void selectMenuRename() {
403 LabelIconView target = layout.getSelectedTarget();
404 if (target == null) {
408 long id = target.getNodeId();
409 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
410 Node node = dao.searchById(id);
412 String text = node.getName();
413 msgEditText.setText(text);
414 setStatus(ScreenStatus.RenameNode);
418 private void selectMenuCut() {
419 LabelIconView target = layout.getSelectedTarget();
420 if (target == null) {
424 layout.setCutTarget(target);
428 private void selectMenuPast() {
429 LabelIconView srcTarget = layout.getCutTarget();
430 if (srcTarget == null) {
434 LabelIconView dstTarget = layout.getSelectedTarget();
435 if (dstTarget == null) {
439 layout.setCutTarget(null);
441 long srcId = srcTarget.getNodeId();
442 long dstId = dstTarget.getNodeId();
443 execute(srcId, dstId);
446 private void updateList() {
447 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
448 top = dao.searchRoot();
456 private void updateList(Node parent) {
459 scrollView.setVisibility(View.GONE);
460 layout.removeAllViews();
461 updateList(parent, 0);
462 layout.setMinimumHeight(viewY);
463 scrollView.setVisibility(View.VISIBLE);
466 scrollView.invalidate();
469 private void updateList(Node node, int depth) {
470 int N = (int) (bmpWidth * 0.6);
471 int M = (int) (bmpWidth * 1.2);
472 int x = N * (depth - indent);
474 if (depth - indent >= 0
475 && !(depth - indent == 0 && node instanceof FileNode)) {
476 LabelIconView view = new LabelIconView(this);
480 int id = node.getStatusIconId();
483 bmp1 = bitmapFactory.get(node.getStatusIconId());
488 Bitmap bmp2 = bitmapFactory.get(node.getIconId());
489 createIconImageView(view, bmp1, bmp2, node.getName(), x, viewY);
490 // LabelIconView s = view.getStatusImageView();
492 // s.setNodeId(node.getId());
494 view.setNodeId(node.getId());
498 if (node.getStatus() != Node.Status.OPEN) {
501 List<Long> idList = node.getChildren();
502 if (idList == null) {
506 List<Node> list = new ArrayList<Node>();
507 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
508 for (Long id : idList) {
509 Node n = dao.searchById(id);
514 if (n instanceof DirNode) {
515 DirNode d = (DirNode) n;
516 if (isNoteBook(d) && !d.isSelected()) {
522 Collections.sort(list, nodeComparator);
523 for (Node n : list) {
524 updateList(n, depth + 1);
528 private void createIconImageView(LabelIconView v, Bitmap bmp1, Bitmap bmp2,
529 String text, int x, int y) {
530 v.init(x, y, bmp1, bmp2, text);
532 android.view.WindowManager.LayoutParams params = new WindowManager.LayoutParams();
533 params.gravity = Gravity.TOP | Gravity.LEFT;
534 params.height = WindowManager.LayoutParams.WRAP_CONTENT;
535 params.width = WindowManager.LayoutParams.WRAP_CONTENT;
536 params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
537 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
538 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
539 | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
540 params.format = PixelFormat.TRANSLUCENT;
541 params.windowAnimations = 0;
544 v.setLayoutParams(params);
547 v.layout(x, y, x + v.getWidth(), y + v.getHeight());
551 public void sendLockResult(boolean b) {
553 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
555 pref.put(Constant.PREF_UPDATE_DATA, Constant.OFF);
568 Intent intent = new Intent(this,
569 (Class<?>) SettingActivity.class);
570 startActivityForResult(intent, 0);
581 status = ScreenStatus.Normal;
584 layout.setVisibility(View.VISIBLE);
587 layout.removeAllViews();
593 layout.setVisibility(View.VISIBLE);
599 LockDao lockDao = (LockDao) LockDao.getInstance();
600 lockDao.unlock(EverFolderActivity.this, Constant.LOCK_UPDATE_NOTE);
606 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
612 protected void onStart() {
617 protected void onResume() {
622 boolean isUnlock = pref.getInt(Constant.PREF_DELETE_LOCK)== Constant.ON;
624 pref.put(Constant.PREF_DELETE_LOCK, Constant.OFF);
628 lockHandler = new LockHandler();
629 lockHandler.lock(this, Constant.LOCK_UPDATE_NOTE, true, isUnlock);
633 layout.setVisibility(View.INVISIBLE);
639 layout.setVisibility(View.INVISIBLE);
645 protected void onPause() {
646 // ロック未取得でも解除する(ゴミ掃除)
647 LockDao lockDao = (LockDao) LockDao.getInstance();
648 lockDao.unlock(this, Constant.LOCK_UPDATE_NOTE);
651 if (lockHandler != null){
652 lockHandler.cancel();
660 private void leftButtonOnClick() {
661 moveButtonOnClick(-1);
665 private void rightButtonOnClick() {
666 moveButtonOnClick(1);
670 private void moveButtonOnClick(int dx) {
687 private void msgOkButtonOnClick(View v) {
688 FolderUtil util = FolderUtil.getInstance();
689 LabelIconView target = layout.getSelectedTarget();
690 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
692 if (status == ScreenStatus.AddNode) {
693 long id = target.getNodeId();
694 Node parent = dao.searchById(id);
695 if (parent != null) {
696 String text = msgEditText.getText().toString();
697 DirNode node = new DirNode(text, null);
698 util.addDirNode(parent, node);
700 layout.setCutTarget(null, false);
701 } else if (status == ScreenStatus.DeleteNode) {
702 long id = target.getNodeId();
703 Node node = dao.searchById(id);
705 util.deleteNode(node);
706 layout.removeView(target);
708 layout.setCutTarget(null, false);
709 } else if (status == ScreenStatus.RenameNode) {
710 long id = target.getNodeId();
711 Node node = dao.searchById(id);
713 String text = msgEditText.getText().toString();
715 dao.updateName(node, text);
717 layout.setCutTarget(null, false);
722 layout.clearTarget();
724 setStatus(ScreenStatus.Normal);
727 private void msgCancelOnClick(View v) {
730 setStatus(ScreenStatus.Normal);
733 private void closeIME(View v) {
734 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
735 imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
738 public void execute(long srcId, long dstId) {
742 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
745 throw new EfException(EfError.NOT_FOUND);
748 throw new EfException(EfError.NOT_FOUND);
751 Node src = dao.searchById(srcId);
753 if (srcId == dstId) {
756 dst = dao.searchById(dstId);
759 if (dstId == src.getParent()) {
763 if (!isFileNode(src) && !isMovable(srcId, dstId)) {
768 Node sp = dao.searchById(src.getParent());
770 throw new EfException(EfError.NOT_FOUND);
773 if (src.getParent() == dst.getParent() || dst.getParent() < 0) {
776 dp = dao.searchById(dst.getParent());
779 throw new EfException(EfError.NOT_FOUND);
782 SQLiteDatabase db = DatabaseHelper.getInstance()
783 .getSQLiteDatabase();
784 db.beginTransaction();
786 dao.removeChildrenIdNT(sp, src.getId());
787 if (dst instanceof DirNode) {
788 dao.updateParentNT(src, dst.getId());
789 dao.addChildrenIdNT(dst, src.getId());
790 } else if (dst instanceof FileNode) {
791 dao.updateParentNT(src, dp.getId());
792 dao.addChildrenIdNT(dp, src.getId());
795 db.setTransactionSuccessful();
799 } catch (EfException e) {
800 EfException.msg(R.string.ErrorSystem, e);
806 private boolean isMovable(long srcId, long dstId) {
807 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
810 if (srcId == dstId) {
813 Node node = dao.searchById(dstId);
818 if (!(node instanceof DirNode)) {
821 dstId = node.getParent();
826 public void execute(long id) {
828 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
830 Node node = dao.searchById(id);
832 throw new EfException(EfError.NOT_FOUND);
835 Status status = node.getStatus();
837 dao.updateStatus(node, status);
840 } catch (EfException e) {
841 EfException.msg(R.string.ErrorSystem, e);
845 public void executeView(long id) {
846 NodeDao dao = (NodeDao) NodeCacheDao.getInstance();
848 Node node = dao.searchById(id);
849 if (!isFileNode(node)) {
852 String guid = node.getGuid();
854 EvernoteIntentUtil util = EvernoteIntentUtil.getInstance();
855 util.viewNote(this, guid);
858 public void targetSelectedChanged(boolean status) {
862 public void removeAllNodeView() {
863 layout.removeAllViews();
866 private void setStatus() {
870 private void setStatus(ScreenStatus status) {
872 if (this.status != status) {
873 this.status = status;
877 int update = pref.getInt(Constant.PREF_UPDATE_DATA);
879 if (update == Constant.ON) {
880 msgLayout.setVisibility(View.VISIBLE);
881 confirmMsg.setText(getString(R.string.mainUpdateMsg));
883 msgLayout.setVisibility(View.GONE);
885 msgEditText.setVisibility(View.GONE);
886 msgButtonLayout.setVisibility(View.GONE);
888 leftButton.setEnabled(false);
889 rightButton.setEnabled(false);
891 status = ScreenStatus.Normal;
895 if (status == ScreenStatus.Normal) {
896 msgLayout.setVisibility(View.GONE);
898 boolean leftButtonFlag = true;
899 boolean rightButtonFlag = true;
902 leftButtonFlag = false;
905 layout.setElabledTouchEvent(true);
907 leftButton.setEnabled(leftButtonFlag);
908 rightButton.setEnabled(rightButtonFlag);
909 } else if (status == ScreenStatus.AddNode) {
910 msgLayout.setVisibility(View.VISIBLE);
911 msgEditText.setVisibility(View.VISIBLE);
912 msgButtonLayout.setVisibility(View.VISIBLE);
913 confirmMsg.setText(getString(R.string.mainAddMsg));
914 msgEditText.setText("");
916 layout.setElabledTouchEvent(false);
918 leftButton.setEnabled(false);
919 rightButton.setEnabled(false);
920 } else if (status == ScreenStatus.DeleteNode) {
921 msgLayout.setVisibility(View.VISIBLE);
922 msgEditText.setVisibility(View.GONE);
923 msgButtonLayout.setVisibility(View.VISIBLE);
924 confirmMsg.setText(getString(R.string.mainDeleteMsg));
926 layout.setElabledTouchEvent(false);
928 leftButton.setEnabled(false);
929 rightButton.setEnabled(false);
930 } else if (status == ScreenStatus.RenameNode) {
931 msgLayout.setVisibility(View.VISIBLE);
932 msgEditText.setVisibility(View.VISIBLE);
933 msgButtonLayout.setVisibility(View.VISIBLE);
934 confirmMsg.setText(getString(R.string.mainRenameMsg));
936 layout.setElabledTouchEvent(false);
938 leftButton.setEnabled(false);
939 rightButton.setEnabled(false);
941 } catch (Exception e) {
942 EfException.msg(R.string.ErrorSystem, e);