OSDN Git Service

Editor: Handle content uri's in the editor
[android-x86/packages-apps-CMFileManager.git] / src / com / cyanogenmod / filemanager / activities / EditorActivity.java
index 26b048e..dfd90b9 100644 (file)
@@ -36,7 +36,6 @@ import android.preference.PreferenceActivity;
 import android.text.Editable;
 import android.text.InputType;
 import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -69,12 +68,18 @@ import com.cyanogenmod.filemanager.ash.SyntaxHighlightFactory;
 import com.cyanogenmod.filemanager.ash.SyntaxHighlightProcessor;
 import com.cyanogenmod.filemanager.commands.AsyncResultListener;
 import com.cyanogenmod.filemanager.commands.WriteExecutable;
+import com.cyanogenmod.filemanager.commands.shell.InvalidCommandDefinitionException;
+import com.cyanogenmod.filemanager.console.Console;
+import com.cyanogenmod.filemanager.console.ConsoleAllocException;
 import com.cyanogenmod.filemanager.console.ConsoleBuilder;
+import com.cyanogenmod.filemanager.console.InsufficientPermissionsException;
+import com.cyanogenmod.filemanager.console.java.JavaConsole;
 import com.cyanogenmod.filemanager.model.FileSystemObject;
 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
 import com.cyanogenmod.filemanager.preferences.Preferences;
 import com.cyanogenmod.filemanager.ui.ThemeManager;
 import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
+import com.cyanogenmod.filemanager.ui.policy.PrintActionPolicy;
 import com.cyanogenmod.filemanager.ui.widgets.ButtonItem;
 import com.cyanogenmod.filemanager.util.AndroidHelper;
 import com.cyanogenmod.filemanager.util.CommandHelper;
@@ -84,11 +89,15 @@ import com.cyanogenmod.filemanager.util.ExceptionUtil.OnRelaunchCommandResult;
 import com.cyanogenmod.filemanager.util.FileHelper;
 import com.cyanogenmod.filemanager.util.MediaHelper;
 import com.cyanogenmod.filemanager.util.ResourcesHelper;
+import com.cyanogenmod.filemanager.util.StringHelper;
+import org.mozilla.universalchardet.UniversalDetector;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.StringReader;
 import java.util.ArrayList;
@@ -182,8 +191,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                                 });
                             }
 
-                        } else if (key.compareTo(FileManagerSettings.SETTINGS_EDITOR_SH_USE_THEME_DEFAULT.getId()) == 0 ||
-                                   key.compareTo(FileManagerSettings.SETTINGS_EDITOR_SH_COLOR_SCHEME.getId()) == 0 ) {
+                        } else if (key.compareTo(FileManagerSettings.SETTINGS_EDITOR_SH_COLOR_SCHEME.getId()) == 0 ) {
                             // Ignore in binary files
                             if (activity.mBinary) return;
 
@@ -202,8 +210,8 @@ public class EditorActivity extends Activity implements TextWatcher {
         }
     };
 
-    private static class HexDumpAdapter extends ArrayAdapter<String> {
-        private static class ViewHolder {
+    private class HexDumpAdapter extends ArrayAdapter<String> {
+        private class ViewHolder {
             TextView mTextView;
         }
 
@@ -224,7 +232,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                 viewHolder.mTextView = (TextView)v.findViewById(android.R.id.text1);
 
                 viewHolder.mTextView.setTextAppearance(context, R.style.hexeditor_text_appearance);
-                viewHolder.mTextView.setTypeface(Typeface.MONOSPACE);
+                viewHolder.mTextView.setTypeface(mHexTypeface);
                 theme.setTextColor(context, viewHolder.mTextView, "text_color"); //$NON-NLS-1$
 
                 v.setTag(viewHolder);
@@ -236,6 +244,21 @@ public class EditorActivity extends Activity implements TextWatcher {
 
             return v;
         }
+
+        /**
+         * Return the view as a document
+         *
+         * @return StringBuilder a buffer to the document
+         */
+        public StringBuilder toStringDocument() {
+            StringBuilder sb = new StringBuilder();
+            int c = getCount();
+            for (int i = 0; i < c; i++) {
+                sb.append(getItem(i));
+                sb.append("\n");
+            }
+            return sb;
+        }
     }
 
     /**
@@ -258,12 +281,19 @@ public class EditorActivity extends Activity implements TextWatcher {
         long mSize;
         FileSystemObject mReadFso;
         OnProgressListener mListener;
+        boolean mDetectEncoding = false;
+        UniversalDetector mDetector;
+        String mDetectedEncoding;
 
         /**
          * Constructor of <code>AsyncReader</code>. For enclosing access.
          */
-        public AsyncReader() {
+        public AsyncReader(boolean detectEncoding) {
             super();
+            mDetectEncoding = detectEncoding;
+            if (mDetectEncoding) {
+                mDetector = new UniversalDetector(null);
+            }
         }
 
         /**
@@ -279,7 +309,15 @@ public class EditorActivity extends Activity implements TextWatcher {
          * {@inheritDoc}
          */
         @Override
-        public void onAsyncEnd(boolean cancelled) {/**NON BLOCK**/}
+        public void onAsyncEnd(boolean cancelled) {
+            if (!cancelled && StringHelper.isBinaryData(mByteBuffer.toByteArray())) {
+                EditorActivity.this.mBinary = true;
+                EditorActivity.this.mReadOnly = true;
+            } else if (mDetector != null) {
+                mDetector.dataEnd();
+                mDetectedEncoding = mDetector.getDetectedCharset();
+            }
+        }
 
         /**
          * {@inheritDoc}
@@ -298,20 +336,10 @@ public class EditorActivity extends Activity implements TextWatcher {
         public void onPartialResult(Object result) {
             try {
                 if (result == null) return;
-                byte[] partial = (byte[])result;
-
-                // Check if the file is a binary file. In this case the editor
-                // is read-only
-                if (!EditorActivity.this.mReadOnly) {
-                    for (int i = 0; i < partial.length-1; i++) {
-                        if (!isPrintableCharacter((char)partial[i])) {
-                            EditorActivity.this.mBinary = true;
-                            EditorActivity.this.mReadOnly = true;
-                            break;
-                        }
-                    }
+                byte[] partial = (byte[]) result;
+                if (mDetectEncoding) {
+                    mDetector.handleData(partial, 0, partial.length);
                 }
-
                 this.mByteBuffer.write(partial, 0, partial.length);
                 this.mSize += partial.length;
                 if (this.mListener != null && this.mReadFso != null) {
@@ -406,11 +434,6 @@ public class EditorActivity extends Activity implements TextWatcher {
         public int getColor(String id, String resid, int def) {
             final Context ctx = EditorActivity.this;
             try {
-                // Is default theme color scheme enabled?
-                if (isDefaultThemeColorScheme()) {
-                    return ThemeManager.getCurrentTheme(ctx).getColor(ctx, resid);
-                }
-
                 // Use the user-defined settings
                 int[] colors = getUserColorScheme();
                 HighlightColors[] schemeColors = HighlightColors.values();
@@ -436,20 +459,6 @@ public class EditorActivity extends Activity implements TextWatcher {
         }
 
         /**
-         * Method that returns if we should return the default theme color scheme or not
-         *
-         * @return boolean Whether return the default theme color scheme or not
-         */
-        private boolean isDefaultThemeColorScheme() {
-            Boolean defaultValue =
-                    (Boolean)FileManagerSettings.
-                                SETTINGS_EDITOR_SH_USE_THEME_DEFAULT.getDefaultValue();
-            return Preferences.getSharedPreferences().getBoolean(
-                        FileManagerSettings.SETTINGS_EDITOR_SH_USE_THEME_DEFAULT.getId(),
-                        defaultValue.booleanValue());
-        }
-
-        /**
          * Method that returns the user-defined color scheme
          *
          * @return int[] The user-defined color scheme
@@ -514,6 +523,10 @@ public class EditorActivity extends Activity implements TextWatcher {
      * @hide
      */
     ButtonItem mSave;
+    /**
+     * @hide
+     */
+    ButtonItem mPrint;
 
     // No suggestions status
     /**
@@ -543,6 +556,8 @@ public class EditorActivity extends Activity implements TextWatcher {
 
     private View mOptionsAnchorView;
 
+    private Typeface mHexTypeface;
+
     private final Object mExecSync = new Object();
 
     /**
@@ -550,13 +565,13 @@ public class EditorActivity extends Activity implements TextWatcher {
      */
     Handler mHandler;
 
-    private static final char[] VALID_NON_PRINTABLE_CHARS = {' ', '\t', '\r', '\n'};
-
     /**
      * @hide
      */
     String mHexLineSeparator;
 
+    private boolean mHexDump;
+
     /**
      * Intent extra parameter for the path of the file to open.
      */
@@ -573,6 +588,15 @@ public class EditorActivity extends Activity implements TextWatcher {
 
         this.mHandler = new Handler();
 
+        // Load typeface for hex editor
+        mHexTypeface = Typeface.createFromAsset(getAssets(), "fonts/Courier-Prime.ttf");
+
+        // Save hexdump user preference
+        mHexDump = Preferences.getSharedPreferences().getBoolean(
+                FileManagerSettings.SETTINGS_EDITOR_HEXDUMP.getId(),
+                ((Boolean)FileManagerSettings.SETTINGS_EDITOR_HEXDUMP.
+                        getDefaultValue()).booleanValue());
+
         // Register the broadcast receiver
         IntentFilter filter = new IntentFilter();
         filter.addAction(FileManagerSettings.INTENT_THEME_CHANGED);
@@ -646,21 +670,27 @@ public class EditorActivity extends Activity implements TextWatcher {
     private void initTitleActionBar() {
         //Configure the action bar options
         getActionBar().setBackgroundDrawable(
-                getResources().getDrawable(R.drawable.bg_holo_titlebar));
+                getResources().getDrawable(R.drawable.bg_material_titlebar));
         getActionBar().setDisplayOptions(
-                ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
+                ActionBar.DISPLAY_SHOW_CUSTOM);
         getActionBar().setDisplayHomeAsUpEnabled(true);
         View customTitle = getLayoutInflater().inflate(R.layout.simple_customtitle, null, false);
         this.mTitle = (TextView)customTitle.findViewById(R.id.customtitle_title);
         this.mTitle.setText(R.string.editor);
         this.mTitle.setContentDescription(getString(R.string.editor));
-        this.mSave = (ButtonItem)customTitle.findViewById(R.id.ab_button1);
-        this.mSave.setImageResource(R.drawable.ic_holo_light_save);
+
+        this.mSave = (ButtonItem)customTitle.findViewById(R.id.ab_button0);
+        this.mSave.setImageResource(R.drawable.ic_material_light_save);
         this.mSave.setContentDescription(getString(R.string.actionbar_button_save_cd));
         this.mSave.setVisibility(View.GONE);
 
+        this.mPrint = (ButtonItem)customTitle.findViewById(R.id.ab_button1);
+        this.mPrint.setImageResource(R.drawable.ic_material_light_print);
+        this.mPrint.setContentDescription(getString(R.string.actionbar_button_print_cd));
+        this.mPrint.setVisibility(View.VISIBLE);
+
         ButtonItem configuration = (ButtonItem)customTitle.findViewById(R.id.ab_button2);
-        configuration.setImageResource(R.drawable.ic_holo_light_overflow);
+        configuration.setImageResource(R.drawable.ic_material_light_overflow);
         configuration.setContentDescription(getString(R.string.actionbar_button_overflow_cd));
 
         View status = findViewById(R.id.editor_status);
@@ -844,7 +874,7 @@ public class EditorActivity extends Activity implements TextWatcher {
      */
     private void showOverflowPopUp(View anchor) {
         SimpleMenuListAdapter adapter =
-                new HighlightedSimpleMenuListAdapter(this, R.menu.editor);
+                new HighlightedSimpleMenuListAdapter(this, R.menu.editor, true);
         MenuItem noSuggestions = adapter.getMenu().findItem(R.id.mnu_no_suggestions);
         if (noSuggestions != null) {
             if (this.mBinary) {
@@ -910,11 +940,19 @@ public class EditorActivity extends Activity implements TextWatcher {
      */
     public void onActionBarItemClick(View view) {
         switch (view.getId()) {
-            case R.id.ab_button1:
+            case R.id.ab_button0:
                 // Save the file
                 checkAndWrite();
                 break;
 
+            case R.id.ab_button1:
+                // Print the file
+                StringBuilder sb = mBinary
+                        ? ((HexDumpAdapter)mBinaryEditor.getAdapter()).toStringDocument()
+                        : new StringBuilder(mEditor.getText().toString());
+                PrintActionPolicy.printStringDocument(this, mFso, sb);
+                break;
+
             case R.id.ab_button2:
                 // Show overflow menu
                 showOverflowPopUp(this.mOptionsAnchorView);
@@ -963,77 +1001,229 @@ public class EditorActivity extends Activity implements TextWatcher {
         this.mReadOnly = false;
 
         // Read the intent and check that is has a valid request
-        String path = uriToPath(this, getIntent().getData());
-        if (path == null || path.length() == 0) {
-            DialogHelper.showToast(
-                    this, R.string.editor_invalid_file_msg, Toast.LENGTH_SHORT);
-            return;
-        }
+        Intent fileIntent = getIntent();
+        if (fileIntent.getData().getScheme().equals("content")) {
+            asyncReadContentURI(fileIntent.getData());
+        } else {
+            // File Scheme URI's
+            String path = uriToPath(this, getIntent().getData());
+            if (path == null || path.length() == 0) {
+                DialogHelper.showToast(
+                        this, R.string.editor_invalid_file_msg, Toast.LENGTH_SHORT);
+                return;
+            }
 
-        // Set the title of the dialog
-        File f = new File(path);
-        this.mTitle.setText(f.getName());
+            // Set the title of the dialog
+            File f = new File(path);
+            this.mTitle.setText(f.getName());
 
-        // Check that the file exists (the real file, not the symlink)
-        try {
-            this.mFso = CommandHelper.getFileInfo(this, path, true, null);
-            if (this.mFso == null) {
+            // Check that the file exists (the real file, not the symlink)
+            try {
+                this.mFso = CommandHelper.getFileInfo(this, path, true, null);
+                if (this.mFso == null) {
+                }
+            } catch (Exception e) {
+                Log.e(TAG, "Failed to get file reference", e); //$NON-NLS-1$
+            }
+
+            // Check that we can handle the length of the file (by device)
+            if (this.mMaxFileSize < this.mFso.getSize()) {
                 DialogHelper.showToast(
-                        this, R.string.editor_file_not_found_msg, Toast.LENGTH_SHORT);
+                        this, R.string.editor_file_exceed_size_msg, Toast.LENGTH_SHORT);
                 return;
             }
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to get file reference", e); //$NON-NLS-1$
-            DialogHelper.showToast(
-                    this, R.string.editor_file_not_found_msg, Toast.LENGTH_SHORT);
-            return;
-        }
 
-        // Check that we can handle the length of the file (by device)
-        if (this.mMaxFileSize < this.mFso.getSize()) {
-            DialogHelper.showToast(
-                    this, R.string.editor_file_exceed_size_msg, Toast.LENGTH_SHORT);
-            return;
-        }
+            // Get the syntax highlight processor
+            SyntaxHighlightFactory shpFactory =
+                    SyntaxHighlightFactory.getDefaultFactory(new ResourcesResolver());
+            this.mSyntaxHighlightProcessor = shpFactory.getSyntaxHighlightProcessor(f);
+            if (this.mSyntaxHighlightProcessor != null) {
+                this.mSyntaxHighlightProcessor.initialize();
+            }
 
-        // Get the syntax highlight processor
-        SyntaxHighlightFactory shpFactory =
-                SyntaxHighlightFactory.getDefaultFactory(new ResourcesResolver());
-        this.mSyntaxHighlightProcessor = shpFactory.getSyntaxHighlightProcessor(f);
-        if (this.mSyntaxHighlightProcessor != null) {
-            this.mSyntaxHighlightProcessor.initialize();
+            // Check that we have read access
+            try {
+                FileHelper.ensureReadAccess(
+                        ConsoleBuilder.getConsole(this),
+                        this.mFso,
+                        null);
+
+                // Read the file in background
+                asyncRead();
+
+            } catch (Exception ex) {
+                ExceptionUtil.translateException(
+                        this, ex, false, true, new OnRelaunchCommandResult() {
+                            @Override
+                            public void onSuccess() {
+                                // Read the file in background
+                                asyncRead();
+                            }
+
+                            @Override
+                            public void onFailed(Throwable cause) {
+                                    finish();
+                                }
+
+                            @Override
+                            public void onCancelled() {
+                                    finish();
+                                }
+                        });
+            }
         }
+    }
 
-        // Check that we have read access
-        try {
-            FileHelper.ensureReadAccess(
-                    ConsoleBuilder.getConsole(this),
-                    this.mFso,
-                    null);
+    /**
+     * Method that does the read of a content uri in the background
+     * @hide
+     */
+    void asyncReadContentURI(Uri uri) {
+        // Do the load of the file
+        AsyncTask<Uri, Integer, Boolean> mReadTask =
+                new AsyncTask<Uri, Integer, Boolean>() {
+
+                    private Exception mCause;
+                    private boolean changeToBinaryMode;
+                    private boolean changeToDisplaying;
+                    private String tempText;
+
+                    @Override
+                    protected void onPreExecute() {
+                        // Show the progress
+                        this.changeToBinaryMode = false;
+                        this.changeToDisplaying = false;
+                        doProgress(true, 0);
+                    }
 
-            // Read the file in background
-            asyncRead();
+                    @Override
+                    protected Boolean doInBackground(Uri... params) {
 
-        } catch (Exception ex) {
-            ExceptionUtil.translateException(
-                    this, ex, false, true, new OnRelaunchCommandResult() {
-                @Override
-                public void onSuccess() {
-                    // Read the file in background
-                    asyncRead();
-                }
+                        // Only one argument (the file to open)
+                        Uri fso = params[0];
+                        this.mCause = null;
 
-                @Override
-                public void onFailed(Throwable cause) {
-                    finish();
-                }
+                        // Read the file in an async listener
+                        try {
 
-                @Override
-                public void onCancelled() {
-                    finish();
-                }
-            });
-        }
+                            publishProgress(Integer.valueOf(0));
+
+                            InputStream is = getContentResolver().openInputStream(fso);
+
+                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                            int readBytes;
+                            byte[] buffer = new byte[1024];
+                            try {
+                                while ((readBytes = is.read(buffer, 0, buffer.length)) != -1) {
+                                    baos.write(buffer, 0, readBytes);
+                                    publishProgress(
+                                            Integer.valueOf((readBytes * 100) / buffer.length));
+                                }
+                            } catch (IOException e) {
+                                e.printStackTrace();
+                                return Boolean.FALSE;
+                            }
+
+                            // 100%
+                            publishProgress(new Integer(100));
+                            tempText = new String(baos.toByteArray(), "UTF-8");
+                            Log.i(TAG, "Bytes read: " + baos.toByteArray().length); //$NON-NLS-1$
+
+                            // 100%
+                            this.changeToDisplaying = true;
+                            publishProgress(new Integer(0));
+
+                        } catch (Exception e) {
+                            this.mCause = e;
+                            return Boolean.FALSE;
+                        }
+
+                        return Boolean.TRUE;
+
+                    }
+
+                    @Override
+                    protected void onProgressUpdate(Integer... values) {
+                        // Do progress
+                        doProgress(true, values[0].intValue());
+                    }
+
+                    @Override
+                    protected void onPostExecute(Boolean result) {
+                        final EditorActivity activity = EditorActivity.this;
+                        // Is error?
+                        if (!result.booleanValue()) {
+                            if (this.mCause != null) {
+                                ExceptionUtil.translateException(activity, this.mCause);
+                                activity.mEditor.setEnabled(false);
+                            }
+                        } else {
+                            // Now we have the buffer, set the text of the editor
+                            activity.mEditor.setText(
+                                    tempText, BufferType.EDITABLE);
+
+                            // Highlight editor text syntax
+                            if (activity.mSyntaxHighlight &&
+                                    activity.mSyntaxHighlightProcessor != null) {
+                                try {
+                                    activity.mSyntaxHighlightProcessor.process(
+                                            activity.mEditor.getText());
+                                } catch (Exception ex) {
+                                    // An error in a syntax library, should not break down app.
+                                    Log.e(TAG, "Syntax highlight failed.", ex); //$NON-NLS-1$
+                                }
+                            }
+
+                            setDirty(false);
+                            activity.mEditor.setEnabled(!activity.mReadOnly);
+
+                            // Notify read-only mode
+                            if (activity.mReadOnly) {
+                                DialogHelper.showToast(
+                                        activity,
+                                        R.string.editor_read_only_mode,
+                                        Toast.LENGTH_SHORT);
+                            }
+                        }
+
+                        doProgress(false, 0);
+                    }
+
+                    @Override
+                    protected void onCancelled() {
+                        // Hide the progress
+                        doProgress(false, 0);
+                    }
+
+                    /**
+                     * Method that update the progress status
+                     *
+                     * @param visible If the progress bar need to be hidden
+                     * @param progress The progress
+                     */
+                    private void doProgress(boolean visible, int progress) {
+                        final EditorActivity activity = EditorActivity.this;
+
+                        // Show the progress bar
+                        activity.mProgressBar.setProgress(progress);
+                        activity.mProgress.setVisibility(visible ? View.VISIBLE : View.GONE);
+
+                        if (this.changeToBinaryMode) {
+                            mWordWrapView.setVisibility(View.GONE);
+                            mNoWordWrapView.setVisibility(View.GONE);
+                            mBinaryEditor.setVisibility(View.VISIBLE);
+
+                            // Show hex dumping text
+                            activity.mProgressBarMsg.setText(R.string.dumping_message);
+                            this.changeToBinaryMode = false;
+                        }
+                        else if (this.changeToDisplaying) {
+                            activity.mProgressBarMsg.setText(R.string.displaying_message);
+                            this.changeToDisplaying = false;
+                        }
+                    }
+                };
+        mReadTask.execute(uri);
     }
 
     /**
@@ -1070,7 +1260,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                 try {
                     while (true) {
                         // Configure the reader
-                        this.mReader = new AsyncReader();
+                        this.mReader = new AsyncReader(true);
                         this.mReader.mReadFso = fso;
                         this.mReader.mListener = new OnProgressListener() {
                             @Override
@@ -1081,7 +1271,8 @@ public class EditorActivity extends Activity implements TextWatcher {
                         };
 
                         // Execute the command (read the file)
-                        CommandHelper.read(activity, fso.getFullPath(), this.mReader, null);
+                        CommandHelper.read(activity, fso.getFullPath(), this.mReader,
+                                           null);
 
                         // Wait for
                         synchronized (this.mReader.mSync) {
@@ -1102,12 +1293,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                     // Now we have the byte array with all the data. is a binary file?
                     // Then dump them byte array to hex dump string (only if users settings
                     // to dump file)
-                    boolean hexDump =
-                            Preferences.getSharedPreferences().getBoolean(
-                                FileManagerSettings.SETTINGS_EDITOR_HEXDUMP.getId(),
-                                ((Boolean)FileManagerSettings.SETTINGS_EDITOR_HEXDUMP.
-                                        getDefaultValue()).booleanValue());
-                    if (activity.mBinary && hexDump) {
+                    if (activity.mBinary && mHexDump) {
                         // we do not use the Hexdump helper class, because we need to show the
                         // progress of the dump process
                         final String data = toHexPrintableString(toHexDump(
@@ -1120,7 +1306,13 @@ public class EditorActivity extends Activity implements TextWatcher {
                         }
                         Log.i(TAG, "Bytes read: " + data.length()); //$NON-NLS-1$
                     } else {
-                        final String data = new String(this.mReader.mByteBuffer.toByteArray());
+                        String data;
+                        if (this.mReader.mDetectedEncoding != null) {
+                            data = new String(this.mReader.mByteBuffer.toByteArray(),
+                                              this.mReader.mDetectedEncoding);
+                        } else {
+                            data = new String(this.mReader.mByteBuffer.toByteArray());
+                        }
                         this.mReader.mBuffer = new SpannableStringBuilder(data);
                         Log.i(TAG, "Bytes read: " + data.getBytes().length); //$NON-NLS-1$
                     }
@@ -1155,7 +1347,7 @@ public class EditorActivity extends Activity implements TextWatcher {
                     }
                 } else {
                     // Now we have the buffer, set the text of the editor
-                    if (activity.mBinary) {
+                    if (activity.mBinary && mHexDump) {
                         HexDumpAdapter adapter = new HexDumpAdapter(EditorActivity.this,
                                 this.mReader.mBinaryBuffer);
                         mBinaryEditor.setAdapter(adapter);
@@ -1508,23 +1700,6 @@ public class EditorActivity extends Activity implements TextWatcher {
     }
 
     /**
-     * Method that check if a character is valid printable character
-     *
-     * @param c The character to check
-     * @return boolean If the character is printable
-     * @hide
-     */
-    static boolean isPrintableCharacter(char c) {
-        int cc = VALID_NON_PRINTABLE_CHARS.length;
-        for (int i = 0; i < cc; i++) {
-            if (c == VALID_NON_PRINTABLE_CHARS[i]) {
-                return true;
-            }
-        }
-        return TextUtils.isGraphic(c);
-    }
-
-    /**
      * Method that applies the current theme to the activity
      * @hide
      */
@@ -1535,9 +1710,11 @@ public class EditorActivity extends Activity implements TextWatcher {
         //- ActionBar
         theme.setTitlebarDrawable(this, getActionBar(), "titlebar_drawable"); //$NON-NLS-1$
         View v = getActionBar().getCustomView().findViewById(R.id.customtitle_title);
-        theme.setTextColor(this, (TextView)v, "text_color"); //$NON-NLS-1$
-        v = findViewById(R.id.ab_button1);
+        theme.setTextColor(this, (TextView)v, "action_bar_text_color"); //$NON-NLS-1$
+        v = findViewById(R.id.ab_button0);
         theme.setImageDrawable(this, (ImageView)v, "ab_save_drawable"); //$NON-NLS-1$
+        v = findViewById(R.id.ab_button1);
+        theme.setImageDrawable(this, (ImageView)v, "ab_print_drawable"); //$NON-NLS-1$
         v = findViewById(R.id.ab_button2);
         theme.setImageDrawable(this, (ImageView)v, "ab_overflow_drawable"); //$NON-NLS-1$
         //- View