Compare commits

...

8 Commits

3
.idea/.gitignore vendored

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/单机版-小米便签-设置密码-报告.iml" filepath="$PROJECT_DIR$/.idea/单机版-小米便签-设置密码-报告.iml" />
</modules>
</component>
</project>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings" defaultProject="true" />
</project>

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="NONE" />
</component>
<component name="ChangeListManager">
<list default="true" id="6809de1b-6483-4e6d-838b-e2e059454c7b" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ClangdSettings">
<option name="formatViaClangd" value="false" />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 3
}</component>
<component name="ProjectId" id="2yXPtZWDIM0mRzuoyeurmc2ZyDL" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"RunOnceActivity.readMode.enableVisualFormatting": "true",
"cf.first.check.clang-format": "false",
"cidr.known.project.marker": "true",
"com.google.services.firebase.aqiPopupShown": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "D:/BaiduNetdiskDownload/单机版-小米便签-设置密码-报告/miui-notes-develop/doc",
"settings.editor.selected.configurable": "http.proxy"
}
}]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="D:\BaiduNetdiskDownload\单机版-小米便签-设置密码-报告\miui-notes-develop\doc" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\BaiduNetdiskDownload\单机版-小米便签-设置密码-报告\miui-notes-develop\doc" />
</key>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="6809de1b-6483-4e6d-838b-e2e059454c7b" name="Changes" comment="" />
<created>1749978160169</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1749978160169</updated>
</task>
<servers />
</component>
</project>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -1,9 +0,0 @@
# generated files
bin/
gen/
# Local configuration file (sdk path, etc)
project.properties
.settings/
.classpath
.project

@ -1,190 +0,0 @@
Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

@ -1,23 +0,0 @@
[中文]
1. MiCode便签是小米便签的社区开源版由MIUI团队(www.miui.com) 发起并贡献第一批代码遵循NOTICE文件所描述的开源协议
今后为MiCode社区(www.micode.net) 拥有,并由社区发布和维护。
2. Bug反馈和跟踪请访问Github,
https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
3. 功能建议和综合讨论请访问MiCode,
http://micode.net/forum.php?mod=forumdisplay&fid=38
[English]
1. MiCode Notes is open source edition of XM notepad, it's first initiated and sponsored by MIUI team (www.miui.com).
It's opened under license described by NOTICE file. It's owned by the MiCode community (www.micode.net). In future,
the MiCode community will release and maintain this project.
2. Regarding issue tracking, please visit Github,
https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
3. Regarding feature request and general discussion, please visit Micode forum,
http://micode.net/forum.php?mod=forumdisplay&fid=38

@ -1,217 +0,0 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.content.Context;
import android.graphics.Rect;
import android.text.Layout;
import android.text.Selection;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.widget.EditText;
import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
public class NoteEditText extends EditText {
private static final String TAG = "NoteEditText";
private int mIndex;
private int mSelectionStartBeforeDelete;
private static final String SCHEME_TEL = "tel:" ;
private static final String SCHEME_HTTP = "http:" ;
private static final String SCHEME_EMAIL = "mailto:" ;
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
static {
sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel);
sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web);
sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email);
}
/**
* Call by the {@link NoteEditActivity} to delete or add edit text
*/
public interface OnTextViewChangeListener {
/**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
* and the text is null
*/
void onEditTextDelete(int index, String text);
/**
* Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER}
* happen
*/
void onEditTextEnter(int index, String text);
/**
* Hide or show item option when text change
*/
void onTextChange(int index, boolean hasText);
}
private OnTextViewChangeListener mOnTextViewChangeListener;
public NoteEditText(Context context) {
super(context, null);
mIndex = 0;
}
public void setIndex(int index) {
mIndex = index;
}
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener;
}
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle);
}
public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
int y = (int) event.getY();
x -= getTotalPaddingLeft();
y -= getTotalPaddingTop();
x += getScrollX();
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
Selection.setSelection(getText(), off);
break;
}
return super.onTouchEvent(event);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
if (mOnTextViewChangeListener != null) {
return false;
}
break;
case KeyEvent.KEYCODE_DEL:
mSelectionStartBeforeDelete = getSelectionStart();
break;
default:
break;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_DEL:
if (mOnTextViewChangeListener != null) {
if (0 == mSelectionStartBeforeDelete && mIndex != 0) {
mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString());
return true;
}
} else {
Log.d(TAG, "OnTextViewChangeListener was not seted");
}
break;
case KeyEvent.KEYCODE_ENTER:
if (mOnTextViewChangeListener != null) {
int selectionStart = getSelectionStart();
String text = getText().subSequence(selectionStart, length()).toString();
setText(getText().subSequence(0, selectionStart));
mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text);
} else {
Log.d(TAG, "OnTextViewChangeListener was not seted");
}
break;
default:
break;
}
return super.onKeyUp(keyCode, event);
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (mOnTextViewChangeListener != null) {
if (!focused && TextUtils.isEmpty(getText())) {
mOnTextViewChangeListener.onTextChange(mIndex, false);
} else {
mOnTextViewChangeListener.onTextChange(mIndex, true);
}
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
@Override
protected void onCreateContextMenu(ContextMenu menu) {
if (getText() instanceof Spanned) {
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();
int min = Math.min(selStart, selEnd);
int max = Math.max(selStart, selEnd);
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);
if (urls.length == 1) {
int defaultResId = 0;
for(String schema: sSchemaActionResMap.keySet()) {
if(urls[0].getURL().indexOf(schema) >= 0) {
defaultResId = sSchemaActionResMap.get(schema);
break;
}
}
if (defaultResId == 0) {
defaultResId = R.string.note_link_other;
}
menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener(
new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// goto a new intent
urls[0].onClick(NoteEditText.this);
return true;
}
});
}
}
super.onCreateContextMenu(menu);
}
}

@ -1,2 +0,0 @@
# Mi_Note

