Kaydet (Commit) 319623a3 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl

android: Add bottom formatting toolbar

The bottom formatting toolbar now shows the formatting options
previously located in the main toolbar as a menu entry (bold,
italic, ...). In addition alignment options and selection of fonts
and sizes have been added.

Bottom formatting toolbar is not shown by default - it enables when
hitting the icon in main toolbar. Also soft keyboard and formatting
toolbar should not be shown at the same time.

Change-Id: I5f6cf8a9fcbdb4d154ae7504a65f9a226c99d694
üst 01d0983e
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_bold_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_italic_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_strikethrough_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_underlined_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_keyboard_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_menu_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_text_format_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/button_selected_background" android:state_pressed="true"/>
<item android:drawable="@color/button_selected_background" android:state_selected="true" />
<item android:drawable="@android:color/transparent" android:state_selected="false" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_check_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_align_center_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_align_justify_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_align_left_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_format_align_right_black_24dp"
android:tint="@color/toolbar_forgeround"/>
\ No newline at end of file
......@@ -12,9 +12,14 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/toolbar"/>
<include layout="@layout/toolbar_bottom"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/toolbar_bottom"
android:orientation="vertical">
<include layout="@layout/toolbar"/>
......@@ -30,7 +35,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<include layout="@layout/text_selection_handles"/>
<org.libreoffice.overlay.DocumentOverlayView
android:id="@+id/text_cursor_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
</LinearLayout>
......@@ -43,9 +51,11 @@
android:gravity="center">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"/>
</RelativeLayout>
<View
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_bottom"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:elevation="3dp"
android:background="@color/toolbar_background"
app:popupTheme="@style/LibreOfficeTheme.Toolbar"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:showIn="@layout/activity_main">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="@+id/formatting_toolbar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/button_bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_bold"/>
<ImageButton
android:id="@+id/button_italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_italic"/>
<ImageButton
android:id="@+id/button_underlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_underlined"/>
<ImageButton
android:id="@+id/button_strikethrough"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_strikethrough"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton
android:id="@+id/button_align_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_align_left"/>
<ImageButton
android:id="@+id/button_align_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_align_center"/>
<ImageButton
android:id="@+id/button_align_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_align_right"/>
<ImageButton
android:id="@+id/button_align_justify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@drawable/image_button_background"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:src="@drawable/ic_format_align_justify"/>
</LinearLayout>
<Spinner
android:id="@+id/font_name_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="50dip"/>
<Spinner
android:id="@+id/font_size_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minHeight="50dip"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.Toolbar>
......@@ -6,36 +6,19 @@
<group android:id="@+id/group_edit_actions"
tools:visible="true"
android:visible="false">
<item android:id="@+id/action_bold"
android:title="@string/action_bold"
android:icon="@drawable/action_bold"
android:orderInCategory="100"
app:showAsAction="always"/>
<item android:id="@+id/action_italic"
android:title="@string/action_italic"
android:icon="@drawable/action_italic"
android:orderInCategory="100"
app:showAsAction="always"/>
<item android:id="@+id/action_underline"
android:title="@string/action_underline"
android:icon="@drawable/action_underline"
android:orderInCategory="100"
app:showAsAction="always"/>
<item android:id="@+id/action_strikeout"
android:title="@string/action_strikeout"
android:icon="@drawable/action_strikeout"
android:orderInCategory="100"
app:showAsAction="always"/>
<item android:id="@+id/action_keyboard"
android:title="@string/action_keyboard"
android:icon="@drawable/ic_format_keyboard_grey600_24dp"
android:icon="@drawable/ic_keyboard"
android:orderInCategory="100"
app:showAsAction="always"/>
<item android:id="@+id/action_format"
android:title="@string/action_fromat"
android:icon="@drawable/ic_text_format"
android:orderInCategory="100"
app:showAsAction="always"/>
<item android:id="@+id/action_save"
android:title="@string/action_save"
android:orderInCategory="100" />
......
......@@ -95,7 +95,8 @@
<color name="toolbar_forgeround">#3e3e3e</color>
<color name="toolbar_background">#ffffff</color>
<color name="handle_color">#40A040</color>
<color name="handle_color">#26a69a</color>
<color name="button_selected_background">#33000000</color>
</resources>
......@@ -64,6 +64,7 @@
<string name="action_strikeout">Strike Out</string>
<string name="action_keyboard">Show keyboard</string>
<string name="action_save">Save</string>
<string name="action_fromat">Enable Format</string>
<!-- Feedback messages -->
<string name="message_saved">Save complete</string>
......
package org.libreoffice;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class FontController implements AdapterView.OnItemSelectedListener {
private boolean mFontNameSpinnerSet = false;
private boolean mFontSizeSpinnerSet = false;
private Activity mActivity;
private List<String> mFontList = null;
private List<String> mFontSizes = new ArrayList<String>();
private Map<String, List<String>> mAllFontSizes = null;
private String mCurrentFontSelected = null;
private String mCurrentFontSizeSelected = null;
public FontController(Activity activity) {
mActivity = activity;
}
private void sendFontChange(String fontName) {
try {
JSONObject json = new JSONObject();
JSONObject valueJson = new JSONObject();
valueJson.put("type", "string");
valueJson.put("value", fontName);
json.put("CharFontName.FamilyName", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CharFontName", json.toString()));
} catch (JSONException e) {
e.printStackTrace();
}
}
private void sendFontSizeChange(String fontSize) {
try {
JSONObject json = new JSONObject();
JSONObject valueJson = new JSONObject();
valueJson.put("type", "float");
valueJson.put("value", fontSize);
json.put("FontHeight.Height", valueJson);
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:FontHeight", json.toString()));
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (mFontList == null || !mFontNameSpinnerSet)
return;
if (parent == mActivity.findViewById(R.id.font_name_spinner)) {
String currentFontSelected = parent.getItemAtPosition(pos).toString();
if (!currentFontSelected.equals(mCurrentFontSelected)) {
mCurrentFontSelected = currentFontSelected;
sendFontChange(mCurrentFontSelected);
}
} else if (parent == mActivity.findViewById(R.id.font_size_spinner)) {
String currentFontSizeSelected = parent.getItemAtPosition(pos).toString();
if (!currentFontSizeSelected.equals(mCurrentFontSizeSelected)) {
mCurrentFontSizeSelected = currentFontSizeSelected;
sendFontSizeChange(mCurrentFontSizeSelected);
}
}
}
@Override
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
public void parseJson(String json) {
mFontList = new ArrayList<String>();
mAllFontSizes = new HashMap<String, List<String>>();
try {
JSONObject jObject = new JSONObject(json);
JSONObject jObject2 = jObject.getJSONObject("commandValues");
Iterator<String> keys = jObject2.keys();
List<String> fontSizes;
while (keys.hasNext()) {
String key = keys.next();
mFontList.add(key);
JSONArray array = jObject2.getJSONArray(key);
fontSizes = new ArrayList<String>();
for (int i = 0; i < array.length(); i++) {
fontSizes.add(array.getString(i));
}
mAllFontSizes.put(key, fontSizes);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void setupFontViews() {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
setupFontNameSpinner();
setupFontSizeSpinner();
}
});
}
private void setupFontNameSpinner() {
Spinner fontSpinner = (Spinner) mActivity.findViewById(R.id.font_name_spinner);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item, mFontList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fontSpinner.setAdapter(dataAdapter);
}
private void setupFontSizeSpinner() {
Spinner fontSizeSpinner = (Spinner) mActivity.findViewById(R.id.font_size_spinner);
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item, mFontSizes);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
fontSizeSpinner.setAdapter(dataAdapter);
}
public void selectFont(final String fontName) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
selectFontCurrentThread(fontName);
}
});
}
private void selectFontCurrentThread(String fontName) {
Spinner spinner = (Spinner) mActivity.findViewById(R.id.font_name_spinner);
if (!mFontNameSpinnerSet) {
spinner.setOnItemSelectedListener(this);
mFontNameSpinnerSet = true;
}
if (fontName.equals(mCurrentFontSelected))
return;
ArrayAdapter<String> arrayAdapter = (ArrayAdapter<String>) spinner.getAdapter();
int position = arrayAdapter.getPosition(fontName);
if (position != -1) {
mCurrentFontSelected = fontName;
spinner.setSelection(position);
}
resetFontSizes(fontName);
}
private void resetFontSizes(String fontName) {
Spinner spinner = (Spinner) mActivity.findViewById(R.id.font_size_spinner);
ArrayAdapter<String> arrayAdapter = (ArrayAdapter<String>) spinner.getAdapter();
List<String> fontSizes = mAllFontSizes.get(fontName);
if (fontSizes != null) {
arrayAdapter.clear();
arrayAdapter.addAll(mAllFontSizes.get(fontName));
}
}
public void selectFontSize(final String fontSize) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
selectFontSizeCurrentThread(fontSize);
}
});
}
private void selectFontSizeCurrentThread(String fontSize) {
Spinner spinner = (Spinner) mActivity.findViewById(R.id.font_size_spinner);
if (!mFontSizeSpinnerSet) {
spinner.setOnItemSelectedListener(this);
mFontSizeSpinnerSet = true;
}
if (fontSize.equals(mCurrentFontSizeSelected))
return;
ArrayAdapter<String> arrayAdapter = (ArrayAdapter<String>) spinner.getAdapter();
int position = arrayAdapter.getPosition(fontSize);
if (position != -1) {
mCurrentFontSizeSelected = fontSize;
spinner.setSelection(position, false);
}
}
}
package org.libreoffice;
import android.content.Context;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;
import org.libreoffice.kit.Document;
public class FormattingController implements View.OnClickListener {
private static final String LOGTAG = ToolbarController.class.getSimpleName();
private final Toolbar mToolbarBottom;
private LibreOfficeMainActivity mContext;
public FormattingController(LibreOfficeMainActivity context, Toolbar toolbarBottom) {
mToolbarBottom = toolbarBottom;
mContext = context;
((ImageButton) context.findViewById(R.id.button_bold)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_italic)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_strikethrough)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_underlined)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_align_left)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_align_center)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_align_right)).setOnClickListener(this);
((ImageButton) context.findViewById(R.id.button_align_justify)).setOnClickListener(this);
}
@Override
public void onClick(View view) {
ImageButton button = (ImageButton) view;
boolean selected = button.isSelected();;
button.setSelected(selected);
if (selected) {
button.getBackground().setState(new int[]{-android.R.attr.state_selected});
} else {
button.getBackground().setState(new int[]{android.R.attr.state_selected});
}
switch(button.getId()) {
case R.id.button_bold:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Bold"));
break;
case R.id.button_italic:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Italic"));
break;
case R.id.button_strikethrough:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Underline"));
break;
case R.id.button_underlined:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Strikeout"));
break;
case R.id.button_align_left:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:LeftPara"));
break;
case R.id.button_align_center:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:CenterPara"));
break;
case R.id.button_align_right:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:RightPara"));
break;
case R.id.button_align_justify:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:JustifyPara"));
break;
default:
break;
}
}
public void onToggleStateChanged(final int type, final boolean selected) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
Integer buttonId = null;
switch (type) {
case Document.BOLD:
buttonId = R.id.button_bold;
break;
case Document.ITALIC:
buttonId = R.id.button_italic;
break;
case Document.UNDERLINE:
buttonId = R.id.button_strikethrough;
break;
case Document.STRIKEOUT:
buttonId = R.id.button_underlined;
break;
case Document.ALIGN_LEFT:
buttonId = R.id.button_align_left;
break;
case Document.ALIGN_CENTER:
buttonId = R.id.button_align_center;
break;
case Document.ALIGN_RIGHT:
buttonId = R.id.button_align_right;
break;
case Document.ALIGN_JUSTIFY:
buttonId = R.id.button_align_justify;
break;
default:
Log.e(LOGTAG, "Uncaptured state change type: " + type);
return;
}
LibreOfficeMainActivity activity = LibreOfficeMainActivity.mAppContext;
ImageButton button = (ImageButton) activity.findViewById(buttonId);
button.setSelected(selected);
if (selected) {
button.getBackground().setState(new int[]{android.R.attr.state_selected});
} else {
button.getBackground().setState(new int[]{-android.R.attr.state_selected});
}
}
});
/*if (menuItem == null) {
Log.e(LOGTAG, "MenuItem not found.");
return;
}
final Drawable drawable;
if (pressed) {
Resources resources = mContext.getResources();
Drawable[] layers = new Drawable[2];
layers[0] = resources.getDrawable(R.drawable.icon_background);
layers[1] = resources.getDrawable(drawableId);
drawable = new LayerDrawable(layers);
} else {
drawable = mContext.getResources().getDrawable(drawableId);
}
final MenuItem fMenuItem = menuItem;
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
fMenuItem.setIcon(drawable);
}
});*/
}
}
......@@ -88,15 +88,29 @@ public class InvalidationHandler implements Document.MessageCallback {
Log.e(LOGTAG, "LOK_CALLBACK_STATE_CHANGED unexpected payload: " + payload);
return;
}
boolean pressed = Boolean.parseBoolean(parts[1]);
final String value = parts[1];
boolean pressed = Boolean.parseBoolean(value);
if (parts[0].equals(".uno:Bold")) {
LOKitShell.getToolbarController().onToggleStateChanged(Document.BOLD, pressed);
LOKitShell.getFormattingController().onToggleStateChanged(Document.BOLD, pressed);
} else if (parts[0].equals(".uno:Italic")) {
LOKitShell.getToolbarController().onToggleStateChanged(Document.ITALIC, pressed);
LOKitShell.getFormattingController().onToggleStateChanged(Document.ITALIC, pressed);
} else if (parts[0].equals(".uno:Underline")) {
LOKitShell.getToolbarController().onToggleStateChanged(Document.UNDERLINE, pressed);
LOKitShell.getFormattingController().onToggleStateChanged(Document.UNDERLINE, pressed);
} else if (parts[0].equals(".uno:Strikeout")) {
LOKitShell.getToolbarController().onToggleStateChanged(Document.STRIKEOUT, pressed);
LOKitShell.getFormattingController().onToggleStateChanged(Document.STRIKEOUT, pressed);
} else if (parts[0].equals(".uno:CharFontName")) {
LOKitShell.getFontController().selectFont(value);
} else if (parts[0].equals(".uno:FontHeight")) {
LOKitShell.getFontController().selectFontSize(value);
} else if (parts[0].equals(".uno:LeftPara")) {
LOKitShell.getFormattingController().onToggleStateChanged(Document.ALIGN_LEFT, pressed);
} else if (parts[0].equals(".uno:CenterPara")) {
LOKitShell.getFormattingController().onToggleStateChanged(Document.ALIGN_CENTER, pressed);
} else if (parts[0].equals(".uno:RightPara")) {
LOKitShell.getFormattingController().onToggleStateChanged(Document.ALIGN_RIGHT, pressed);
} else if (parts[0].equals(".uno:JustifyPara")) {
LOKitShell.getFormattingController().onToggleStateChanged(Document.ALIGN_JUSTIFY, pressed);
} else {
Log.d(LOGTAG, "LOK_CALLBACK_STATE_CHANGED type uncatched: " + payload);
}
......@@ -383,7 +397,7 @@ public class InvalidationHandler implements Document.MessageCallback {
* Handle a transition to OverlayState.CURSOR state.
*/
private void handleCursorState(OverlayState previous) {
LibreOfficeMainActivity.mAppContext.showSoftKeyboard();
LibreOfficeMainActivity.mAppContext.showSoftKeyboardOrFormattingToolbar();
if (previous == OverlayState.TRANSITION) {
mDocumentOverlay.showHandle(SelectionHandle.HandleType.MIDDLE);
mDocumentOverlay.showCursor();
......
......@@ -59,6 +59,14 @@ public class LOKitShell {
return LibreOfficeMainActivity.mAppContext.getToolbarController();
}
public static FormattingController getFormattingController() {
return LibreOfficeMainActivity.mAppContext.getFormattingController();
}
public static FontController getFontController() {
return LibreOfficeMainActivity.mAppContext.getFontController();
}
public static int getMemoryClass(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
return activityManager.getMemoryClass() * 1024 * 1024;
......
......@@ -124,6 +124,8 @@ public class LOKitTileProvider implements TileProvider {
mDocument.setPart(0);
setupDocumentFonts();
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
......@@ -132,6 +134,15 @@ public class LOKitTileProvider implements TileProvider {
});
}
private void setupDocumentFonts() {
String values = mDocument.getCommandValues(".uno:CharFontName");
if (values == null || values.isEmpty())
return;
LOKitShell.getFontController().parseJson(values);
LOKitShell.getFontController().setupFontViews();
}
private String getGenericPartName(int i) {
if (mDocument == null) {
return "";
......
......@@ -17,8 +17,6 @@ import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
......@@ -61,20 +59,24 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
private static boolean mEnableEditing;
int providerId;
URI documentUri;
private int providerId;
private URI documentUri;
public Handler mMainHandler;
private DrawerLayout mDrawerLayout;
private LOAbout mAbout;
private ListView mDrawerList;
private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
private File mInputFile;
private DocumentOverlay mDocumentOverlay;
private File mTempFile = null;
private LOAbout mAbout;
private FormattingController mFormattingController;
private ToolbarController mToolbarController;
private FontController mFontController;
public LibreOfficeMainActivity() {
mAbout = new LOAbout(this, false);
......@@ -88,63 +90,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
return mEnableEditing;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
mToolbarController.setOptionMenu(menu);
if (mTempFile != null) {
mToolbarController.disableMenuItem(R.id.action_save, true);
Toast.makeText(this, getString(R.string.temp_file_saving_disabled), Toast.LENGTH_LONG).show();
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_bold:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Bold"));
return true;
case R.id.action_italic:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Italic"));
return true;
case R.id.action_underline:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Underline"));
return true;
case R.id.action_strikeout:
LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:Strikeout"));
return true;
case R.id.action_keyboard:
showSoftKeyboard();
break;
case R.id.action_about:
mAbout.showAbout();
return true;
case R.id.action_save:
saveDocument();
return true;
case R.id.action_parts:
mDrawerLayout.openDrawer(mDrawerList);
return true;
case R.id.action_settings:
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean isDrawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
// Do the same in case the drawer is locked.
boolean isDrawerLocked = mDrawerLayout.getDrawerLockMode(mDrawerList) != DrawerLayout.LOCK_MODE_UNLOCKED;
menu.findItem(R.id.action_parts).setVisible(!isDrawerOpen && !isDrawerLocked);
menu.setGroupVisible(R.id.group_edit_actions, mEnableEditing);
return super.onPrepareOptionsMenu(menu);
public boolean usesTemporaryFile() {
return mTempFile != null;
}
@Override
......@@ -153,7 +100,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
mAppContext = this;
super.onCreate(savedInstanceState);
SharedPreferences sPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mEnableEditing = sPrefs.getBoolean(ENABLE_EXPERIMENTAL_PREFS_KEY, false);
......@@ -166,9 +112,21 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mToolbarController = new ToolbarController(this, getSupportActionBar(), toolbar);
Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar);
Toolbar toolbarBottom = (Toolbar) findViewById(R.id.toolbar_bottom);
hideBottomToolbar();
mToolbarController = new ToolbarController(this, getSupportActionBar(), toolbarTop);
mFormattingController = new FormattingController(this, toolbarBottom);
toolbarTop.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LOKitShell.sendNavigationClickEvent();
}
});
mFontController = new FontController(this);
if (getIntent().getData() != null) {
if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
......@@ -193,13 +151,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
mInputFile = new File(DEFAULT_DOC_PATH);
}
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LOKitShell.sendNavigationClickEvent();
}
});
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
if (mDocumentPartViewListAdapter == null) {
......@@ -226,6 +177,8 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
// create TextCursorLayer
mDocumentOverlay = new DocumentOverlay(mAppContext, layerView);
mToolbarController.setupToolbars();
}
private boolean copyFileToTemp() {
......@@ -272,7 +225,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
* Save the document and invoke save on document provider to upload the file
* to the cloud if necessary.
*/
private void saveDocument() {
public void saveDocument() {
final long lastModified = mInputFile.lastModified();
final Activity activity = LibreOfficeMainActivity.this;
Toast.makeText(this, R.string.message_saving, Toast.LENGTH_SHORT).show();
......@@ -328,9 +281,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
else {
// 20 seconds later, the local file has not changed,
// maybe there were no changes at all
Toast.makeText(activity,
R.string.message_save_incomplete,
Toast.LENGTH_LONG).show();
Toast.makeText(activity, R.string.message_save_incomplete, Toast.LENGTH_LONG).show();
}
}
}
......@@ -346,7 +297,6 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
boolean bEnableExperimental = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(ENABLE_EXPERIMENTAL_PREFS_KEY, false);
if (bEnableExperimental != mEnableEditing) {
mEnableEditing = bEnableExperimental;
invalidateOptionsMenu();
}
}
......@@ -415,11 +365,29 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
LayerView layerView = (LayerView) findViewById(R.id.layer_view);
showSoftKeyboardDirect();
}
});
}
if (layerView.requestFocus()) {
InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(layerView, InputMethodManager.SHOW_FORCED);
private void showSoftKeyboardDirect() {
LayerView layerView = (LayerView) findViewById(R.id.layer_view);
if (layerView.requestFocus()) {
InputMethodManager inputMethodManager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(layerView, InputMethodManager.SHOW_FORCED);
}
hideBottomToolbar();
}
public void showSoftKeyboardOrFormattingToolbar() {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
Toolbar toolbarBottom = (Toolbar) findViewById(R.id.toolbar_bottom);
if (toolbarBottom.getVisibility() != View.VISIBLE) {
showSoftKeyboardDirect();
}
}
});
......@@ -447,6 +415,46 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
}
}
public void showBottomToolbar() {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
findViewById(R.id.toolbar_bottom).setVisibility(View.VISIBLE);
}
});
}
public void hideBottomToolbar() {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
findViewById(R.id.toolbar_bottom).setVisibility(View.GONE);
findViewById(R.id.formatting_toolbar).setVisibility(View.GONE);
}
});
}
public void showFormattingToolbar() {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
showBottomToolbar();
findViewById(R.id.formatting_toolbar).setVisibility(View.VISIBLE);
hideSoftKeyboardDirect();
}
});
}
public void hideFormattingToolbar() {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
hideBottomToolbar();
findViewById(R.id.formatting_toolbar).setVisibility(View.GONE);
}
});
}
public void showProgressSpinner() {
findViewById(R.id.loadingPanel).setVisibility(View.VISIBLE);
}
......@@ -455,12 +463,12 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
findViewById(R.id.loadingPanel).setVisibility(View.GONE);
}
public void showAlertDialog(String s) {
public void showAlertDialog(String message) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(LibreOfficeMainActivity.this);
alertDialogBuilder.setTitle("Error");
alertDialogBuilder.setMessage(s);
alertDialogBuilder.setMessage(message);
alertDialogBuilder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
......@@ -479,6 +487,32 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
return mToolbarController;
}
public FontController getFontController() {
return mFontController;
}
public FormattingController getFormattingController() {
return mFormattingController;
}
public void openDrawer() {
mDrawerLayout.openDrawer(mDrawerList);
}
public void showAbout() {
mAbout.showAbout();
}
public void showSettings() {
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
}
public boolean isDrawerEnabled() {
boolean isDrawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
boolean isDrawerLocked = mDrawerLayout.getDrawerLockMode(mDrawerList) != DrawerLayout.LOCK_MODE_UNLOCKED;
return !isDrawerOpen && !isDrawerLocked;
}
private class DocumentPartClickListener implements android.widget.AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
......
......@@ -9,39 +9,54 @@
package org.libreoffice;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import org.libreoffice.canvas.ImageUtils;
import org.libreoffice.kit.Document;
import java.sql.SQLOutput;
import java.util.Arrays;
/**
* Controls the changes to the toolbar.
*/
public class ToolbarController {
public class ToolbarController implements Toolbar.OnMenuItemClickListener {
private static final String LOGTAG = ToolbarController.class.getSimpleName();
private final Toolbar mToolbar;
private final Toolbar mToolbarTop;
private final ActionBar mActionBar;
private Menu mOptionsMenu;
private Context mContext;
private LibreOfficeMainActivity mContext;
private Menu mMainMenu;
public ToolbarController(Context context, ActionBar actionBar, Toolbar toolbar) {
mToolbar = toolbar;
public ToolbarController(LibreOfficeMainActivity context, ActionBar actionBar, Toolbar toolbarTop) {
mToolbarTop = toolbarTop;
mActionBar = actionBar;
mContext = context;
mToolbarTop.inflateMenu(R.menu.main);
mToolbarTop.setOnMenuItemClickListener(this);
switchToViewMode();
mMainMenu = mToolbarTop.getMenu();
}
public void disableMenuItem(final int menuItemId, final boolean disabled) {
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
MenuItem menuItem = mOptionsMenu.findItem(menuItemId);
MenuItem menuItem = mMainMenu.findItem(menuItemId);
if (menuItem != null) {
menuItem.setEnabled(!disabled);
} else {
......@@ -51,53 +66,6 @@ public class ToolbarController {
});
}
public void onToggleStateChanged(int type, boolean pressed) {
MenuItem menuItem = null;
Bitmap icon = null;
switch (type) {
case Document.BOLD:
menuItem = mOptionsMenu.findItem(R.id.action_bold);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.action_bold);
break;
case Document.ITALIC:
menuItem = mOptionsMenu.findItem(R.id.action_italic);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.action_italic);
break;
case Document.UNDERLINE:
menuItem = mOptionsMenu.findItem(R.id.action_underline);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.action_underline);
break;
case Document.STRIKEOUT:
menuItem = mOptionsMenu.findItem(R.id.action_strikeout);
icon = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.action_strikeout);
break;
default:
Log.e(LOGTAG, "Uncaptured state change type: " + type);
return;
}
if (menuItem == null) {
Log.e(LOGTAG, "MenuItem not found.");
return;
}
if (pressed) {
icon = ImageUtils.bitmapToPressed(icon);
}
final MenuItem fMenuItem = menuItem;
final Bitmap fIcon = icon;
LOKitShell.getMainHandler().post(new Runnable() {
public void run() {
fMenuItem.setIcon(new BitmapDrawable(mContext.getResources(), fIcon));
}
});
}
public void setOptionMenu(Menu menu) {
mOptionsMenu = menu;
}
/**
* Change the toolbar to edit mode.
*/
......@@ -109,9 +77,10 @@ public class ToolbarController {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
mActionBar.setDisplayHomeAsUpEnabled(false);
mToolbar.setNavigationIcon(R.drawable.ic_check_grey600_24dp);
mToolbar.setTitle(null);
mMainMenu.setGroupVisible(R.id.group_edit_actions, true);
mToolbarTop.setNavigationIcon(R.drawable.ic_check);
mToolbarTop.setTitle(null);
mToolbarTop.setLogo(null);
}
});
......@@ -128,12 +97,48 @@ public class ToolbarController {
LOKitShell.getMainHandler().post(new Runnable() {
@Override
public void run() {
mToolbar.setNavigationIcon(R.drawable.ic_menu_grey600_24dp);
mToolbar.setTitle("LibreOffice");
mActionBar.setDisplayHomeAsUpEnabled(true);
mMainMenu.setGroupVisible(R.id.group_edit_actions, false);
mToolbarTop.setNavigationIcon(R.drawable.lo_icon);
mToolbarTop.setTitle(null);
mToolbarTop.setLogo(null);
}
});
}
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_keyboard:
mContext.showSoftKeyboard();
break;
case R.id.action_format:
mContext.showFormattingToolbar();
break;
case R.id.action_about:
mContext.showAbout();
return true;
case R.id.action_save:
mContext.saveDocument();
return true;
case R.id.action_parts:
mContext.openDrawer();
return true;
case R.id.action_settings:
mContext.showSettings();
return true;
}
return false;
}
public void setupToolbars() {
LibreOfficeMainActivity activity = mContext;
if (activity.usesTemporaryFile()) {
disableMenuItem(R.id.action_save, true);
Toast.makeText(activity, activity.getString(R.string.temp_file_saving_disabled), Toast.LENGTH_LONG).show();
}
mMainMenu.findItem(R.id.action_parts).setVisible(activity.isDrawerEnabled());
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -5,6 +5,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
/**
* Bitmap handle canvas element is used to show a handle on the screen.
......@@ -26,8 +27,9 @@ public abstract class BitmapHandle extends CommonCanvasElement {
* Return a bitmap for a drawable id.
*/
protected static Bitmap getBitmapForDrawable(Context context, int drawableId) {
BitmapFactory.Options options = new BitmapFactory.Options();
return BitmapFactory.decodeResource(context.getResources(), drawableId, options);
Drawable drawable = context.getResources().getDrawable(drawableId);
return ImageUtils.getBitmapForDrawable(drawable);
}
/**
......
package org.libreoffice.canvas;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
public class ImageUtils {
/**
* Convert transparent pixels to gray ones.
*/
public static Bitmap bitmapToPressed(Bitmap input) {
Bitmap op = Bitmap.createBitmap(input.getWidth(), input.getHeight(), input.getConfig());
for(int i=0; i<op.getWidth(); i++){
for(int j=0; j<op.getHeight(); j++){
int p = input.getPixel(i, j);
// assign gray color if the pixel in input is transparent.
int newColor = Color.alpha(p) == 0 ? Color.argb(255, 200, 200, 200) : p;
op.setPixel(i, j, newColor);
}
}
return op;
public static Bitmap getBitmapForDrawable(Drawable drawable) {
drawable = drawable.mutate();
int width = !drawable.getBounds().isEmpty() ?
drawable.getBounds().width() : drawable.getIntrinsicWidth();
width = width <= 0 ? 1 : width;
int height = !drawable.getBounds().isEmpty() ?
drawable.getBounds().height() : drawable.getIntrinsicHeight();
height = height <= 0 ? 1 : height;
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment