OSDN Git Service

cmfm: improve hexdump display
authorJorge Ruesga <jorge@ruesga.com>
Sun, 7 Sep 2014 12:55:39 +0000 (14:55 +0200)
committerJorge Ruesga <jorge@ruesga.com>
Sun, 7 Sep 2014 12:55:39 +0000 (14:55 +0200)
Change-Id: I29d1f75e9cba3b0a9710ca8b0e3c803bb4828ef9
Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
res/layout/editor.xml
res/layout/hexdump_line.xml [new file with mode: 0644]
src/com/cyanogenmod/filemanager/activities/EditorActivity.java

index 9b013d8..557a5cf 100644 (file)
     </ScrollView>
   </HorizontalScrollView>
 
+  <!-- editor in a listview (binary) -->
+  <ListView
+      android:id="@+id/editor_binary"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:padding="@dimen/default_margin"
+      android:scrollbars="vertical"
+      android:scrollbarStyle="outsideOverlay"
+      android:fillViewport="true"
+      android:dividerHeight="0dp"
+      android:divider="@null"
+      android:listSelector="@android:color/transparent"
+      android:visibility="gone" />
+
   <RelativeLayout
     android:id="@+id/editor_progress"
     android:layout_width="match_parent"
diff --git a/res/layout/hexdump_line.xml b/res/layout/hexdump_line.xml
new file mode 100644 (file)
index 0000000..2e104ec
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The CyanogenMod Project
+
+     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.
+ -->
+
+<EditText xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center_vertical"
+    android:textAppearance="@style/secondary_text_appearance"
+    android:singleLine="true"
+    android:maxLines="1" />
\ No newline at end of file
index 9e96265..26b048e 100644 (file)
@@ -40,14 +40,17 @@ import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.ListPopupWindow;
+import android.widget.ListView;
 import android.widget.ProgressBar;
 import android.widget.TextView;
 import android.widget.TextView.BufferType;
@@ -82,11 +85,15 @@ import com.cyanogenmod.filemanager.util.FileHelper;
 import com.cyanogenmod.filemanager.util.MediaHelper;
 import com.cyanogenmod.filemanager.util.ResourcesHelper;
 
+import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.OutputStream;
+import java.io.StringReader;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.UUID;
 
 /**
@@ -195,6 +202,42 @@ public class EditorActivity extends Activity implements TextWatcher {
         }
     };
 
+    private static class HexDumpAdapter extends ArrayAdapter<String> {
+        private static class ViewHolder {
+            TextView mTextView;
+        }
+
+        public HexDumpAdapter(Context context, List<String> data) {
+            super(context, R.layout.hexdump_line, data);
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View v = convertView;
+            if (v == null) {
+                final Context context = getContext();
+                LayoutInflater inflater = LayoutInflater.from(context);
+                Theme theme = ThemeManager.getCurrentTheme(context);
+
+                v = inflater.inflate(R.layout.hexdump_line, parent, false);
+                ViewHolder viewHolder = new EditorActivity.HexDumpAdapter.ViewHolder();
+                viewHolder.mTextView = (TextView)v.findViewById(android.R.id.text1);
+
+                viewHolder.mTextView.setTextAppearance(context, R.style.hexeditor_text_appearance);
+                viewHolder.mTextView.setTypeface(Typeface.MONOSPACE);
+                theme.setTextColor(context, viewHolder.mTextView, "text_color"); //$NON-NLS-1$
+
+                v.setTag(viewHolder);
+            }
+
+            String text = getItem(position);
+            ViewHolder viewHolder = (ViewHolder)v.getTag();
+            viewHolder.mTextView.setText(text);
+
+            return v;
+        }
+    }
+
     /**
      * Internal interface to notify progress update
      */
@@ -209,6 +252,7 @@ public class EditorActivity extends Activity implements TextWatcher {
 
         final Object mSync = new Object();
         ByteArrayOutputStream mByteBuffer = null;
+        ArrayList<String> mBinaryBuffer = null;
         SpannableStringBuilder mBuffer = null;
         Exception mCause;
         long mSize;
@@ -453,6 +497,10 @@ public class EditorActivity extends Activity implements TextWatcher {
     /**
      * @hide
      */
+    ListView mBinaryEditor;
+    /**
+     * @hide
+     */
     View mProgress;
     /**
      * @hide
@@ -532,7 +580,7 @@ public class EditorActivity extends Activity implements TextWatcher {
         registerReceiver(this.mNotificationReceiver, filter);
 
         // Generate a random separator
-        this.mHexLineSeparator = UUID.randomUUID().toString();
+        this.mHexLineSeparator = UUID.randomUUID().toString() + UUID.randomUUID().toString();
 
         // Set the theme before setContentView
         Theme theme = ThemeManager.getCurrentTheme(this);
@@ -636,6 +684,8 @@ public class EditorActivity extends Activity implements TextWatcher {
         this.mWordWrapView.setVisibility(View.VISIBLE);
         this.mNoWordWrapView.setVisibility(View.GONE);
 
+        this.mBinaryEditor = (ListView)findViewById(R.id.editor_binary);
+
         this.mNoSuggestions = false;
         this.mWordWrap = true;
         this.mSyntaxHighlight = true;
@@ -1060,11 +1110,15 @@ public class EditorActivity extends Activity implements TextWatcher {
                     if (activity.mBinary && hexDump) {
                         // we do not use the Hexdump helper class, because we need to show the
                         // progress of the dump process
-                        final String data = toHexPrintableString(
-                                                toHexDump(
-                                                        this.mReader.mByteBuffer.toByteArray()));
-                        this.mReader.mBuffer = new SpannableStringBuilder(data);
-                        Log.i(TAG, "Bytes read: " + data.getBytes().length); //$NON-NLS-1$
+                        final String data = toHexPrintableString(toHexDump(
+                                this.mReader.mByteBuffer.toByteArray()));
+                        this.mReader.mBinaryBuffer = new ArrayList<String>();
+                        BufferedReader reader = new BufferedReader(new StringReader(data));
+                        String line;
+                        while ((line = reader.readLine()) != null) {
+                            this.mReader.mBinaryBuffer.add(line);
+                        }
+                        Log.i(TAG, "Bytes read: " + data.length()); //$NON-NLS-1$
                     } else {
                         final String data = new String(this.mReader.mByteBuffer.toByteArray());
                         this.mReader.mBuffer = new SpannableStringBuilder(data);
@@ -1093,7 +1147,6 @@ public class EditorActivity extends Activity implements TextWatcher {
             @Override
             protected void onPostExecute(Boolean result) {
                 final EditorActivity activity = EditorActivity.this;
-
                 // Is error?
                 if (!result.booleanValue()) {
                     if (this.mCause != null) {
@@ -1103,8 +1156,12 @@ public class EditorActivity extends Activity implements TextWatcher {
                 } else {
                     // Now we have the buffer, set the text of the editor
                     if (activity.mBinary) {
-                        activity.mEditor.setText(
-                                this.mReader.mBuffer, BufferType.NORMAL);
+                        HexDumpAdapter adapter = new HexDumpAdapter(EditorActivity.this,
+                                this.mReader.mBinaryBuffer);
+                        mBinaryEditor.setAdapter(adapter);
+
+                        // Cleanup
+                        this.mReader.mBinaryBuffer = null;
                     } else {
                         activity.mEditor.setText(
                                 this.mReader.mBuffer, BufferType.EDITABLE);
@@ -1120,8 +1177,11 @@ public class EditorActivity extends Activity implements TextWatcher {
                                 Log.e(TAG, "Syntax highlight failed.", ex); //$NON-NLS-1$
                             }
                         }
+
+                        //Cleanup
+                        this.mReader.mBuffer = null;
                     }
-                    this.mReader.mBuffer = null; //Cleanup
+
                     setDirty(false);
                     activity.mEditor.setEnabled(!activity.mReadOnly);
 
@@ -1157,18 +1217,12 @@ public class EditorActivity extends Activity implements TextWatcher {
                 activity.mProgress.setVisibility(visible ? View.VISIBLE : View.GONE);
 
                 if (this.changeToBinaryMode) {
-                    // Hexdump always in nowrap mode
-                    if (activity.mWordWrap) {
-                        activity.toggleWordWrap();
-                    }
-                    // Hexdump always has no syntax highlight
-                    if (activity.mSyntaxHighlight) {
-                        activity.toggleSyntaxHighlight();
-                    }
+                    mWordWrapView.setVisibility(View.GONE);
+                    mNoWordWrapView.setVisibility(View.GONE);
+                    mBinaryEditor.setVisibility(View.VISIBLE);
 
                     // Show hex dumping text
                     activity.mProgressBarMsg.setText(R.string.dumping_message);
-                    applyHexViewerTheme();
                     this.changeToBinaryMode = false;
                 }
                 else if (this.changeToDisplaying) {
@@ -1203,7 +1257,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                     //offset   dump(16)   data\n
                     String linedata = new String(line, 0, read);
                     sb.append(HexDump.toHexString(offset));
-                    sb.append("   "); //$NON-NLS-1$
+                    sb.append(" "); //$NON-NLS-1$
                     String hexDump = HexDump.toHexString(line, 0, read);
                     if (hexDump.length() != (DISPLAY_SIZE * 2)) {
                         char[] array = new char[(DISPLAY_SIZE * 2) - hexDump.length()];
@@ -1211,7 +1265,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                         hexDump += new String(array);
                     }
                     sb.append(hexDump);
-                    sb.append("   "); //$NON-NLS-1$
+                    sb.append(" "); //$NON-NLS-1$
                     sb.append(linedata);
                     sb.append(EditorActivity.this.mHexLineSeparator);
                     offset += DISPLAY_SIZE;
@@ -1504,18 +1558,6 @@ public class EditorActivity extends Activity implements TextWatcher {
     }
 
     /**
-     * Method that applies the current theme to the hex viewer editor
-     * @hide
-     */
-    void applyHexViewerTheme() {
-        Theme theme = ThemeManager.getCurrentTheme(this);
-        TextView editor = (TextView)findViewById(R.id.editor);
-        editor.setTextAppearance(this, R.style.hexeditor_text_appearance);
-        editor.setTypeface(Typeface.MONOSPACE);
-        theme.setTextColor(this, editor, "text_color"); //$NON-NLS-1$
-    }
-
-    /**
      * Method that resolves the content uri to a valid system path
      *
      * @param ctx The current context