@ -1,2 +0,0 @@
111
lpq

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 吴柚柚
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,40 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion '30.0.2'
namespace 'net.micode.notes'
defaultConfig {
applicationId "net.micode.notes"
minSdkVersion 21
targetSdkVersion 8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.5.0'
}
}
allprojects {
repositories {
jcenter()
google()
}
}
tasks.withType(JavaCompile){
options.encoding = "UTF-8"
}

@ -0,0 +1,30 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
org.gradle.daemon = true
org.gradle.parallel = true
org.gradle.configureondemand=true
android.nonTransitiveRClass=true
android.enableJetifier=true
android.injected.testOnly = false
android.enableDexingArtifactTransfrom=false
android.nonFinalResIds = false

@ -0,0 +1,6 @@
#Sat Mar 23 02:05:41 CST 2024
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

@ -0,0 +1,8 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Fri Jun 07 11:35:47 CST 2024
sdk.dir=E\:\\Android\\sdk

@ -16,6 +16,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="net.micode.notes"
android:versionCode="1"
android:versionName="0.1" >
@ -54,9 +55,10 @@
android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/NoteTheme" >
android:theme="@style/NoteTheme"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<intent-filter android:scheme="http" tools:ignore="AppLinkUrlError">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
@ -146,5 +148,6 @@
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
</application>
</manifest>

@ -86,6 +86,7 @@ public class Notes {
*/
public static final String MODIFIED_DATE = "modified_date";
//public static final String TOP = "top";
/**
* Alert date
@ -110,6 +111,7 @@ public class Notes {
* <P> Type: INTEGER (long) </P>
*/
public static final String WIDGET_TYPE = "widget_type";
public static final String PASSWORD = "secretKey";
/**
* Note's background color's id
@ -204,6 +206,8 @@ public class Notes {
*/
public static final String CONTENT = "content";
public static final String PASSWORD = "secretKey";
/**
* Generic data column, the meaning is {@link #MIMETYPE} specific, used for
@ -250,6 +254,8 @@ public class Notes {
public static final int MODE_CHECK_LIST = 1;
//public static final int MODE_CHECK_LIST1 = 1;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note";

@ -53,6 +53,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," +
DataColumns.PASSWORD + " TEXT," +
NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," +
@ -71,6 +72,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," +
DataColumns.PASSWORD + " TEXT," +
DataColumns.DATA1 + " INTEGER," +
DataColumns.DATA2 + " INTEGER," +
DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," +

@ -239,6 +239,10 @@ public class NotesProvider extends ContentProvider {
count = db.update(TABLE.NOTE, values, selection, selectionArgs);
break;
case URI_NOTE_ITEM:
String secret_key = (String) values.get("secretKey");
if (!TextUtils.isEmpty(secret_key)){
values.put("secretKey",secret_key);
}
id = uri.getPathSegments().get(1);
increaseNoteVersion(Long.valueOf(id), selection, selectionArgs);
count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id
@ -249,6 +253,7 @@ public class NotesProvider extends ContentProvider {
updateData = true;
break;
case URI_DATA_ITEM:
// values.put("secret_key", "123");
id = uri.getPathSegments().get(1);
count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id
+ parseSelection(selection), selectionArgs);

@ -39,6 +39,7 @@ public abstract class Node {
public static final int SYNC_ACTION_ERROR = 8;
private String mGid;
private String mName;

@ -509,6 +509,8 @@ public class GTaskClient {
}
}
public JSONArray getTaskLists() throws NetworkFailureException {
if (!mLoggedin) {
Log.e(TAG, "please login first");

@ -23,6 +23,7 @@ import android.content.Context;
import android.content.OperationApplicationException;
import android.net.Uri;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.data.Notes;
@ -80,6 +81,10 @@ public class Note {
mNoteData.setTextData(key, value);
}
public void setTextData(String key, String value,String secretKey) {
mNoteData.setTextData(key, value,secretKey);
}
public void setTextDataId(long id) {
mNoteData.setTextDataId(id);
}
@ -178,6 +183,15 @@ public class Note {
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
void setTextData(String key, String value,String secretKey) {
mTextDataValues.put(key, value);
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
if (!TextUtils.isEmpty(secretKey)){
mNoteDiffValues.put("secretkey",secretKey);
}
}
Uri pushIntoContentResolver(Context context, long noteId) {
/**
* Check for safety

@ -22,7 +22,9 @@ import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.CallNote;
import net.micode.notes.data.Notes.DataColumns;
@ -30,6 +32,7 @@ import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.tool.ResourceParser.NoteBgResources;
import net.micode.notes.ui.NotesListItem;
public class WorkingNote {
@ -38,7 +41,7 @@ public class WorkingNote {
// Note Id
private long mNoteId;
// Note content
private String mContent;
public String mContent;
// Note mode
private int mMode;
@ -60,6 +63,8 @@ public class WorkingNote {
private boolean mIsDeleted;
public boolean mTop = false;
private NoteSettingChangedListener mNoteSettingStatusListener;
public static final String[] DATA_PROJECTION = new String[] {
@ -112,6 +117,7 @@ public class WorkingNote {
mIsDeleted = false;
mMode = 0;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
mTop = false;
}
// Existing note construct
@ -122,6 +128,7 @@ public class WorkingNote {
mIsDeleted = false;
mNote = new Note();
loadNote();
mTop = false;
}
private void loadNote() {
@ -239,6 +246,15 @@ public class WorkingNote {
}
}
public boolean isTop(boolean mTop){
if (mTop) {
NotesListItem item = null;
item.setTop();
return true;
}
return false;
}
public void markDeleted(boolean mark) {
mIsDeleted = mark;
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
@ -288,6 +304,15 @@ public class WorkingNote {
}
}
public void setWorkingText(String text,String secretKey) {
if (!TextUtils.equals(mContent, text)) {
mContent = text;
mNote.setTextData(DataColumns.CONTENT, mContent,secretKey);
}else {
mNote.setTextData(DataColumns.CONTENT, text,secretKey);
}
}
public void convertToCallNote(String phoneNumber, long callDate) {
mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));
mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);

@ -39,6 +39,18 @@ public class ResourceParser {
public static final int BG_DEFAULT_FONT_SIZE = TEXT_MEDIUM;
//public static int top = 0;
//public static int deleteTop = 1;
//更改字体
public static final int TEXT_BLACK = 0;
public static final int TEXT_LIGHT = 1;
public static final int TEXT_MONOSPACE = 2;
public static final int TEXT_CURSIVE = 3;
public static final int BG_DEFAULT_FONT_STYLE =TEXT_BLACK;
public static class NoteBgResources {
private final static int [] BG_EDIT_RESOURCES = new int [] {
R.drawable.edit_yellow,
@ -154,26 +166,72 @@ public class ResourceParser {
}
}
/*
public static class TextAppearanceResources {
private final static int [] TEXTAPPEARANCE_RESOURCES = new int [] {
private final static int []TEXTAPPEARANCE_RESOURCES = new int []{
R.style.TextAppearanceNormal,
R.style.TextAppearanceMedium,
R.style.TextAppearanceLarge,
R.style.TextAppearanceSuper
R.style.TextAppearanceSuper,
R.style.TextAppearanceBlack,
R.style.TextAppearanceLight,
R.style.TextAppearanceMonospace,
R.style.TextAppearanceCursive,
};*/
public static class TextAppearanceResources {
private final static int []TEXTAPPEARANCE_RESOURCES = new int [] {
R.style.TextAppearanceNormal,
R.style.TextAppearanceMedium,
R.style.TextAppearanceLarge,
R.style.TextAppearanceSuper,
};
public static int getTexAppearanceResource(int id) {
private final static int []TEXTAPPEARANCE_RESOURCES2 = new int [] {
R.style.TextAppearanceBlack,
R.style.TextAppearanceLight,
R.style.TextAppearanceMonospace,
R.style.TextAppearanceCursive,
}
;
public static int getTexAppearanceResource(int id,int style) {
/**
* HACKME: Fix bug of store the resource id in shared preference.
* The id may larger than the length of resources, in this case,
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
*/
if (id >= TEXTAPPEARANCE_RESOURCES.length) {
return BG_DEFAULT_FONT_SIZE;
}
if (style >= TEXTAPPEARANCE_RESOURCES2.length) {
return BG_DEFAULT_FONT_STYLE;
}
return TEXTAPPEARANCE_RESOURCES[id];
}
public static int getTexAppearanceResource2(int id,int style) {
/**
* HACKME: Fix bug of store the resource id in shared preference.
* The id may larger than the length of resources, in this case,
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
*/
if (id >= TEXTAPPEARANCE_RESOURCES.length) {
return BG_DEFAULT_FONT_SIZE;
}
if (style >= TEXTAPPEARANCE_RESOURCES2.length) {
return BG_DEFAULT_FONT_STYLE;
}
return TEXTAPPEARANCE_RESOURCES2[style];
}
public static int getResourcesSize() {
return TEXTAPPEARANCE_RESOURCES.length;
}

@ -41,8 +41,7 @@ public class AlarmInitReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
long currentDate = System.currentTimeMillis();
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
PROJECTION,
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, PROJECTION,
NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
new String[] { String.valueOf(currentDate) },
null);
@ -54,8 +53,7 @@ public class AlarmInitReceiver extends BroadcastReceiver {
Intent sender = new Intent(context, AlarmReceiver.class);
sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID)));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0);
AlarmManager alermManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
AlarmManager alermManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);
} while (c.moveToNext());
}

@ -22,19 +22,36 @@ import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.InputType;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -43,10 +60,12 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -65,6 +84,8 @@ import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.io.FileNotFoundException;
import java.nio.channels.Selector;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -74,6 +95,9 @@ import java.util.regex.Pattern;
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
private String mSecretKey;
private class HeadViewHolder {
public TextView tvModified;
@ -82,6 +106,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public TextView tvAlertDate;
public ImageView ibSetBgColor;
public ImageView topIcon;
}
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
@ -118,7 +144,26 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select);
}
private static final String TAG = "NoteEditActivity";
//更改字体
private static final Map<Integer, Integer> sFontStyleBtnsMap = new HashMap<Integer, Integer>();
static {
sFontStyleBtnsMap.put(R.id.ll_font_black, ResourceParser.TEXT_BLACK);
sFontStyleBtnsMap.put(R.id.ll_font_light, ResourceParser.TEXT_LIGHT);
sFontStyleBtnsMap.put(R.id.ll_font_monospace, ResourceParser.TEXT_MONOSPACE);
sFontStyleBtnsMap.put(R.id.ll_font_cursive, ResourceParser.TEXT_CURSIVE);
}
private static final Map<Integer, Integer> sFontStyleSelectorSelectionMap = new HashMap<Integer, Integer>();
static {
sFontStyleSelectorSelectionMap.put(ResourceParser.TEXT_BLACK, R.id.iv_black_select);
sFontStyleSelectorSelectionMap.put(ResourceParser.TEXT_LIGHT, R.id.iv_light_select);
sFontStyleSelectorSelectionMap.put(ResourceParser.TEXT_MONOSPACE, R.id.iv_monospace_select);
sFontStyleSelectorSelectionMap.put(ResourceParser.TEXT_CURSIVE, R.id.iv_cursive_select);
}
private static final String TAG = "NoteEd itActivity";
private HeadViewHolder mNoteHeaderHolder;
@ -128,6 +173,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private View mFontSizeSelector;
private View mFontStyleSelector;
private EditText mNoteEditor;
private View mNoteEditorPanel;
@ -135,10 +182,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private WorkingNote mWorkingNote;
private SharedPreferences mSharedPrefs;
private SharedPreferences mSharedPrefs1;
private int mFontSizeId;
//更改字体id
private int mFontStyleId;
private static final String PREFERENCE_FONT_SIZE = "pref_font_size";
private static final String PREFERENCE_FONT_STYLE = "pref_font_style";
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10;
public static final String TAG_CHECKED = String.valueOf('\u221A');
@ -148,23 +202,140 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
private TextView mWordCountTextView;//用于存储字数统计的TextView
private final int PHOTO_REQUEST = 1;//请求码
public void highlightText(View view) {
int startSelection = mNoteEditor.getSelectionStart();
int endSelection = mNoteEditor.getSelectionEnd();
if (startSelection != -1 && endSelection != -1) {
SpannableString spannable = new SpannableString(mNoteEditor.getText());
spannable.setSpan(new BackgroundColorSpan(getResources().getColor(R.color.highlight_color)), startSelection, endSelection, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
mNoteEditor.setText(spannable);
}
}
public void removeHighlight(View view) {
int startSelection = mNoteEditor.getSelectionStart();
int endSelection = mNoteEditor.getSelectionEnd();
if (startSelection != -1 && endSelection != -1) {
SpannableString spannable = new SpannableString(mNoteEditor.getText());
BackgroundColorSpan[] spans = spannable.getSpans(startSelection, endSelection, BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
int spanStart = spannable.getSpanStart(span);
int spanEnd = spannable.getSpanEnd(span);
if (spanStart <= endSelection && spanEnd >= startSelection) {
if (spanStart < startSelection) {
spannable.setSpan(new BackgroundColorSpan(span.getBackgroundColor()), spanStart, startSelection, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
if (spanEnd > endSelection) {
spannable.setSpan(new BackgroundColorSpan(span.getBackgroundColor()), endSelection, spanEnd, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
spannable.removeSpan(span);
}
}
mNoteEditor.setText(spannable);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
ImageView ivHighlight = (ImageView) findViewById(R.id.iv_highlight);
ivHighlight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
highlightText(view);
}
});
ImageView ivRemoveHighlight = (ImageView) findViewById(R.id.iv_remove_highlight);
ivRemoveHighlight.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
removeHighlight(view);
}
});
if (savedInstanceState == null && !initActivityState(getIntent())) {
finish();
return;
}
initResources();
// 根据id获取字数统计TextView
mWordCountTextView = (TextView) findViewById(R.id.tv_word_count);
//根据id获取添加图片按钮
final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);
//为点击图片按钮设置监听器
add_img_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: click add image button");
//ACTION_GET_CONTENT: 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT);
//Category属性用于指定当前动作Action被执行的环境.
//CATEGORY_OPENABLE; 用来指示一个ACTION_GET_CONTENT的intent
loadImage.addCategory(Intent.CATEGORY_OPENABLE);
loadImage.setType("image/*");
startActivityForResult(loadImage, PHOTO_REQUEST);
}
});
// 根据id获取编辑框
//mNoteEditor = (EditText) findViewById(R.id.et_note_editor);
// 根据id获取字数统计TextView
mWordCountTextView = (TextView) findViewById(R.id.tv_word_count);
// 添加文本改变监听器
mNoteEditor.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
// 获取当前文本的字数
int wordCount = countWords(charSequence.toString().trim());
// 更新字数统计TextView
mWordCountTextView.setText(String.valueOf(wordCount));
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
// 计算字数的方法
private int countWords(String text) {
int count = 0;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) != ' ') {
count++;
}
}
return count;
}
// 判断字符是否为标点符号的方法
private boolean isPunctuation(char c) {
return Character.getType(c) == Character.OTHER_PUNCTUATION
|| Character.getType(c) == Character.END_PUNCTUATION
|| Character.getType(c) == Character.START_PUNCTUATION
|| Character.getType(c) == Character.CONNECTOR_PUNCTUATION
|| Character.getType(c) == Character.DASH_PUNCTUATION
|| Character.getType(c) == Character.INITIAL_QUOTE_PUNCTUATION
|| Character.getType(c) == Character.FINAL_QUOTE_PUNCTUATION
|| Character.getType(c) == Character.OTHER_PUNCTUATION;
}
/**
* Current activity may be killed when the memory is low. Once it is killed, for another time
* user load this activity, we should restore the former state
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
@ -263,14 +434,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
@Override
protected void onResume() {
protected void onResume() {//能获得用户焦点:可以操作
super.onResume();
initNoteScreen();
initNoteScreen();//初始化便签屏幕
}
public void setTextAppearance(Context context, int size,int style) {
throw new RuntimeException("Stub!");
}
private void initNoteScreen() {
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId,mFontStyleId));
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent());
} else {
@ -288,11 +462,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
| DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME
| DateUtils.FORMAT_SHOW_YEAR));
/**
* TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker
* is not ready
*/
showAlertHeader();
//将有图片路径的位置转换为图片
convertToImage();
}
private void showAlertHeader() {
@ -312,6 +484,47 @@ public class NoteEditActivity extends Activity implements OnClickListener,
};
}
//路径字符串格式 转换为 图片image格式
private void convertToImage() {
NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view); //获取当前的edit
Editable editable = noteEditText.getText();//1.获取text
String noteText = editable.toString(); //2.将note内容转换为字符串
int length = editable.length(); //内容的长度
//3.截取img片段 [local]+uri+[local]提取uri
for(int i = 0; i < length; i++) {
for(int j = i; j < length; j++) {
String img_fragment = noteText.substring(i, j+1); //img_fragment关于图片路径的片段
if(img_fragment.length() > 15 && img_fragment.endsWith("[/local]") && img_fragment.startsWith("[local]")){
int limit = 7; //[local]为7个字符
//[local][/local]共15个字符剩下的为真正的path长度
int len = img_fragment.length()-15;
//从[local]之后的len个字符就是path
String path = img_fragment.substring(limit,limit+len);//获取到了图片路径
Bitmap bitmap = null;
Log.d(TAG, "图片的路径是:"+path);
try {
bitmap = BitmapFactory.decodeFile(path);//将图片路径解码为图片格式
} catch (Exception e) {
e.printStackTrace();
}
if(bitmap!=null){ //若图片存在
Log.d(TAG, "图片不为null");
ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
//4.创建一个SpannableString对象以便插入用ImageSpan对象封装的图像
String ss = "[local]" + path + "[/local]";
SpannableString spannableString = new SpannableString(ss);
//5.将指定的标记对象附加到文本的开始...结束范围
spannableString.setSpan(imageSpan, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.d(TAG, "Create spannable string success!");
Editable edit_text = noteEditText.getEditableText();
edit_text.delete(i,i+len+15); //6.删掉图片路径的文字
edit_text.insert(i, spannableString); //7.在路径的起始位置插入图片
}
}
}
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@ -346,6 +559,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mFontSizeSelector.setVisibility(View.GONE);
return true;
}
//更改字体
if (mFontStyleSelector.getVisibility() == View.VISIBLE
&& !inRangeOfView(mFontStyleSelector, ev)) {
mFontStyleSelector.setVisibility(View.GONE);
return true;
}
return super.dispatchTouchEvent(ev);
}
@ -358,8 +578,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight())) {
return false;
}
return false;
}
return true;
}
@ -368,6 +588,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteHeaderHolder = new HeadViewHolder();
mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date);
mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon);
mNoteHeaderHolder.topIcon = (ImageView) findViewById(R.id.menu_top);
mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date);
mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color);
mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);
@ -384,8 +605,19 @@ public class NoteEditActivity extends Activity implements OnClickListener,
View view = findViewById(id);
view.setOnClickListener(this);
};
mFontStyleSelector = findViewById(R.id.font_style_selector);
for (int id : sFontStyleBtnsMap.keySet()) {
View view = findViewById(id);
view.setOnClickListener(this);
};
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
mSharedPrefs1 = PreferenceManager.getDefaultSharedPreferences(this);
mFontStyleId = mSharedPrefs1.getInt(PREFERENCE_FONT_STYLE, ResourceParser.BG_DEFAULT_FONT_STYLE);
/**
* HACKME: Fix bug of store the resource id in shared preference.
* The id may larger than the length of resources, in this case,
@ -394,6 +626,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
if(mFontStyleId >= TextAppearanceResources.getResourcesSize()) {
mFontStyleId = ResourceParser.BG_DEFAULT_FONT_STYLE;
}
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
}
@ -418,7 +654,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
mWorkingNote.getWidgetId()
mWorkingNote.getWidgetId()
});
sendBroadcast(intent);
@ -430,7 +666,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- View.VISIBLE);
View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@ -446,9 +682,22 @@ public class NoteEditActivity extends Activity implements OnClickListener,
switchToListMode(mWorkingNote.getContent());
} else {
mNoteEditor.setTextAppearance(this,
TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
TextAppearanceResources.getTexAppearanceResource(mFontSizeId,mFontStyleId));
}
mFontSizeSelector.setVisibility(View.GONE);
}else if (sFontStyleBtnsMap.containsKey(id)) {
findViewById(sFontStyleSelectorSelectionMap.get(mFontStyleId)).setVisibility(View.GONE);
mFontStyleId = sFontStyleBtnsMap.get(id);
mSharedPrefs1.edit().putInt(PREFERENCE_FONT_STYLE, mFontStyleId).commit();
findViewById(sFontStyleSelectorSelectionMap.get(mFontStyleId)).setVisibility(View.VISIBLE);
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
getWorkingText();
switchToListMode(mWorkingNote.getContent());
} else {
mNoteEditor.setTextAppearance(this,
TextAppearanceResources.getTexAppearanceResource2(mFontStyleId,mFontStyleId));
}
mFontStyleSelector.setVisibility(View.GONE);
}
}
@ -457,7 +706,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if(clearSettingState()) {
return;
}
saveNote();
super.onBackPressed();
}
@ -469,6 +717,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
} else if (mFontSizeSelector.getVisibility() == View.VISIBLE) {
mFontSizeSelector.setVisibility(View.GONE);
return true;
}else if (mFontStyleSelector.getVisibility() == View.VISIBLE) {
mFontStyleSelector.setVisibility(View.GONE);
return true;
}
return false;
}
@ -502,6 +753,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
} else {
menu.findItem(R.id.menu_delete_remind).setVisible(false);
}
if (mWorkingNote.mTop == true) {//置顶标志
menu.findItem(R.id.menu_top).setVisible(false);//置顶 不显示置顶 只显示删除置顶
} else {
mNoteHeaderHolder.topIcon.setVisibility(View.GONE);
menu.findItem(R.id.menu_delete_top).setVisible(false);//没置顶 显示置顶 不显示删除置顶
}
return true;
}
@ -511,6 +768,37 @@ public class NoteEditActivity extends Activity implements OnClickListener,
case R.id.menu_new_note:
createNewNote();
break;
case R.id.menu_encrypt:
AlertDialog.Builder builderS = new AlertDialog.Builder(this);
builderS.setTitle("提示");
LayoutInflater inflater = LayoutInflater.from(this);
View dialogView = inflater.inflate(R.layout.dialog_input, null);
EditText inputEditText = (EditText) dialogView.findViewById(R.id.inputEditText);
inputEditText.setHint("请输入密码");
builderS.setView(dialogView);
builderS.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mSecretKey = inputEditText.getText().toString();
}
});
builderS.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mSecretKey = "";
}
});
AlertDialog alertDialog = builderS.create();
alertDialog.show();
break;
case R.id.menu_delete:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
@ -526,10 +814,38 @@ public class NoteEditActivity extends Activity implements OnClickListener,
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.menu_top:
AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
builder2.setTitle(getString(R.string.alert_title_top));
builder2.setIcon(android.R.drawable.ic_dialog_alert);
builder2.setMessage(getString(R.string.alert_message_top_notes));
builder2.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mWorkingNote.mTop = true;
topCurrentNote();//出现置顶图标
}
});
builder2.setNegativeButton(android.R.string.cancel, null);
builder2.show();
break;
case R.id.menu_delete_top://删除置顶
mWorkingNote.mTop = false;
mNoteHeaderHolder.topIcon.setVisibility(View.GONE);//置顶图标置为空
break;
case R.id.menu_font_size:
mFontSizeSelector.setVisibility(View.VISIBLE);
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
break;
case R.id.menu_font_style:
mFontStyleSelector.setVisibility(View.VISIBLE);
findViewById(sFontStyleSelectorSelectionMap.get(mFontStyleId)).setVisibility(View.VISIBLE);
break;
case R.id.menu_list_mode:
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
TextNote.MODE_CHECK_LIST : 0);
@ -563,10 +879,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
d.show();
}
/**
* Share note to apps that support {@link Intent#ACTION_SEND} action
* and {@text/plain} type
*/
private void sendTo(Context context, String info) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, info);
@ -608,6 +920,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mWorkingNote.markDeleted(true);
}
//显示置顶图标
private void topCurrentNote() {
// 如果便签存在于数据库中
if (mWorkingNote.existInDatabase()) {
// 设置置顶图标可见
mNoteHeaderHolder.topIcon.setVisibility(View.VISIBLE);
// 设置置顶图标资源为置顶图标
mNoteHeaderHolder.topIcon.setImageResource(R.drawable.menu_top);
}else {
mNoteHeaderHolder.topIcon.setVisibility(View.GONE);
}
}
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
}
@ -728,7 +1054,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private View getListItem(String item, int index) {
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
//cedit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId,mFontStyleId));
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
@ -773,12 +1099,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
switchToListMode(mNoteEditor.getText().toString());
} else {
if (!getWorkingText()) {
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ",
""));
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", ""),mSecretKey);
}
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mEditTextList.setVisibility(View.GONE);
mNoteEditor.setVisibility(View.VISIBLE);
convertToImage(); //退出清单模式,应该将有图片的地方显示出来
}
}
@ -798,9 +1124,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
}
mWorkingNote.setWorkingText(sb.toString());
mWorkingNote.setWorkingText(sb.toString(),mSecretKey);
} else {
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
mWorkingNote.setWorkingText(mNoteEditor.getText().toString(),mSecretKey);
}
return hasChecked;
}
@ -870,4 +1196,147 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
@Override
//重写onActivityResult()来处理返回的数据
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
ContentResolver resolver = getContentResolver();
switch (requestCode) {
case PHOTO_REQUEST:
Uri originalUri = intent.getData(); //1.获得图片的真实路径
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));//2.解码图片
} catch (FileNotFoundException e) {
Log.d(TAG, "onActivityResult: get file_exception");
e.printStackTrace();
}
if(bitmap != null){
//3.根据Bitmap对象创建ImageSpan对象
Log.d(TAG, "onActivityResult: bitmap is not null");
ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
String path = getPath(this,originalUri);
//4.使用[local][/local]将path括起来用于之后方便识别图片路径在note中的位置
String img_fragment= "[local]" + path + "[/local]";
//创建一个SpannableString对象以便插入用ImageSpan对象封装的图像
SpannableString spannableString = new SpannableString(img_fragment);
spannableString.setSpan(imageSpan, 0, img_fragment.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//5.将选择的图片追加到EditText中光标所在位置
NoteEditText e = (NoteEditText) findViewById(R.id.note_edit_view);
int index = e.getSelectionStart(); //获取光标所在位置
Log.d(TAG, "Index是: " + index);
Editable edit_text = e.getEditableText();
edit_text.insert(index, spannableString); //将图片插入到光标所在位置
mWorkingNote.mContent = e.getText().toString();
//6.把改动提交到数据库中,两个数据库表都要改的
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
final long id = mWorkingNote.getNoteId();
contentValues.put("snippet",mWorkingNote.mContent);
contentResolver.update(Uri.parse("content://micode_notes/note"), contentValues,"_id=?",new String[]{""+id});
ContentValues contentValues1 = new ContentValues();
contentValues1.put("content",mWorkingNote.mContent);
contentResolver.update(Uri.parse("content://micode_notes/data"), contentValues1,"mime_type=? and note_id=?", new String[]{"vnd.android.cursor.item/text_note",""+id});
}else{
Toast.makeText(NoteEditActivity.this, "获取图片失败", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
//获取文件的real path
public String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
// if (isExternalStorageDocument(uri)) {
// final String docId = DocumentsContract.getDocumentId(uri);
// final String[] split = docId.split(":");
// final String type = split[0];
//
// if ("primary".equalsIgnoreCase(type)) {
// return Environment.getExternalStorageDirectory() + "/" + split[1];
// }
// }
// // DownloadsProvider
// else if (isDownloadsDocument(uri)) {
// final String id = DocumentsContract.getDocumentId(uri);
// final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
// return getDataColumn(context, contentUri, null, null);
// }
// MediaProvider
// else
if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// Media
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
//获取数据列_获取此 Uri 的数据列的值。这对MediaStore Uris 和其他基于文件的 ContentProvider。
public String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
//是否为外部存储文件
// public boolean isExternalStorageDocument(Uri uri) {
// return "com.android.externalstorage.documents".equals(uri.getAuthority());
// }
//
// //是否为下载文件
// public boolean isDownloadsDocument(Uri uri) {
// return "com.android.providers.downloads.documents".equals(uri.getAuthority());
// }
//是否为媒体文件
public boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
}

@ -0,0 +1,127 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.BackgroundColorSpan;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.widget.EditText;
import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
public class NoteEditText extends EditText {
private static final String TAG = "NoteEditText";
private int mIndex;
private int mSelectionStartBeforeDelete;
private static final String SCHEME_TEL = "tel:" ;
private static final String SCHEME_HTTP = "http:" ;
private static final String SCHEME_EMAIL = "mailto:" ;
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
static {
sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel);
sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web);
sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email);
}
/**
* Call by the {@link NoteEditActivity} to delete or add edit text
*/
public interface OnTextViewChangeListener {
/**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
* and the text is null
*/
void onEditTextDelete(int index, String text);
/**
* Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER}
* happen
*/
void onEditTextEnter(int index, String text);
/**
* Hide or show item option when text change
*/
void onTextChange(int index, boolean hasText);
}
private OnTextViewChangeListener mOnTextViewChangeListener;
public NoteEditText(Context context) {
super(context, null);
mIndex = 0;
}
public void setIndex(int index) {
mIndex = index;
}
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener;
}
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle);
}
public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX() + getScrollX() - getTotalPaddingLeft();
int y = (int) event.getY() + getScrollY() - getTotalPaddingTop();
Layout layout = getLayout();
if (layout != null) {
int line = layout.getLineForVertical(y);
int off = getOffsetForHorizontal(layout, line, x);
Selection.setSelection(getText(), off);
}
break;
}
return super.onTouchEvent(event);
}
private int getOffsetForHorizontal(Layout layout, int line, int x) {
return layout.getOffsetForHorizontal(line, x);
}
}

