summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/Bootstrap/src/org/libreoffice/kit/Document.java2
-rw-r--r--android/source/build.gradle2
-rw-r--r--android/source/res/anim/fab_close.xml18
-rw-r--r--android/source/res/anim/fab_open.xml19
-rw-r--r--android/source/res/drawable/ic_add_black_24dp.xml9
-rw-r--r--android/source/res/layout/activity_document_browser.xml213
-rw-r--r--android/source/res/values/strings.xml9
-rw-r--r--android/source/src/java/org/libreoffice/LOEvent.java17
-rw-r--r--android/source/src/java/org/libreoffice/LOKitShell.java12
-rw-r--r--android/source/src/java/org/libreoffice/LOKitThread.java58
-rw-r--r--android/source/src/java/org/libreoffice/LOKitTileProvider.java24
-rwxr-xr-xandroid/source/src/java/org/libreoffice/LibreOfficeMainActivity.java132
-rw-r--r--android/source/src/java/org/libreoffice/TileProvider.java6
-rw-r--r--android/source/src/java/org/libreoffice/ToolbarController.java6
-rw-r--r--android/source/src/java/org/libreoffice/ui/FileUtilities.java2
-rw-r--r--android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java123
-rw-r--r--desktop/source/lib/lokandroid.cxx2
17 files changed, 586 insertions, 68 deletions
diff --git a/android/Bootstrap/src/org/libreoffice/kit/Document.java b/android/Bootstrap/src/org/libreoffice/kit/Document.java
index a7d3f04938bb..7cf99413644c 100644
--- a/android/Bootstrap/src/org/libreoffice/kit/Document.java
+++ b/android/Bootstrap/src/org/libreoffice/kit/Document.java
@@ -147,7 +147,7 @@ public class Document {
public native void setClientZoom(int nTilePixelWidth, int nTilePixelHeight, int nTileTwipWidth, int nTileTwipHeight);
- private native void saveAs(String url, String format, String options);
+ public native void saveAs(String url, String format, String options);
private native void paintTileNative(ByteBuffer buffer, int canvasWidth, int canvasHeight, int tilePositionX, int tilePositionY, int tileWidth, int tileHeight);
diff --git a/android/source/build.gradle b/android/source/build.gradle
index d5fc5c932be0..302d34a54754 100644
--- a/android/source/build.gradle
+++ b/android/source/build.gradle
@@ -26,6 +26,7 @@ dependencies {
compile files("${liboWorkdir}/UnpackedTarball/owncloud_android_lib/bin/owncloud-android-library.jar")
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
android {
@@ -64,6 +65,7 @@ android {
// ToDo: fix openssl stuff to not block targeting 23 or later
targetSdkVersion 22
manifestPlaceholders = [installLocation: "preferExternal"]
+ vectorDrawables.useSupportLibrary = true
}
buildTypes {
debug {
diff --git a/android/source/res/anim/fab_close.xml b/android/source/res/anim/fab_close.xml
new file mode 100644
index 000000000000..ba13b0f038be
--- /dev/null
+++ b/android/source/res/anim/fab_close.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fillAfter="true">
+ <scale
+ android:duration="300"
+ android:fromXScale="0.8"
+ android:fromYScale="0.8"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:toXScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:toYScale="0.0" />
+
+ <alpha android:fromAlpha="1.0"
+ android:toAlpha="0.0"
+ android:interpolator="@android:anim/accelerate_interpolator"
+ android:duration="300"/>
+</set>
diff --git a/android/source/res/anim/fab_open.xml b/android/source/res/anim/fab_open.xml
new file mode 100644
index 000000000000..9099d8b53c80
--- /dev/null
+++ b/android/source/res/anim/fab_open.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:fillAfter="true">
+ <scale
+ android:duration="300"
+ android:fromXScale="0.0"
+ android:fromYScale="0.0"
+ android:interpolator="@android:anim/linear_interpolator"
+ android:toXScale="0.8"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:toYScale="0.8"/>
+
+ <alpha
+ android:fromAlpha="0.0"
+ android:toAlpha="1.0"
+ android:interpolator="@android:anim/accelerate_interpolator"
+ android:duration="300"/>
+</set>
diff --git a/android/source/res/drawable/ic_add_black_24dp.xml b/android/source/res/drawable/ic_add_black_24dp.xml
new file mode 100644
index 000000000000..0258249cc482
--- /dev/null
+++ b/android/source/res/drawable/ic_add_black_24dp.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
+</vector>
diff --git a/android/source/res/layout/activity_document_browser.xml b/android/source/res/layout/activity_document_browser.xml
index 20ca14125003..fab1b095035e 100644
--- a/android/source/res/layout/activity_document_browser.xml
+++ b/android/source/res/layout/activity_document_browser.xml
@@ -6,32 +6,45 @@
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.constraint.ConstraintLayout 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="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical" >
+ android:orientation="vertical">
<!-- The toolbar -->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
android:elevation="3dp"
android:background="@color/toolbar_background"
app:theme="@style/LibreOfficeTheme.Toolbar"
tools:theme="@style/LibreOfficeTheme.Toolbar"
- app:popupTheme="@style/LibreOfficeTheme">
+ app:popupTheme="@style/LibreOfficeTheme"
+ tools:layout_constraintTop_creator="1"
+ tools:layout_constraintRight_creator="1"
+ app:layout_constraintRight_toRightOf="parent"
+ tools:layout_constraintLeft_creator="1"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ tools:layout_constraintTop_creator="1"
+ tools:layout_constraintRight_creator="1"
+ tools:layout_constraintBottom_creator="1"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/toolbar"
+ tools:layout_constraintLeft_creator="1"
+ app:layout_constraintLeft_toLeftOf="parent">
<!-- The content -->
<ScrollView
@@ -53,7 +66,7 @@
android:gravity="center_vertical"
android:textSize="14sp"
android:padding="16dp"
- android:textStyle="bold"/>
+ android:textStyle="bold" />
<!--Recent files-->
<android.support.v7.widget.RecyclerView
@@ -61,7 +74,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"/>
+ android:layout_marginBottom="8dp" />
<TextView
android:layout_width="match_parent"
@@ -82,19 +95,177 @@
android:background="@color/background_normal"
android:orientation="vertical" />
- </LinearLayout>
+ </LinearLayout>
- </ScrollView>
+ </ScrollView>
- <!-- The navigation drawer -->
- <android.support.design.widget.NavigationView
- android:id="@+id/navigation_drawer"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="start"
- android:background="@color/background_normal"
- app:menu="@menu/navigation_menu"
- android:theme="@style/LibreOfficeTheme.NavigationView" />
+ <!-- The navigation drawer -->
+ <android.support.design.widget.NavigationView
+ android:id="@+id/navigation_drawer"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="start"
+ android:background="@color/background_normal"
+ app:menu="@menu/navigation_menu"
+ android:theme="@style/LibreOfficeTheme.NavigationView" />
</android.support.v4.widget.DrawerLayout>
-</LinearLayout>
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/editFAB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginRight="16dp"
+ android:clickable="true"
+ app:fabSize="normal"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ app:backgroundTint="@color/background_normal"
+ app:srcCompat="@drawable/ic_add_black_24dp" />
+
+ <LinearLayout
+ android:id="@+id/writerLayout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toTopOf="@+id/editFAB"
+ app:layout_constraintRight_toRightOf="parent">
+
+ <TextView
+ android:id="@+id/newWriterTextView"
+ android:layout_width="120dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginRight="8dp"
+ android:elevation="2dp"
+ android:gravity="center_horizontal"
+ android:text="@string/new_write"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:background="@color/background_normal"
+ android:typeface="normal" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/newWriterFAB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ app:fabSize="normal"
+ app:backgroundTint="@color/background_normal"
+ app:srcCompat="@drawable/writer" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/impressLayout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toTopOf="@+id/writerLayout"
+ app:layout_constraintLeft_toLeftOf="@+id/writerLayout"
+ app:layout_constraintRight_toRightOf="parent">
+
+ <TextView
+ android:id="@+id/newImpressTextView"
+ android:layout_width="120dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginRight="8dp"
+ android:elevation="2dp"
+ android:gravity="center_horizontal"
+ android:text="@string/new_impress"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:background="@color/background_normal"
+ android:typeface="normal" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/newImpressFAB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ app:fabSize="normal"
+ app:backgroundTint="@color/background_normal"
+ app:srcCompat="@drawable/impress" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/calcLayout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toTopOf="@+id/impressLayout"
+ app:layout_constraintLeft_toLeftOf="@+id/impressLayout"
+ app:layout_constraintRight_toRightOf="parent">
+
+ <TextView
+ android:id="@+id/newCalcTextView"
+ android:layout_width="120dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginRight="8dp"
+ android:elevation="2dp"
+ android:gravity="center_horizontal"
+ android:text="@string/new_spreadsheet"
+ android:background="@color/background_normal"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:typeface="normal" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/newCalcFAB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ app:fabSize="normal"
+ app:backgroundTint="@color/background_normal"
+ app:srcCompat="@drawable/calc" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/drawLayout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toTopOf="@+id/calcLayout"
+ app:layout_constraintLeft_toLeftOf="@+id/calcLayout"
+ app:layout_constraintRight_toRightOf="parent">
+
+ <TextView
+ android:id="@+id/newDrawTextView"
+ android:layout_width="120dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginRight="8dp"
+ android:elevation="2dp"
+ android:gravity="center_horizontal"
+ android:text="@string/new_draw"
+ android:background="@color/background_normal"
+ android:textSize="18sp"
+ android:textStyle="bold"
+ android:typeface="normal" />
+
+ <android.support.design.widget.FloatingActionButton
+ android:id="@+id/newDrawFAB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="true"
+ app:fabSize="normal"
+ app:backgroundTint="@color/background_normal"
+ app:srcCompat="@drawable/draw" />
+
+ </LinearLayout>
+
+</android.support.constraint.ConstraintLayout>
diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index 9832d8b72eb2..ce3754ee3d15 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -16,6 +16,10 @@
<string name="about_moreinfo">More Info</string>
<string name="back_again_to_quit">Press back again to quit</string>
+ <string name="new_impress">New Impress</string>
+ <string name="new_spreadsheet">New Sheet</string>
+ <string name="new_draw">New Draw</string>
+
<string name="browser_app_name">LibreOffice Browser</string>
<string name="menu_search">Search</string>
<string name="list_view">List</string>
@@ -89,6 +93,7 @@
<string name="message_saved">Save complete</string>
<string name="message_saving">Saving the document…</string>
<string name="message_save_incomplete">Save incomplete. Were there any changes?</string>
+ <string name="new_file_created">File created in Documents folder</string>
<!-- Document provider settings -->
<string name="storage_provider_settings">Storage provider settings</string>
@@ -117,6 +122,10 @@
<string name="save_document">SAVE</string>
<string name="cancel_save_document">CANCEL</string>
<string name="no_save_document">NO</string>
+ <string name="new_write">New Write</string>
+
+ <string name="save_as_success">Saved file -</string>
+ <string name="save_as_error">Unable to create new file, please check entered file name.</string>
</resources>
diff --git a/android/source/src/java/org/libreoffice/LOEvent.java b/android/source/src/java/org/libreoffice/LOEvent.java
index 23109e8d7f6a..3e058c8c035e 100644
--- a/android/source/src/java/org/libreoffice/LOEvent.java
+++ b/android/source/src/java/org/libreoffice/LOEvent.java
@@ -34,6 +34,8 @@ public class LOEvent implements Comparable<LOEvent> {
public static final int NAVIGATION_CLICK = 13;
public static final int UNO_COMMAND = 14;
public static final int RESUME = 15;
+ public static final int LOAD_NEW = 16;
+ public static final int SAVE_AS = 17;
public final int mType;
public int mPriority = 0;
@@ -42,6 +44,8 @@ public class LOEvent implements Comparable<LOEvent> {
public ThumbnailCreator.ThumbnailCreationTask mTask;
public int mPartIndex;
public String mString;
+ public String filePath;
+ public String fileType;
public ComposedTileLayer mComposedTileLayer;
public String mTouchType;
public PointF mDocumentCoordinate;
@@ -81,6 +85,19 @@ public class LOEvent implements Comparable<LOEvent> {
mPartIndex = value;
}
+ public LOEvent(String filePath, int type) {
+ mType = type;
+ mTypeString = "Load";
+ this.filePath = filePath;
+ }
+
+ public LOEvent(String filePath, String fileType, int type) {
+ mType = type;
+ mTypeString = "Load New/Save As";
+ this.filePath = filePath;
+ this.fileType = fileType;
+ }
+
public LOEvent(int type, int partIndex) {
mType = type;
mPartIndex = partIndex;
diff --git a/android/source/src/java/org/libreoffice/LOKitShell.java b/android/source/src/java/org/libreoffice/LOKitShell.java
index 35a8fd009dc2..7b7525722250 100644
--- a/android/source/src/java/org/libreoffice/LOKitShell.java
+++ b/android/source/src/java/org/libreoffice/LOKitShell.java
@@ -106,8 +106,16 @@ public class LOKitShell {
LOKitShell.sendEvent(new LOEvent(LOEvent.CHANGE_PART, part));
}
- public static void sendLoadEvent(String inputFile) {
- LOKitShell.sendEvent(new LOEvent(LOEvent.LOAD, inputFile));
+ public static void sendLoadEvent(String inputFilePath) {
+ LOKitShell.sendEvent(new LOEvent(inputFilePath, LOEvent.LOAD));
+ }
+
+ public static void sendNewDocumentLoadEvent(String newDocumentPath, String newDocumentType) {
+ LOKitShell.sendEvent(new LOEvent(newDocumentPath, newDocumentType, LOEvent.LOAD_NEW));
+ }
+
+ public static void sendSaveAsEvent(String filePath, String fileFormat) {
+ LOKitShell.sendEvent(new LOEvent(filePath, fileFormat, LOEvent.SAVE_AS));
}
public static void sendResumeEvent(String inputFile, int partIndex) {
diff --git a/android/source/src/java/org/libreoffice/LOKitThread.java b/android/source/src/java/org/libreoffice/LOKitThread.java
index 742b1cb6e34c..31d3b96440ed 100644
--- a/android/source/src/java/org/libreoffice/LOKitThread.java
+++ b/android/source/src/java/org/libreoffice/LOKitThread.java
@@ -3,9 +3,11 @@ package org.libreoffice;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.graphics.RectF;
+import android.util.Log;
import android.view.KeyEvent;
import org.libreoffice.canvas.SelectionHandle;
+import org.libreoffice.ui.LibreOfficeUIActivity;
import org.mozilla.gecko.gfx.CairoImage;
import org.mozilla.gecko.gfx.ComposedTileLayer;
import org.mozilla.gecko.gfx.GeckoLayerClient;
@@ -171,8 +173,6 @@ class LOKitThread extends Thread {
} else {
closeDocument();
}
-
-
}
/**
@@ -189,25 +189,65 @@ class LOKitThread extends Thread {
/**
* Handle load document event.
- * @param filename - filename where the document is located
+ * @param filePath - filePath to where the document is located
*/
- private void loadDocument(String filename) {
+ private void loadDocument(String filePath) {
+ mLayerClient = mContext.getLayerClient();
+ mInvalidationHandler = new InvalidationHandler(mContext);
+ mTileProvider = TileProviderFactory.create(mContext, mInvalidationHandler, filePath);
+
+ if (mTileProvider.isReady()) {
+ LOKitShell.showProgressSpinner(mContext);
+ refresh();
+ LOKitShell.hideProgressSpinner(mContext);
+ } else {
+ closeDocument();
+ }
+ }
+
+ /**
+ * Handle load new document event.
+ * @param filePath - filePath to where new document is to be created
+ * @param fileType - fileType what type of new document is to be loaded
+ */
+ private void loadNewDocument(String filePath, String fileType) {
mLayerClient = mContext.getLayerClient();
mInvalidationHandler = new InvalidationHandler(mContext);
- mTileProvider = TileProviderFactory.create(mContext, mInvalidationHandler, filename);
+ mTileProvider = TileProviderFactory.create(mContext, mInvalidationHandler, fileType);
if (mTileProvider.isReady()) {
LOKitShell.showProgressSpinner(mContext);
refresh();
LOKitShell.hideProgressSpinner(mContext);
+
+ if (fileType.matches(LibreOfficeUIActivity.NEW_WRITER_STRING_KEY))
+ mTileProvider.saveDocumentAs(filePath, "odt");
+ else if (fileType.matches(LibreOfficeUIActivity.NEW_CALC_STRING_KEY))
+ mTileProvider.saveDocumentAs(filePath, "ods");
+ else if (fileType.matches(LibreOfficeUIActivity.NEW_IMPRESS_STRING_KEY))
+ mTileProvider.saveDocumentAs(filePath, "odp");
+ else
+ mTileProvider.saveDocumentAs(filePath, "odg");
+
} else {
closeDocument();
}
}
/**
+ * Save the currently loaded document.
+ */
+ private void saveDocumentAs(String filePath, String fileType) {
+ if (mTileProvider == null) {
+ Log.e(LOGTAG, "Error in saving, Tile Provider instance is null");
+ } else {
+ mTileProvider.saveDocumentAs(filePath, fileType);
+ }
+ }
+
+ /**
* Close the currently loaded document.
*/
private void closeDocument() {
@@ -223,7 +263,13 @@ class LOKitThread extends Thread {
private void processEvent(LOEvent event) {
switch (event.mType) {
case LOEvent.LOAD:
- loadDocument(event.mString);
+ loadDocument(event.filePath);
+ break;
+ case LOEvent.LOAD_NEW:
+ loadNewDocument(event.filePath, event.fileType);
+ break;
+ case LOEvent.SAVE_AS:
+ saveDocumentAs(event.filePath, event.fileType);
break;
case LOEvent.RESUME:
resumeDocument(event.mString, event.mPartIndex);
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index d0fbe9431de7..6ed73ee32805 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -131,6 +131,30 @@ class LOKitTileProvider implements TileProvider {
});
}
+ @Override
+ public void saveDocumentAs(String filePath, String format) {
+ String newFilePath = "file://" + filePath;
+ Log.d("saveFilePathURL", newFilePath);
+ mDocument.saveAs(newFilePath, format, "");
+ if (!mOffice.getError().isEmpty()){
+ Log.e("Save Error", mOffice.getError());
+ LOKitShell.getMainHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ // There was some error
+ mContext.showSaveStatusToast(true);
+ }
+ });
+ }
+ LOKitShell.getMainHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ // There was no error
+ mContext.showSaveStatusToast(false);
+ }
+ });
+ }
+
private void setupDocumentFonts() {
String values = mDocument.getCommandValues(".uno:CharFontName");
if (values == null || values.isEmpty())
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 02129e50a7e8..fb41762af342 100755
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -10,8 +10,10 @@ import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.graphics.RectF;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.widget.DrawerLayout;
@@ -23,12 +25,13 @@ import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ListView;
-import android.widget.TabHost;
import android.widget.Toast;
import org.libreoffice.overlay.DocumentOverlay;
import org.libreoffice.storage.DocumentProviderFactory;
import org.libreoffice.storage.IFile;
+import org.libreoffice.ui.FileUtilities;
+import org.libreoffice.ui.LibreOfficeUIActivity;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.gfx.GeckoLayerClient;
import org.mozilla.gecko.gfx.LayerView;
@@ -66,19 +69,23 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
private URI documentUri;
private DrawerLayout mDrawerLayout;
+ Toolbar toolbarTop;
private ListView mDrawerList;
private List<DocumentPartView> mDocumentPartView = new ArrayList<DocumentPartView>();
private DocumentPartViewListAdapter mDocumentPartViewListAdapter;
private int partIndex=-1;
private File mInputFile;
+ private String newFileName = "untitled";
+ private String newFilePath = "/storage/emulated/0/Documents/";
private DocumentOverlay mDocumentOverlay;
private File mTempFile = null;
-
+ private String newDocumentType = null;
private FormattingController mFormattingController;
private ToolbarController mToolbarController;
private FontController mFontController;
private SearchController mSearchController;
+ private static final int PICKFOLDER_RESULT_CODE = 1;
public GeckoLayerClient getLayerClient() {
return mLayerClient;
@@ -96,7 +103,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
private boolean isFormattingToolbarOpen = false;
private boolean isSearchToolbarOpen = false;
private boolean isDocumentChanged = false;
-
+ public boolean isNewDocument = false;
@Override
public void onCreate(Bundle savedInstanceState) {
Log.w(LOGTAG, "onCreate..");
@@ -112,7 +119,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
}
setContentView(R.layout.activity_main);
- Toolbar toolbarTop = (Toolbar) findViewById(R.id.toolbar);
+ toolbarTop = (Toolbar) findViewById(R.id.toolbar);
hideBottomToolbar();
mToolbarController = new ToolbarController(this, toolbarTop);
@@ -127,32 +134,48 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
mFontController = new FontController(this);
mSearchController = new SearchController(this);
+ // New document type string is not null, it means we want to open a new document
+ if (getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY) != null) {
+ newDocumentType = getIntent().getStringExtra(LibreOfficeUIActivity.NEW_DOC_TYPE_KEY);
+ if (newDocumentType.matches(LibreOfficeUIActivity.NEW_WRITER_STRING_KEY))
+ newFileName = newFileName + ".odt";
+ else if (newDocumentType.matches(LibreOfficeUIActivity.NEW_IMPRESS_STRING_KEY))
+ newFileName = newFileName + ".odp";
+ else if (newDocumentType.matches(LibreOfficeUIActivity.NEW_CALC_STRING_KEY))
+ newFileName = newFileName + ".ods";
+ else
+ newFileName = newFileName + ".odg";
+ // We want to create a new Document, create an alert dialogue to name the new file.
+ openSelectPathIntent();
+ isNewDocument = true;
+ }
+
if (getIntent().getData() != null) {
if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
if (copyFileToTemp() && mTempFile != null) {
mInputFile = mTempFile;
- Log.d(LOGTAG, "SCHEME_CONTENT: getPath(): " + getIntent().getData().getPath());
+ Log.e(LOGTAG, "SCHEME_CONTENT: getPath(): " + getIntent().getData().getPath());
+ toolbarTop.setTitle(mInputFile.getName());
} else {
// TODO: can't open the file
Log.e(LOGTAG, "couldn't create temporary file from " + getIntent().getData());
}
} else if (getIntent().getData().getScheme().equals(ContentResolver.SCHEME_FILE)) {
mInputFile = new File(getIntent().getData().getPath());
- Log.d(LOGTAG, "SCHEME_FILE: getPath(): " + getIntent().getData().getPath());
-
+ Log.e(LOGTAG, "SCHEME_FILE: getPath(): " + getIntent().getData().getPath());
+ toolbarTop.setTitle(mInputFile.getName());
// Gather data to rebuild IFile object later
providerId = getIntent().getIntExtra(
"org.libreoffice.document_provider_id", 0);
documentUri = (URI) getIntent().getSerializableExtra(
"org.libreoffice.document_uri");
}
+ } else if (isNewDocument){
+ toolbarTop.setTitle(newFileName);
} else {
mInputFile = new File(DEFAULT_DOC_PATH);
}
- toolbarTop.setTitle(mInputFile.getName());
-
-
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
if (mDocumentPartViewListAdapter == null) {
@@ -187,24 +210,42 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
mDocumentOverlay = new DocumentOverlay(this, layerView);
mToolbarController.setupToolbars();
+ }
- TabHost host = (TabHost) findViewById(R.id.toolbarTabHost);
- host.setup();
-
- TabHost.TabSpec spec = host.newTabSpec("Character");
- spec.setContent(R.id.tab_character);
- spec.setIndicator("Character");
- host.addTab(spec);
-
- spec = host.newTabSpec("Paragraph");
- spec.setContent(R.id.tab_paragraph);
- spec.setIndicator("Paragraph");
- host.addTab(spec);
+ private void openSelectPathIntent() {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT)
+ .addCategory(Intent.CATEGORY_OPENABLE)
+ .setType("*/*")
+ .putExtra(Intent.EXTRA_TITLE, newFileName);
+ startActivityForResult(intent, PICKFOLDER_RESULT_CODE);
+ }
- spec = host.newTabSpec("Insert");
- spec.setContent(R.id.tab_insert);
- spec.setIndicator("Insert");
- host.addTab(spec);
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch(requestCode){
+ case PICKFOLDER_RESULT_CODE:
+ if(resultCode==RESULT_OK){
+ Uri fileURI = data.getData();
+ newFilePath = fileURI.getPath();
+ if (newFilePath.contains("primary")) {
+ /* When file is being saved in primary storage folder other than Documents home.
+ * newFilePath content is similar to this - /document/primary:Downloads/untitled1.odt */
+ newFilePath = Environment.getExternalStorageDirectory().getPath() + "/" + newFilePath.split(":")[1];
+ } else if (newFilePath.contains("home")) {
+ /* When file is being saved in documents folder itself i.e. Document home.
+ * newFilePath content is similar to this - /document/home:untitled1.odt */
+ newFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/" + newFilePath.split(":")[1];
+ } else {
+ newFilePath = Environment.getExternalStorageDirectory().getPath() + "/";
+ }
+ Log.d("newFilePath", newFilePath);
+ }
+ // Now set the input file variable to new file created
+ mInputFile = new File(newFilePath);
+ // and load the new document
+ LOKitShell.sendNewDocumentLoadEvent(newFilePath, newDocumentType);
+ break;
+ }
}
public RectF getCurrentCursorPosition() {
@@ -252,10 +293,21 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
}
/**
+ * Save a new document
+ * */
+ public void saveAs(){
+ LOKitShell.sendSaveAsEvent(mInputFile.getPath(), FileUtilities.getExtension(mInputFile.getPath()).substring(1));
+ }
+
+ /**
* Save the document and invoke save on document provider to upload the file
* to the cloud if necessary.
*/
public void saveDocument() {
+ if (!mInputFile.exists()) {
+ // Needed for handling null in case new document is not created.
+ mInputFile = new File(DEFAULT_DOC_PATH);
+ }
final long lastModified = mInputFile.lastModified();
final Activity activity = LibreOfficeMainActivity.this;
Toast.makeText(this, R.string.message_saving, Toast.LENGTH_SHORT).show();
@@ -341,10 +393,12 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
protected void onStart() {
Log.i(LOGTAG, "onStart..");
super.onStart();
- if(partIndex == -1)
- LOKitShell.sendLoadEvent(mInputFile.getPath());
- else
- LOKitShell.sendResumeEvent(mInputFile.getPath(), partIndex);
+ if (!isNewDocument){
+ if (partIndex == -1)
+ LOKitShell.sendLoadEvent(mInputFile.getPath());
+ else
+ LOKitShell.sendResumeEvent(mInputFile.getPath(), partIndex);
+ }
}
@Override
@@ -381,12 +435,14 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
- //SAVE
- saveDocument();
+ if (isNewDocument) {
+ saveAs();
+ } else {
+ saveDocument();
+ }
isDocumentChanged=false;
onBackPressed();
break;
-
case DialogInterface.BUTTON_NEGATIVE:
//CANCEL
break;
@@ -640,7 +696,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
}
private static boolean copyFromAssets(AssetManager assetManager,
- String fromAssetPath, String targetDir) {
+ String fromAssetPath, String targetDir) {
try {
String[] files = assetManager.list(fromAssetPath);
@@ -695,6 +751,14 @@ public class LibreOfficeMainActivity extends AppCompatActivity {
return false;
}
}
+
+ // This method is used in LOKitTileProvider.java to show status of new file creation.
+ public void showSaveStatusToast(boolean error) {
+ if (!error)
+ Toast.makeText(this, getString(R.string.save_as_success) + newFilePath, Toast.LENGTH_SHORT).show();
+ else
+ Toast.makeText(this, R.string.save_as_error, Toast.LENGTH_SHORT).show();
+ }
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/source/src/java/org/libreoffice/TileProvider.java b/android/source/src/java/org/libreoffice/TileProvider.java
index 0ab5a1f641c9..e84127cb0715 100644
--- a/android/source/src/java/org/libreoffice/TileProvider.java
+++ b/android/source/src/java/org/libreoffice/TileProvider.java
@@ -20,6 +20,12 @@ import org.mozilla.gecko.gfx.IntSize;
* Provides the tiles and other document information.
*/
public interface TileProvider {
+
+ /**
+ * Save the current document.
+ */
+ void saveDocumentAs(String filePath, String format);
+
/**
* Returns the page width in pixels.
*/
diff --git a/android/source/src/java/org/libreoffice/ToolbarController.java b/android/source/src/java/org/libreoffice/ToolbarController.java
index e4a55dd424b6..0012fdbeae06 100644
--- a/android/source/src/java/org/libreoffice/ToolbarController.java
+++ b/android/source/src/java/org/libreoffice/ToolbarController.java
@@ -98,7 +98,11 @@ public class ToolbarController implements Toolbar.OnMenuItemClickListener {
mContext.showAbout();
return true;
case R.id.action_save:
- mContext.saveDocument();
+ if (mContext.isNewDocument) {
+ mContext.saveAs();
+ } else {
+ mContext.saveDocument();
+ }
return true;
case R.id.action_parts:
mContext.openDrawer();
diff --git a/android/source/src/java/org/libreoffice/ui/FileUtilities.java b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
index 811fc4562dc7..aff6e0bfd7f3 100644
--- a/android/source/src/java/org/libreoffice/ui/FileUtilities.java
+++ b/android/source/src/java/org/libreoffice/ui/FileUtilities.java
@@ -121,7 +121,7 @@ public class FileUtilities {
extensionToMimeTypeMap.put("oth", "application/vnd.oasis.opendocument.text-web");
}
- private static final String getExtension(String filename) {
+ public static final String getExtension(String filename) {
if (filename == null)
return "";
int nExt = filename.lastIndexOf('.');
diff --git a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
index f2f408a7c331..01585b1077be 100644
--- a/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
+++ b/android/source/src/java/org/libreoffice/ui/LibreOfficeUIActivity.java
@@ -23,11 +23,14 @@ import android.hardware.usb.UsbManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
+import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.NavigationView;
import android.support.v4.content.ContextCompat;
+import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
@@ -47,7 +50,11 @@ import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
+import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
@@ -60,10 +67,12 @@ import org.libreoffice.storage.DocumentProviderFactory;
import org.libreoffice.storage.DocumentProviderSettingsActivity;
import org.libreoffice.storage.IDocumentProvider;
import org.libreoffice.storage.IFile;
+import org.libreoffice.storage.local.LocalFile;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
+import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
@@ -74,7 +83,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
-public class LibreOfficeUIActivity extends AppCompatActivity implements SettingsListenerModel.OnSettingsPreferenceChangedListener{
+public class LibreOfficeUIActivity extends AppCompatActivity implements SettingsListenerModel.OnSettingsPreferenceChangedListener, View.OnClickListener{
private String LOGTAG = LibreOfficeUIActivity.class.getSimpleName();
private SharedPreferences prefs;
private int filterMode = FileUtilities.ALL;
@@ -98,6 +107,12 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
public static final String SORT_MODE_KEY = "SORT_MODE";
private static final String RECENT_DOCUMENTS_KEY = "RECENT_DOCUMENTS";
+ public static final String NEW_DOC_TYPE_KEY = "NEW_DOC_TYPE_KEY";
+ public static final String NEW_WRITER_STRING_KEY = "private:factory/swriter";
+ public static final String NEW_IMPRESS_STRING_KEY = "private:factory/simpress";
+ public static final String NEW_CALC_STRING_KEY = "private:factory/scalc";
+ public static final String NEW_DRAW_STRING_KEY = "private:factory/sdraw";
+
public static final int GRID_VIEW = 0;
public static final int LIST_VIEW = 1;
@@ -110,6 +125,20 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
private boolean canQuit = false;
+ private Animation fabOpenAnimation;
+ private Animation fabCloseAnimation;
+ private boolean isFabMenuOpen = false;
+ private FloatingActionButton editFAB;
+ private FloatingActionButton writerFAB;
+ private FloatingActionButton drawFAB;
+ private FloatingActionButton impressFAB;
+ private FloatingActionButton calcFAB;
+ private LinearLayout drawLayout;
+ private LinearLayout writerLayout;
+ private LinearLayout impressLayout;
+ private LinearLayout calcLayout;
+
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -129,6 +158,7 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
// init UI and populate with contents from the provider
switchToDocumentProvider(documentProviderFactory.getDefaultProvider());
createUI();
+ getAnimations();
}
public void createUI() {
@@ -143,6 +173,21 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
actionBar.setDisplayHomeAsUpEnabled(true);
}
+ editFAB = (FloatingActionButton) findViewById(R.id.editFAB);
+ editFAB.setOnClickListener(this);
+ impressFAB = (FloatingActionButton) findViewById(R.id.newImpressFAB);
+ impressFAB.setOnClickListener(this);
+ writerFAB = (FloatingActionButton) findViewById(R.id.newWriterFAB);
+ writerFAB.setOnClickListener(this);
+ calcFAB = (FloatingActionButton) findViewById(R.id.newCalcFAB);
+ calcFAB.setOnClickListener(this);
+ drawFAB = (FloatingActionButton) findViewById(R.id.newDrawFAB);
+ drawFAB.setOnClickListener(this);
+ writerLayout = (LinearLayout) findViewById(R.id.writerLayout);
+ impressLayout = (LinearLayout) findViewById(R.id.impressLayout);
+ calcLayout = (LinearLayout) findViewById(R.id.calcLayout);
+ drawLayout = (LinearLayout) findViewById(R.id.drawLayout);
+
recentRecyclerView = (RecyclerView) findViewById(R.id.list_recent);
Set<String> recentFileStrings = prefs.getStringSet(RECENT_DOCUMENTS_KEY, new HashSet<String>());
@@ -235,6 +280,9 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
super.onDrawerOpened(drawerView);
supportInvalidateOptionsMenu();
navigationDrawer.requestFocus(); // Make keypad navigation easier
+ if (isFabMenuOpen) {
+ collapseFabMenu(); //Collapse FAB Menu when drawer is opened
+ }
}
@Override
@@ -248,6 +296,37 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
drawerToggle.syncState();
}
+ private void getAnimations() {
+ fabOpenAnimation = AnimationUtils.loadAnimation(this, R.anim.fab_open);
+ fabCloseAnimation = AnimationUtils.loadAnimation(this, R.anim.fab_close);
+ }
+
+ private void expandFabMenu() {
+ ViewCompat.animate(editFAB).rotation(45.0F).withLayer().setDuration(300).setInterpolator(new OvershootInterpolator(10.0F)).start();
+ drawLayout.startAnimation(fabOpenAnimation);
+ impressLayout.startAnimation(fabOpenAnimation);
+ writerLayout.startAnimation(fabOpenAnimation);
+ calcLayout.startAnimation(fabOpenAnimation);
+ writerFAB.setClickable(true);
+ impressFAB.setClickable(true);
+ drawFAB.setClickable(true);
+ calcFAB.setClickable(true);
+ isFabMenuOpen = true;
+ }
+
+ private void collapseFabMenu() {
+ ViewCompat.animate(editFAB).rotation(0.0F).withLayer().setDuration(300).setInterpolator(new OvershootInterpolator(10.0F)).start();
+ writerLayout.startAnimation(fabCloseAnimation);
+ impressLayout.startAnimation(fabCloseAnimation);
+ drawLayout.startAnimation(fabCloseAnimation);
+ calcLayout.startAnimation(fabCloseAnimation);
+ writerFAB.setClickable(false);
+ impressFAB.setClickable(false);
+ drawFAB.setClickable(false);
+ calcFAB.setClickable(false);
+ isFabMenuOpen = false;
+ }
+
private boolean checkDocumentProviderAvailability(IDocumentProvider provider) {
return provider.checkProviderAvailability();
}
@@ -273,15 +352,23 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
fileRecyclerView.setAdapter(new ExplorerItemAdapter(this, filePaths));
// close drawer if it was open
drawerLayout.closeDrawer(navigationDrawer);
+ if (isFabMenuOpen) {
+ collapseFabMenu();
+ }
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(navigationDrawer)) {
drawerLayout.closeDrawer(navigationDrawer);
+ if (isFabMenuOpen) {
+ collapseFabMenu();
+ }
} else if (!currentDirectory.equals(homeDirectory)) {
// navigate upwards in directory hierarchy
openParentDirectory();
+ } else if (isFabMenuOpen) {
+ collapseFabMenu();
} else {
// only exit if warning has been shown
if (canQuit) {
@@ -460,6 +547,13 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
}.execute(document);
}
+ // For opening a new Document
+ private void open(String newDocumentType) {
+ Intent intent = new Intent(this, LibreOfficeMainActivity.class);
+ intent.putExtra(NEW_DOC_TYPE_KEY, newDocumentType);
+ startActivity(intent);
+ }
+
private void open(int position) {
IFile file = filePaths.get(position);
if (!file.isDirectory()) {
@@ -884,6 +978,33 @@ public class LibreOfficeUIActivity extends AppCompatActivity implements Settings
}
}
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ switch (id){
+ case R.id.editFAB:
+ if (isFabMenuOpen) {
+ collapseFabMenu();
+ } else {
+ expandFabMenu();
+ }
+ break;
+ case R.id.newWriterFAB:
+ open(NEW_WRITER_STRING_KEY);
+ break;
+ case R.id.newImpressFAB:
+ open(NEW_IMPRESS_STRING_KEY);
+ break;
+ case R.id.newCalcFAB:
+ open(NEW_CALC_STRING_KEY);
+ break;
+ case R.id.newDrawFAB:
+ open(NEW_DRAW_STRING_KEY);
+ break;
+ }
+ }
+
+
class ExplorerItemAdapter extends RecyclerView.Adapter<ExplorerItemAdapter.ViewHolder> {
private Activity mActivity;
diff --git a/desktop/source/lib/lokandroid.cxx b/desktop/source/lib/lokandroid.cxx
index af3604aed6b6..0f807d061590 100644
--- a/desktop/source/lib/lokandroid.cxx
+++ b/desktop/source/lib/lokandroid.cxx
@@ -257,7 +257,7 @@ extern "C" SAL_JNI_EXPORT void JNICALL Java_org_libreoffice_kit_Document_initial
pDocument->pClass->initializeForRendering(pDocument, NULL);
}
-extern "C" SAL_JNI_EXPORT jint JNICALL Java_org_libreoffice_kit_Office_saveAs
+extern "C" SAL_JNI_EXPORT jint JNICALL Java_org_libreoffice_kit_Document_saveAs
(JNIEnv* pEnv, jobject aObject, jstring sUrl, jstring sFormat, jstring sOptions)
{
LibreOfficeKitDocument* pDocument = getHandle<LibreOfficeKitDocument>(pEnv, aObject);