@ -40,6 +40,7 @@ public class NoteItemData {
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.PASSWORD,
};
private static final int ID_COLUMN = 0;
@ -69,6 +70,15 @@ public class NoteItemData {
private int mWidgetType;
private String mName;
private String mPhoneNumber;
private String mSecretKey;
public String getmSecretKey() {
return mSecretKey;
}
public void setmSecretKey(String mSecretKey) {
this.mSecretKey = mSecretKey;
}
private boolean mIsLastItem;
private boolean mIsFirstItem;
@ -86,11 +96,13 @@ public class NoteItemData {
mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN);
mParentId = cursor.getLong(PARENT_ID_COLUMN);
mSnippet = cursor.getString(SNIPPET_COLUMN);
mSnippet = cursor.getString(SNIPPET_COLUMN);
mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED, "").replace(
NoteEditActivity.TAG_UNCHECKED, "");
mType = cursor.getInt(TYPE_COLUMN);
mWidgetId = cursor.getInt(WIDGET_ID_COLUMN);
mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN);
mSecretKey = cursor.getString(12);
mPhoneNumber = "";
if (mParentId == Notes.ID_CALL_RECORD_FOLDER) {
@ -221,4 +233,30 @@ public class NoteItemData {
public static int getNoteType(Cursor cursor) {
return cursor.getInt(TYPE_COLUMN);
}
@Override
public String toString() {
return "NoteItemData{" +
"mId=" + mId +
", mAlertDate=" + mAlertDate +
", mBgColorId=" + mBgColorId +
", mCreatedDate=" + mCreatedDate +
", mHasAttachment=" + mHasAttachment +
", mModifiedDate=" + mModifiedDate +
", mNotesCount=" + mNotesCount +
", mParentId=" + mParentId +
", mSnippet='" + mSnippet + '\'' +
", mType=" + mType +
", mWidgetId=" + mWidgetId +
", mWidgetType=" + mWidgetType +
", mName='" + mName + '\'' +
", mPhoneNumber='" + mPhoneNumber + '\'' +
", mSecretKey='" + mSecretKey + '\'' +
", mIsLastItem=" + mIsLastItem +
", mIsFirstItem=" + mIsFirstItem +
", mIsOnlyOneItem=" + mIsOnlyOneItem +
", mIsOneNoteFollowingFolder=" + mIsOneNoteFollowingFolder +
", mIsMultiNotesFollowingFolder=" + mIsMultiNotesFollowingFolder +
'}';
}
}

@ -55,6 +55,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.TextView;
@ -89,6 +90,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private static final int MENU_FOLDER_CHANGE_NAME = 2;
private int topcount = 0;
private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction";
private enum ListEditState {
@ -107,6 +110,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private boolean mDispatch;
private boolean mtop;
public ImageView topIcon;
private int mOriginY;
private int mDispatchY;
@ -123,6 +130,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
public static final int NOTES_LISTVIEW_SCROLL_RATE = 30;
//初始化当secret_mode == 1即表示进入了隐私模式
public static int secret_mode = 0;
public static int top_mode = 0;
private NoteItemData mFocusNoteDataItem;
private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?";
@ -240,31 +252,50 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
getMenuInflater().inflate(R.menu.note_list_options, menu);
menu.findItem(R.id.delete).setOnMenuItemClickListener(this);
mMoveMenu = menu.findItem(R.id.move);
if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER
|| DataUtils.getUserFolderCount(mContentResolver) == 0) {
if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER || DataUtils.getUserFolderCount(mContentResolver) == 0) {
mMoveMenu.setVisible(false);
} else {
mMoveMenu.setVisible(true);
mMoveMenu.setOnMenuItemClickListener(this);
}
mActionMode = mode;
mNotesListAdapter.setChoiceMode(true);
mNotesListView.setLongClickable(false);
mAddNewNote.setVisibility(View.GONE);
View customView = LayoutInflater.from(NotesListActivity.this).inflate(
R.layout.note_list_dropdown_menu, null);
View customView = LayoutInflater.from(NotesListActivity.this).inflate(R.layout.note_list_dropdown_menu, null);
mode.setCustomView(customView);
mDropDownMenu = new DropdownMenu(NotesListActivity.this,
(Button) customView.findViewById(R.id.selection_menu),
R.menu.note_list_dropdown);
mDropDownMenu = new DropdownMenu(NotesListActivity.this, (Button) customView.findViewById(R.id.selection_menu), R.menu.note_list_dropdown);
mDropDownMenu.setOnDropdownMenuItemClickListener(new PopupMenu.OnMenuItemClickListener(){
public boolean onMenuItemClick(MenuItem item) {
mNotesListAdapter.selectAll(!mNotesListAdapter.isAllSelected());
updateMenu();
return true;
}
});
//添加置顶 菜单显示
MenuItem topMenuItem = menu.findItem(R.id.menu_top);
topMenuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
AlertDialog.Builder builder2 = new AlertDialog.Builder(NotesListActivity.this);
builder2.setTitle(getString(R.string.alert_title_top));
builder2.setIcon(android.R.drawable.ic_dialog_alert);
builder2.setMessage(getString(R.string.alert_message_top_notes));
builder2.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
ImageView icon = (ImageView) findViewById(R.id.menu_top);
icon.setVisibility(View.VISIBLE);
icon.setImageResource(R.drawable.menu_top);
}
});
builder2.setNegativeButton(android.R.string.cancel, null);
builder2.show();
return true;
}
});
return true;
}
@ -306,39 +337,38 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mActionMode.finish();
}
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
mNotesListAdapter.setCheckedItem(position, checked);
updateMenu();
}
public boolean onMenuItemClick(MenuItem item) {
if (mNotesListAdapter.getSelectedCount() == 0) {
Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none),
Toast.LENGTH_SHORT).show();
Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none), Toast.LENGTH_SHORT).show();
return true;
}
switch (item.getItemId()) {
case R.id.delete:
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
builder.setMessage(getString(R.string.alert_message_delete_notes, mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.move:
startQueryDestinationFolders();
break;
case R.id.menu_top:
ImageView icon = (ImageView) findViewById(R.id.menu_top);
icon.setVisibility(View.VISIBLE);
icon.setImageResource(R.drawable.menu_top);
break;
default:
return false;
}
@ -347,7 +377,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
private class NewNoteOnTouchListener implements OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
@ -411,10 +440,33 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
if(secret_mode == 0) {
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
else{
String str1 = "******";
String [] PROJECTION = new String [] { //定义一个新的PROJECTION数组只换掉SNIPPET
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE,
NoteColumns.HAS_ATTACHMENT,
NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT,
NoteColumns.PARENT_ID,
str1,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
};
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
}
private final class BackgroundQueryHandler extends AsyncQueryHandler {
@ -537,7 +589,49 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_UID, data.getId());
this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
Log.d(TAG, "openNode: "+data.toString());
if (TextUtils.isEmpty(data.getmSecretKey())){
this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
}else {
AlertDialog.Builder builderS = new AlertDialog.Builder(this);
builderS.setTitle("提示");
LayoutInflater inflater = LayoutInflater.from(this);
View dialogView = inflater.inflate(R.layout.dialog_input, null);
EditText inputEditText = (EditText) dialogView.findViewById(R.id.inputEditText);
inputEditText.setHint("请输入密码");
builderS.setView(dialogView);
builderS.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String secretKey = inputEditText.getText().toString().trim();
if (TextUtils.isEmpty(secretKey)){
Toast.makeText(NotesListActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
return;
}
if (secretKey.equals(data.getmSecretKey())){
dialog.dismiss();
startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
}else {
Toast.makeText(NotesListActivity.this, "密码输入有误,请重新输入!", Toast.LENGTH_SHORT).show();
}
}
});
builderS.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = builderS.create();
alertDialog.show();
}
}
private void openFolder(NoteItemData data) {
@ -775,6 +869,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
} else {
Log.e(TAG, "Wrong state:" + mState);
}
if(secret_mode == 1)
menu.findItem(R.id.menu_secret).setVisible(false);
else
menu.findItem(R.id.menu_quit_secret).setVisible(false);
return true;
}
@ -812,6 +912,51 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
case R.id.menu_search:
onSearchRequested();
break;
//进入隐私模式
case R.id.menu_secret: {
secret_mode = 1;
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认进入隐私模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAsyncNotesListQuery();
Toast.makeText(NotesListActivity.this,"您已进入隐私模式",Toast.LENGTH_SHORT).show();
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){}
});
dialog.show();
startAsyncNotesListQuery();
break;
}
//退出隐私模式
case R.id.menu_quit_secret:{
secret_mode = 0;
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认退出隐私模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAsyncNotesListQuery();
Toast.makeText(NotesListActivity.this,"您已退出隐私模式",Toast.LENGTH_SHORT).show();
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){}
});
dialog.show();
break;
}
default:
break;
}

@ -29,7 +29,6 @@ import net.micode.notes.data.Notes;
import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser.NoteItemBgResources;
public class NotesListItem extends LinearLayout {
private ImageView mAlert;
private TextView mTitle;
@ -37,6 +36,7 @@ public class NotesListItem extends LinearLayout {
private TextView mCallName;
private NoteItemData mItemData;
private CheckBox mCheckBox;
private ImageView topIcon;
public NotesListItem(Context context) {
super(context);
@ -46,6 +46,12 @@ public class NotesListItem extends LinearLayout {
mTime = (TextView) findViewById(R.id.tv_time);
mCallName = (TextView) findViewById(R.id.tv_name);
mCheckBox = (CheckBox) findViewById(android.R.id.checkbox);
topIcon = (ImageView) findViewById(R.id.menu_top);//
}
public void setTop(){
topIcon.setImageResource(R.drawable.menu_top);
topIcon.setVisibility(View.VISIBLE);
}
public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) {
@ -61,8 +67,7 @@ public class NotesListItem extends LinearLayout {
mCallName.setVisibility(View.GONE);
mAlert.setVisibility(View.VISIBLE);
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
mTitle.setText(context.getString(R.string.call_record_folder_name)
+ context.getString(R.string.format_folder_files_count, data.getNotesCount()));
mTitle.setText(context.getString(R.string.call_record_folder_name) + context.getString(R.string.format_folder_files_count, data.getNotesCount()));
mAlert.setImageResource(R.drawable.call_record);
} else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) {
mCallName.setVisibility(View.VISIBLE);
@ -94,6 +99,8 @@ public class NotesListItem extends LinearLayout {
}
}
}
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
setBackground(data);

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 B

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save