Commit c7a1e38b authored by wanglei's avatar wanglei

...

parent 9fa8260b
...@@ -19,9 +19,6 @@ ...@@ -19,9 +19,6 @@
android:theme="@style/Theme.PDFViewerScannerWhite" android:theme="@style/Theme.PDFViewerScannerWhite"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:targetApi="34"> tools:targetApi="34">
<activity
android:name=".ui.document.ppt.PptActivity"
android:exported="false" />
<meta-data <meta-data
android:name="com.google.android.gms.version" android:name="com.google.android.gms.version"
...@@ -49,6 +46,12 @@ ...@@ -49,6 +46,12 @@
android:launchMode="singleTop" android:launchMode="singleTop"
android:screenOrientation="portrait" android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" /> tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity
android:name=".ui.document.ppt.PptActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="portrait"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity <activity
android:name=".ui.document.excel.ExcelActivity" android:name=".ui.document.excel.ExcelActivity"
android:exported="false" android:exported="false"
...@@ -58,7 +61,9 @@ ...@@ -58,7 +61,9 @@
<activity <activity
android:name=".ui.document.word.WordActivity" android:name=".ui.document.word.WordActivity"
android:exported="false" android:exported="false"
android:theme="@style/Theme.PDFViewerScannerWhite" /> android:screenOrientation="portrait"
android:theme="@style/Theme.PDFViewerScannerWhite"
tools:ignore="DiscouragedApi,LockedOrientationActivity" />
<activity <activity
android:name=".ui.document.pdf.PdfMergeActivity" android:name=".ui.document.pdf.PdfMergeActivity"
android:exported="false" android:exported="false"
......
...@@ -2,6 +2,7 @@ package com.base.pdfviewerscannerwhite.ui.main ...@@ -2,6 +2,7 @@ package com.base.pdfviewerscannerwhite.ui.main
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.net.Uri import android.net.Uri
import android.provider.MediaStore
import android.view.View import android.view.View
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
...@@ -20,6 +21,7 @@ import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime2 ...@@ -20,6 +21,7 @@ import com.base.pdfviewerscannerwhite.utils.KotlinExt.toFormatTime2
import com.base.pdfviewerscannerwhite.utils.LogEx import com.base.pdfviewerscannerwhite.utils.LogEx
import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission import com.base.pdfviewerscannerwhite.utils.PermissionUtils.checkStorePermission
import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast import com.base.pdfviewerscannerwhite.utils.ToastUtils.toast
import com.base.pdfviewerscannerwhite.utils.updateMediaStore
class MainActivity : BaseActivity<ActivityMainBinding>(), MainView { class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
...@@ -81,7 +83,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView { ...@@ -81,7 +83,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), MainView {
if (!checkStorePermission()) { if (!checkStorePermission()) {
showStoragePermission(launcher) showStoragePermission(launcher)
updateMediaStore()
} }
} }
private fun initTabLayout() { private fun initTabLayout() {
......
...@@ -28,6 +28,10 @@ android { ...@@ -28,6 +28,10 @@ android {
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = '1.8'
} }
buildFeatures {
viewBinding = true
}
} }
dependencies { dependencies {
......
...@@ -6,7 +6,7 @@ import android.util.Log ...@@ -6,7 +6,7 @@ import android.util.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.cherry.lib.doc.bean.DocEngine import com.cherry.lib.doc.bean.DocEngine
import com.cherry.lib.doc.util.Constant import com.cherry.lib.doc.util.Constant
import kotlinx.android.synthetic.main.activity_doc_viewer.mDocView import com.cherry.lib.doc.widget.DocView
open class DocViewerActivity : AppCompatActivity() { open class DocViewerActivity : AppCompatActivity() {
private val TAG = "DocViewerActivity" private val TAG = "DocViewerActivity"
...@@ -16,7 +16,7 @@ open class DocViewerActivity : AppCompatActivity() { ...@@ -16,7 +16,7 @@ open class DocViewerActivity : AppCompatActivity() {
activity: AppCompatActivity, docSourceType: Int, path: String?, activity: AppCompatActivity, docSourceType: Int, path: String?,
fileType: Int? = null, engine: Int? = null fileType: Int? = null, engine: Int? = null
) { ) {
var intent = Intent(activity, DocViewerActivity::class.java) val intent = Intent(activity, DocViewerActivity::class.java)
intent.putExtra(Constant.INTENT_SOURCE_KEY, docSourceType) intent.putExtra(Constant.INTENT_SOURCE_KEY, docSourceType)
intent.putExtra(Constant.INTENT_DATA_KEY, path) intent.putExtra(Constant.INTENT_DATA_KEY, path)
intent.putExtra(Constant.INTENT_TYPE_KEY, fileType) intent.putExtra(Constant.INTENT_TYPE_KEY, fileType)
...@@ -34,6 +34,8 @@ open class DocViewerActivity : AppCompatActivity() { ...@@ -34,6 +34,8 @@ open class DocViewerActivity : AppCompatActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_doc_viewer) setContentView(R.layout.activity_doc_viewer)
initView() initView()
initData(intent) initData(intent)
} }
...@@ -47,7 +49,13 @@ open class DocViewerActivity : AppCompatActivity() { ...@@ -47,7 +49,13 @@ open class DocViewerActivity : AppCompatActivity() {
fileType = intent?.getIntExtra(Constant.INTENT_TYPE_KEY, -1) ?: -1 fileType = intent?.getIntExtra(Constant.INTENT_TYPE_KEY, -1) ?: -1
engine = intent?.getIntExtra(Constant.INTENT_ENGINE_KEY, DocEngine.INTERNAL.value) ?: DocEngine.INTERNAL.value engine = intent?.getIntExtra(Constant.INTENT_ENGINE_KEY, DocEngine.INTERNAL.value) ?: DocEngine.INTERNAL.value
mDocView.openDoc(this,docUrl,docSourceType,fileType,false, DocEngine.values().first { it.value == engine }) findViewById<DocView>(R.id.mDocView).openDoc(
this,
docUrl,
docSourceType,
fileType,
false,
DocEngine.values().first { it.value == engine })
Log.e(TAG, "initData-docUrl = $docUrl") Log.e(TAG, "initData-docUrl = $docUrl")
Log.e(TAG, "initData-docSourceType = $docSourceType") Log.e(TAG, "initData-docSourceType = $docSourceType")
Log.e(TAG, "initData-fileType = $fileType") Log.e(TAG, "initData-fileType = $fileType")
......
...@@ -5,7 +5,6 @@ import android.graphics.Bitmap; ...@@ -5,7 +5,6 @@ import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import com.blankj.utilcode.util.AppUtils; import com.blankj.utilcode.util.AppUtils;
import com.cherry.lib.doc.office.common.IOfficeToPicture; import com.cherry.lib.doc.office.common.IOfficeToPicture;
import com.cherry.lib.doc.office.constant.EventConstant; import com.cherry.lib.doc.office.constant.EventConstant;
...@@ -13,7 +12,6 @@ import com.cherry.lib.doc.office.constant.wp.WPViewConstant; ...@@ -13,7 +12,6 @@ import com.cherry.lib.doc.office.constant.wp.WPViewConstant;
import com.cherry.lib.doc.office.res.ResKit; import com.cherry.lib.doc.office.res.ResKit;
import com.cherry.lib.doc.office.system.IMainFrame; import com.cherry.lib.doc.office.system.IMainFrame;
import com.cherry.lib.doc.office.system.MainControl; import com.cherry.lib.doc.office.system.MainControl;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
...@@ -217,7 +215,7 @@ public abstract class IOffice implements IMainFrame { ...@@ -217,7 +215,7 @@ public abstract class IOffice implements IMainFrame {
* 是否绘制页码 * 是否绘制页码
*/ */
public boolean isDrawPageNumber() { public boolean isDrawPageNumber() {
return true; return false;
} }
/** /**
......
...@@ -17,13 +17,9 @@ ...@@ -17,13 +17,9 @@
package com.cherry.lib.doc.office.fc.hslf.model; package com.cherry.lib.doc.office.fc.hslf.model;
import java.io.ByteArrayOutputStream;
import com.cherry.lib.doc.office.fc.ddf.EscherClientDataRecord;
import com.cherry.lib.doc.office.fc.ddf.EscherContainerRecord; import com.cherry.lib.doc.office.fc.ddf.EscherContainerRecord;
import com.cherry.lib.doc.office.fc.ddf.EscherProperties;
import com.cherry.lib.doc.office.fc.hslf.exceptions.HSLFException;
import com.cherry.lib.doc.office.fc.hslf.record.*; import com.cherry.lib.doc.office.fc.hslf.record.*;
import com.cherry.lib.doc.office.fc.hslf.record.Record;
import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow; import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow;
...@@ -32,8 +28,7 @@ import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow; ...@@ -32,8 +28,7 @@ import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow;
* *
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public final class MovieShape extends Picture public final class MovieShape extends Picture {
{
public static final int DEFAULT_MOVIE_THUMBNAIL = -1; public static final int DEFAULT_MOVIE_THUMBNAIL = -1;
public static final int MOVIE_MPEG = 1; public static final int MOVIE_MPEG = 1;
...@@ -42,10 +37,9 @@ public final class MovieShape extends Picture ...@@ -42,10 +37,9 @@ public final class MovieShape extends Picture
/** /**
* Create a new <code>Picture</code> * Create a new <code>Picture</code>
* *
* @param pictureIdx the index of the picture * @param pictureIdx the index of the picture
*/ */
public MovieShape(int movieIdx, int pictureIdx) public MovieShape(int movieIdx, int pictureIdx) {
{
super(pictureIdx, null); super(pictureIdx, null);
setMovieIndex(movieIdx); setMovieIndex(movieIdx);
setAutoPlay(true); setAutoPlay(true);
...@@ -54,24 +48,22 @@ public final class MovieShape extends Picture ...@@ -54,24 +48,22 @@ public final class MovieShape extends Picture
/** /**
* Create a new <code>Picture</code> * Create a new <code>Picture</code>
* *
* @param idx the index of the picture * @param idx the index of the picture
* @param parent the parent shape * @param parent the parent shape
*/ */
public MovieShape(int movieIdx, int idx, Shape parent) public MovieShape(int movieIdx, int idx, Shape parent) {
{
super(idx, parent); super(idx, parent);
setMovieIndex(movieIdx); setMovieIndex(movieIdx);
} }
/** /**
* Create a <code>Picture</code> object * Create a <code>Picture</code> object
* *
* @param escherRecord the <code>EscherSpContainer</code> record which holds information about * @param escherRecord the <code>EscherSpContainer</code> record which holds information about
* this picture in the <code>Slide</code> * this picture in the <code>Slide</code>
* @param parent the parent shape of this picture * @param parent the parent shape of this picture
*/ */
protected MovieShape(EscherContainerRecord escherRecord, Shape parent) protected MovieShape(EscherContainerRecord escherRecord, Shape parent) {
{
super(escherRecord, parent); super(escherRecord, parent);
} }
...@@ -80,8 +72,7 @@ public final class MovieShape extends Picture ...@@ -80,8 +72,7 @@ public final class MovieShape extends Picture
* *
* @return the created <code>EscherContainerRecord</code> which holds shape data * @return the created <code>EscherContainerRecord</code> which holds shape data
*/ */
protected EscherContainerRecord createSpContainer(int idx, boolean isChild) protected EscherContainerRecord createSpContainer(int idx, boolean isChild) {
{
_escherContainer = super.createSpContainer(idx, isChild); _escherContainer = super.createSpContainer(idx, isChild);
/*setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x1000100); /*setEscherProperty(EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x1000100);
...@@ -112,7 +103,8 @@ public final class MovieShape extends Picture ...@@ -112,7 +103,8 @@ public final class MovieShape extends Picture
{ {
throw new HSLFException(e); throw new HSLFException(e);
} }
cldata.setRemainingData(out.toByteArray())*/; cldata.setRemainingData(out.toByteArray())*/
;
return _escherContainer; return _escherContainer;
} }
...@@ -120,17 +112,15 @@ public final class MovieShape extends Picture ...@@ -120,17 +112,15 @@ public final class MovieShape extends Picture
/** /**
* Assign a movie to this shape * Assign a movie to this shape
* *
* @param idx the index of the movie
* @see com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow#addMovie(String, int) * @see com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow#addMovie(String, int)
* @param idx the index of the movie
*/ */
public void setMovieIndex(int idx) public void setMovieIndex(int idx) {
{ OEShapeAtom oe = (OEShapeAtom) getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
oe.setOptions(idx); oe.setOptions(idx);
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID); AnimationInfo an = (AnimationInfo) getClientDataRecord(RecordTypes.AnimationInfo.typeID);
if (an != null) if (an != null) {
{
AnimationInfoAtom ai = an.getAnimationInfoAtom(); AnimationInfoAtom ai = an.getAnimationInfoAtom();
ai.setDimColor(0x07000000); ai.setDimColor(0x07000000);
ai.setFlag(AnimationInfoAtom.Automatic, true); ai.setFlag(AnimationInfoAtom.Automatic, true);
...@@ -140,21 +130,17 @@ public final class MovieShape extends Picture ...@@ -140,21 +130,17 @@ public final class MovieShape extends Picture
} }
} }
public void setAutoPlay(boolean flag) public void setAutoPlay(boolean flag) {
{ AnimationInfo an = (AnimationInfo) getClientDataRecord(RecordTypes.AnimationInfo.typeID);
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID); if (an != null) {
if (an != null)
{
an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag); an.getAnimationInfoAtom().setFlag(AnimationInfoAtom.Automatic, flag);
updateClientData(); updateClientData();
} }
} }
public boolean isAutoPlay() public boolean isAutoPlay() {
{ AnimationInfo an = (AnimationInfo) getClientDataRecord(RecordTypes.AnimationInfo.typeID);
AnimationInfo an = (AnimationInfo)getClientDataRecord(RecordTypes.AnimationInfo.typeID); if (an != null) {
if (an != null)
{
return an.getAnimationInfoAtom().getFlag(AnimationInfoAtom.Automatic); return an.getAnimationInfoAtom().getFlag(AnimationInfoAtom.Automatic);
} }
return false; return false;
...@@ -163,27 +149,23 @@ public final class MovieShape extends Picture ...@@ -163,27 +149,23 @@ public final class MovieShape extends Picture
/** /**
* @return UNC or local path to a video file * @return UNC or local path to a video file
*/ */
public String getPath() public String getPath() {
{ OEShapeAtom oe = (OEShapeAtom) getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
OEShapeAtom oe = (OEShapeAtom)getClientDataRecord(RecordTypes.OEShapeAtom.typeID);
int idx = oe.getOptions(); int idx = oe.getOptions();
SlideShow ppt = getSheet().getSlideShow(); SlideShow ppt = getSheet().getSlideShow();
ExObjList lst = (ExObjList)ppt.getDocumentRecord().findFirstOfType( ExObjList lst = (ExObjList) ppt.getDocumentRecord().findFirstOfType(
RecordTypes.ExObjList.typeID); RecordTypes.ExObjList.typeID);
if (lst == null) if (lst == null)
return null; return null;
Record[] r = lst.getChildRecords(); Record[] r = lst.getChildRecords();
for (int i = 0; i < r.length; i++) for (int i = 0; i < r.length; i++) {
{ if (r[i] instanceof ExMCIMovie) {
if (r[i] instanceof ExMCIMovie) ExMCIMovie mci = (ExMCIMovie) r[i];
{
ExMCIMovie mci = (ExMCIMovie)r[i];
ExVideoContainer exVideo = mci.getExVideo(); ExVideoContainer exVideo = mci.getExVideo();
int objectId = exVideo.getExMediaAtom().getObjectId(); int objectId = exVideo.getExMediaAtom().getObjectId();
if (objectId == idx) if (objectId == idx) {
{
return exVideo.getPathAtom().getText(); return exVideo.getPathAtom().getText();
} }
} }
......
...@@ -23,6 +23,7 @@ import java.util.Vector; ...@@ -23,6 +23,7 @@ import java.util.Vector;
import com.cherry.lib.doc.office.fc.hslf.model.textproperties.AutoNumberTextProp; import com.cherry.lib.doc.office.fc.hslf.model.textproperties.AutoNumberTextProp;
import com.cherry.lib.doc.office.fc.hslf.model.textproperties.TextPropCollection; import com.cherry.lib.doc.office.fc.hslf.model.textproperties.TextPropCollection;
import com.cherry.lib.doc.office.fc.hslf.record.*; import com.cherry.lib.doc.office.fc.hslf.record.*;
import com.cherry.lib.doc.office.fc.hslf.record.Record;
import com.cherry.lib.doc.office.fc.hslf.usermodel.RichTextRun; import com.cherry.lib.doc.office.fc.hslf.usermodel.RichTextRun;
import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow; import com.cherry.lib.doc.office.fc.hslf.usermodel.SlideShow;
import com.cherry.lib.doc.office.fc.util.StringUtil; import com.cherry.lib.doc.office.fc.util.StringUtil;
...@@ -30,14 +31,13 @@ import com.cherry.lib.doc.office.fc.util.StringUtil; ...@@ -30,14 +31,13 @@ import com.cherry.lib.doc.office.fc.util.StringUtil;
/** /**
* This class represents a run of text in a powerpoint document. That * This class represents a run of text in a powerpoint document. That
* run could be text on a sheet, or text in a note. * run could be text on a sheet, or text in a note.
* It is only a very basic class for now * It is only a very basic class for now
* *
* @author Nick Burch * @author Nick Burch
*/ */
public final class TextRun public final class TextRun {
{
/** /**
* all text run records that follow TextHeaderAtom. * all text run records that follow TextHeaderAtom.
* (there can be misc InteractiveInfo, TxInteractiveInfo and other records) * (there can be misc InteractiveInfo, TxInteractiveInfo and other records)
...@@ -45,43 +45,37 @@ public final class TextRun ...@@ -45,43 +45,37 @@ public final class TextRun
protected Record[] _records; protected Record[] _records;
/** /**
* Constructs a Text Run from a Unicode text block * Constructs a Text Run from a Unicode text block
* *
* @param tha the TextHeaderAtom that defines what's what * @param tha the TextHeaderAtom that defines what's what
* @param tca the TextCharsAtom containing the text * @param tca the TextCharsAtom containing the text
* @param sta the StyleTextPropAtom which defines the character stylings * @param sta the StyleTextPropAtom which defines the character stylings
*/ */
public TextRun(TextHeaderAtom tha, TextCharsAtom tca, StyleTextPropAtom sta) public TextRun(TextHeaderAtom tha, TextCharsAtom tca, StyleTextPropAtom sta) {
{
this(tha, null, tca, sta); this(tha, null, tca, sta);
} }
/** /**
* Constructs a Text Run from a Ascii text block * Constructs a Text Run from a Ascii text block
* *
* @param tha the TextHeaderAtom that defines what's what * @param tha the TextHeaderAtom that defines what's what
* @param tba the TextBytesAtom containing the text * @param tba the TextBytesAtom containing the text
* @param sta the StyleTextPropAtom which defines the character stylings * @param sta the StyleTextPropAtom which defines the character stylings
*/ */
public TextRun(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) public TextRun(TextHeaderAtom tha, TextBytesAtom tba, StyleTextPropAtom sta) {
{
this(tha, tba, null, sta); this(tha, tba, null, sta);
} }
/** /**
* Internal constructor and initializer * Internal constructor and initializer
*/ */
private TextRun(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta) private TextRun(TextHeaderAtom tha, TextBytesAtom tba, TextCharsAtom tca, StyleTextPropAtom sta) {
{
_headerAtom = tha; _headerAtom = tha;
_styleAtom = sta; _styleAtom = sta;
if (tba != null) if (tba != null) {
{
_byteAtom = tba; _byteAtom = tba;
_isUnicode = false; _isUnicode = false;
} } else {
else
{
_charAtom = tca; _charAtom = tca;
_isUnicode = true; _isUnicode = true;
} }
...@@ -90,8 +84,7 @@ public final class TextRun ...@@ -90,8 +84,7 @@ public final class TextRun
// Figure out the rich text runs // Figure out the rich text runs
LinkedList pStyles = new LinkedList(); LinkedList pStyles = new LinkedList();
LinkedList cStyles = new LinkedList(); LinkedList cStyles = new LinkedList();
if (_styleAtom != null) if (_styleAtom != null) {
{
// Get the style atom to grok itself // Get the style atom to grok itself
_styleAtom.setParentTextSize(runRawText.length()); _styleAtom.setParentTextSize(runRawText.length());
pStyles = _styleAtom.getParagraphStyles(); pStyles = _styleAtom.getParagraphStyles();
...@@ -100,17 +93,13 @@ public final class TextRun ...@@ -100,17 +93,13 @@ public final class TextRun
buildRichTextRuns(pStyles, cStyles, runRawText); buildRichTextRuns(pStyles, cStyles, runRawText);
} }
public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText) public void buildRichTextRuns(LinkedList pStyles, LinkedList cStyles, String runRawText) {
{
// Handle case of no current style, with a default // Handle case of no current style, with a default
if (pStyles.size() == 0 || cStyles.size() == 0) if (pStyles.size() == 0 || cStyles.size() == 0) {
{
_rtRuns = new RichTextRun[1]; _rtRuns = new RichTextRun[1];
_rtRuns[0] = new RichTextRun(this, 0, runRawText.length()); _rtRuns[0] = new RichTextRun(this, 0, runRawText.length());
} } else {
else
{
// Build up Rich Text Runs, one for each // Build up Rich Text Runs, one for each
// character/paragraph style pair // character/paragraph style pair
Vector rtrs = new Vector(); Vector rtrs = new Vector();
...@@ -123,27 +112,23 @@ public final class TextRun ...@@ -123,27 +112,23 @@ public final class TextRun
int cLenRemain = -1; int cLenRemain = -1;
// Build one for each run with the same style // Build one for each run with the same style
while (pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) while (pos <= runRawText.length() && curP < pStyles.size() && curC < cStyles.size()) {
{
// Get the Props to use // Get the Props to use
TextPropCollection pProps = (TextPropCollection)pStyles.get(curP); TextPropCollection pProps = (TextPropCollection) pStyles.get(curP);
TextPropCollection cProps = (TextPropCollection)cStyles.get(curC); TextPropCollection cProps = (TextPropCollection) cStyles.get(curC);
int pLen = pProps.getCharactersCovered(); int pLen = pProps.getCharactersCovered();
int cLen = cProps.getCharactersCovered(); int cLen = cProps.getCharactersCovered();
// Handle new pass // Handle new pass
boolean freshSet = false; boolean freshSet = false;
if (pLenRemain == -1 && cLenRemain == -1) if (pLenRemain == -1 && cLenRemain == -1) {
{
freshSet = true; freshSet = true;
} }
if (pLenRemain == -1) if (pLenRemain == -1) {
{
pLenRemain = pLen; pLenRemain = pLen;
} }
if (cLenRemain == -1) if (cLenRemain == -1) {
{
cLenRemain = cLen; cLenRemain = cLen;
} }
...@@ -153,8 +138,7 @@ public final class TextRun ...@@ -153,8 +138,7 @@ public final class TextRun
boolean cShared = false; boolean cShared = false;
// Same size, new styles - neither shared // Same size, new styles - neither shared
if (pLen == cLen && freshSet) if (pLen == cLen && freshSet) {
{
runLen = cLen; runLen = cLen;
pShared = false; pShared = false;
cShared = false; cShared = false;
...@@ -162,20 +146,16 @@ public final class TextRun ...@@ -162,20 +146,16 @@ public final class TextRun
curC++; curC++;
pLenRemain = -1; pLenRemain = -1;
cLenRemain = -1; cLenRemain = -1;
} } else {
else
{
// Some sharing // Some sharing
// See if we are already in a shared block // See if we are already in a shared block
if (pLenRemain < pLen) if (pLenRemain < pLen) {
{
// Existing shared p block // Existing shared p block
pShared = true; pShared = true;
// Do we end with the c block, or either side of it? // Do we end with the c block, or either side of it?
if (pLenRemain == cLenRemain) if (pLenRemain == cLenRemain) {
{
// We end at the same time // We end at the same time
cShared = false; cShared = false;
runLen = pLenRemain; runLen = pLenRemain;
...@@ -183,18 +163,14 @@ public final class TextRun ...@@ -183,18 +163,14 @@ public final class TextRun
curC++; curC++;
pLenRemain = -1; pLenRemain = -1;
cLenRemain = -1; cLenRemain = -1;
} } else if (pLenRemain < cLenRemain) {
else if (pLenRemain < cLenRemain)
{
// We end before the c block // We end before the c block
cShared = true; cShared = true;
runLen = pLenRemain; runLen = pLenRemain;
curP++; curP++;
cLenRemain -= pLenRemain; cLenRemain -= pLenRemain;
pLenRemain = -1; pLenRemain = -1;
} } else {
else
{
// We end after the c block // We end after the c block
cShared = false; cShared = false;
runLen = cLenRemain; runLen = cLenRemain;
...@@ -202,15 +178,12 @@ public final class TextRun ...@@ -202,15 +178,12 @@ public final class TextRun
pLenRemain -= cLenRemain; pLenRemain -= cLenRemain;
cLenRemain = -1; cLenRemain = -1;
} }
} } else if (cLenRemain < cLen) {
else if (cLenRemain < cLen)
{
// Existing shared c block // Existing shared c block
cShared = true; cShared = true;
// Do we end with the p block, or either side of it? // Do we end with the p block, or either side of it?
if (pLenRemain == cLenRemain) if (pLenRemain == cLenRemain) {
{
// We end at the same time // We end at the same time
pShared = false; pShared = false;
runLen = cLenRemain; runLen = cLenRemain;
...@@ -218,18 +191,14 @@ public final class TextRun ...@@ -218,18 +191,14 @@ public final class TextRun
curC++; curC++;
pLenRemain = -1; pLenRemain = -1;
cLenRemain = -1; cLenRemain = -1;
} } else if (cLenRemain < pLenRemain) {
else if (cLenRemain < pLenRemain)
{
// We end before the p block // We end before the p block
pShared = true; pShared = true;
runLen = cLenRemain; runLen = cLenRemain;
curC++; curC++;
pLenRemain -= cLenRemain; pLenRemain -= cLenRemain;
cLenRemain = -1; cLenRemain = -1;
} } else {
else
{
// We end after the p block // We end after the p block
pShared = false; pShared = false;
runLen = pLenRemain; runLen = pLenRemain;
...@@ -237,12 +206,9 @@ public final class TextRun ...@@ -237,12 +206,9 @@ public final class TextRun
cLenRemain -= pLenRemain; cLenRemain -= pLenRemain;
pLenRemain = -1; pLenRemain = -1;
} }
} } else {
else
{
// Start of a shared block // Start of a shared block
if (pLenRemain < cLenRemain) if (pLenRemain < cLenRemain) {
{
// Shared c block // Shared c block
pShared = false; pShared = false;
cShared = true; cShared = true;
...@@ -250,9 +216,7 @@ public final class TextRun ...@@ -250,9 +216,7 @@ public final class TextRun
curP++; curP++;
cLenRemain -= pLenRemain; cLenRemain -= pLenRemain;
pLenRemain = -1; pLenRemain = -1;
} } else {
else
{
// Shared p block // Shared p block
pShared = true; pShared = true;
cShared = false; cShared = false;
...@@ -268,14 +232,13 @@ public final class TextRun ...@@ -268,14 +232,13 @@ public final class TextRun
int prevPos = pos; int prevPos = pos;
pos += runLen; pos += runLen;
// Adjust for end-of-run extra 1 length // Adjust for end-of-run extra 1 length
if (pos > runRawText.length()) if (pos > runRawText.length()) {
{
runLen--; runLen--;
} }
// Save // Save
RichTextRun rtr = new RichTextRun(this, prevPos, runLen, pProps, cProps, pShared, RichTextRun rtr = new RichTextRun(this, prevPos, runLen, pProps, cProps, pShared,
cShared); cShared);
rtrs.add(rtr); rtrs.add(rtr);
} }
...@@ -290,13 +253,12 @@ public final class TextRun ...@@ -290,13 +253,12 @@ public final class TextRun
/** /**
* Adds the supplied text onto the end of the TextRun, * Adds the supplied text onto the end of the TextRun,
* creating a new RichTextRun (returned) for it to * creating a new RichTextRun (returned) for it to
* sit in. * sit in.
* In many cases, before calling this, you'll want to add * In many cases, before calling this, you'll want to add
* a newline onto the end of your last RichTextRun * a newline onto the end of your last RichTextRun
*/ */
public RichTextRun appendText(String s) public RichTextRun appendText(String s) {
{
// We will need a StyleTextProp atom // We will need a StyleTextProp atom
ensureStyleAtomPresent(); ensureStyleAtomPresent();
...@@ -310,22 +272,20 @@ public final class TextRun ...@@ -310,22 +272,20 @@ public final class TextRun
// extra character onto the new ones // extra character onto the new ones
int pOverRun = _styleAtom.getParagraphTextLengthCovered() - oldSize; int pOverRun = _styleAtom.getParagraphTextLengthCovered() - oldSize;
int cOverRun = _styleAtom.getCharacterTextLengthCovered() - oldSize; int cOverRun = _styleAtom.getCharacterTextLengthCovered() - oldSize;
if (pOverRun > 0) if (pOverRun > 0) {
{ TextPropCollection tpc = (TextPropCollection) _styleAtom.getParagraphStyles().getLast();
TextPropCollection tpc = (TextPropCollection)_styleAtom.getParagraphStyles().getLast();
tpc.updateTextSize(tpc.getCharactersCovered() - pOverRun); tpc.updateTextSize(tpc.getCharactersCovered() - pOverRun);
} }
if (cOverRun > 0) if (cOverRun > 0) {
{ TextPropCollection tpc = (TextPropCollection) _styleAtom.getCharacterStyles().getLast();
TextPropCollection tpc = (TextPropCollection)_styleAtom.getCharacterStyles().getLast();
tpc.updateTextSize(tpc.getCharactersCovered() - cOverRun); tpc.updateTextSize(tpc.getCharactersCovered() - cOverRun);
} }
// Next, add the styles for its paragraph and characters // Next, add the styles for its paragraph and characters
TextPropCollection newPTP = _styleAtom TextPropCollection newPTP = _styleAtom
.addParagraphTextPropCollection(s.length() + pOverRun); .addParagraphTextPropCollection(s.length() + pOverRun);
TextPropCollection newCTP = _styleAtom TextPropCollection newCTP = _styleAtom
.addCharacterTextPropCollection(s.length() + cOverRun); .addCharacterTextPropCollection(s.length() + cOverRun);
// Now, create the new RichTextRun // Now, create the new RichTextRun
RichTextRun nr = new RichTextRun(this, oldSize, s.length(), newPTP, newCTP, false, false); RichTextRun nr = new RichTextRun(this, oldSize, s.length(), newPTP, newCTP, false, false);
...@@ -342,36 +302,28 @@ public final class TextRun ...@@ -342,36 +302,28 @@ public final class TextRun
/** /**
* Saves the given string to the records. Doesn't * Saves the given string to the records. Doesn't
* touch the stylings. * touch the stylings.
*/ */
private void storeText(String s) private void storeText(String s) {
{
// Remove a single trailing \r, as there is an implicit one at the // Remove a single trailing \r, as there is an implicit one at the
// end of every record // end of every record
if (s.endsWith("\r")) if (s.endsWith("\r")) {
{
s = s.substring(0, s.length() - 1); s = s.substring(0, s.length() - 1);
} }
// Store in the appropriate record // Store in the appropriate record
if (_isUnicode) if (_isUnicode) {
{
// The atom can safely convert to unicode // The atom can safely convert to unicode
_charAtom.setText(s); _charAtom.setText(s);
} } else {
else
{
// Will it fit in a 8 bit atom? // Will it fit in a 8 bit atom?
boolean hasMultibyte = StringUtil.hasMultibyte(s); boolean hasMultibyte = StringUtil.hasMultibyte(s);
if (!hasMultibyte) if (!hasMultibyte) {
{
// Fine to go into 8 bit atom // Fine to go into 8 bit atom
byte[] text = new byte[s.length()]; byte[] text = new byte[s.length()];
StringUtil.putCompressedUnicode(s, text, 0); StringUtil.putCompressedUnicode(s, text, 0);
_byteAtom.setText(text); _byteAtom.setText(text);
} } else {
else
{
// Need to swap a TextBytesAtom for a TextCharsAtom // Need to swap a TextBytesAtom for a TextCharsAtom
// Build the new TextCharsAtom // Build the new TextCharsAtom
...@@ -381,11 +333,9 @@ public final class TextRun ...@@ -381,11 +333,9 @@ public final class TextRun
// Use the TextHeaderAtom to do the swap on the parent // Use the TextHeaderAtom to do the swap on the parent
RecordContainer parent = _headerAtom.getParentRecord(); RecordContainer parent = _headerAtom.getParentRecord();
Record[] cr = parent.getChildRecords(); Record[] cr = parent.getChildRecords();
for (int i = 0; i < cr.length; i++) for (int i = 0; i < cr.length; i++) {
{
// Look for TextBytesAtom // Look for TextBytesAtom
if (cr[i].equals(_byteAtom)) if (cr[i].equals(_byteAtom)) {
{
// Found it, so replace, then all done // Found it, so replace, then all done
cr[i] = _charAtom; cr[i] = _charAtom;
break; break;
...@@ -402,13 +352,10 @@ public final class TextRun ...@@ -402,13 +352,10 @@ public final class TextRun
* otherwise the ppt will be corrupted * otherwise the ppt will be corrupted
*/ */
if (_records != null) if (_records != null)
for (int i = 0; i < _records.length; i++) for (int i = 0; i < _records.length; i++) {
{ if (_records[i] instanceof TextSpecInfoAtom) {
if (_records[i] instanceof TextSpecInfoAtom) TextSpecInfoAtom specAtom = (TextSpecInfoAtom) _records[i];
{ if ((s.length() + 1) != specAtom.getCharactersCovered()) {
TextSpecInfoAtom specAtom = (TextSpecInfoAtom)_records[i];
if ((s.length() + 1) != specAtom.getCharactersCovered())
{
specAtom.reset(s.length() + 1); specAtom.reset(s.length() + 1);
} }
} }
...@@ -417,22 +364,19 @@ public final class TextRun ...@@ -417,22 +364,19 @@ public final class TextRun
/** /**
* Handles an update to the text stored in one of the Rich Text Runs * Handles an update to the text stored in one of the Rich Text Runs
*
* @param run * @param run
* @param s * @param s
*/ */
public void changeTextInRichTextRun(RichTextRun run, String s) public void changeTextInRichTextRun(RichTextRun run, String s) {
{
// Figure out which run it is // Figure out which run it is
int runID = -1; int runID = -1;
for (int i = 0; i < _rtRuns.length; i++) for (int i = 0; i < _rtRuns.length; i++) {
{ if (run.equals(_rtRuns[i])) {
if (run.equals(_rtRuns[i]))
{
runID = i; runID = i;
} }
} }
if (runID == -1) if (runID == -1) {
{
throw new IllegalArgumentException("Supplied RichTextRun wasn't from this TextRun"); throw new IllegalArgumentException("Supplied RichTextRun wasn't from this TextRun");
} }
...@@ -452,25 +396,18 @@ public final class TextRun ...@@ -452,25 +396,18 @@ public final class TextRun
TextPropCollection pCol = run._getRawParagraphStyle(); TextPropCollection pCol = run._getRawParagraphStyle();
TextPropCollection cCol = run._getRawCharacterStyle(); TextPropCollection cCol = run._getRawCharacterStyle();
int newSize = s.length(); int newSize = s.length();
if (runID == _rtRuns.length - 1) if (runID == _rtRuns.length - 1) {
{
newSize++; newSize++;
} }
if (run._isParagraphStyleShared()) if (run._isParagraphStyleShared()) {
{
pCol.updateTextSize(pCol.getCharactersCovered() - run.getLength() + s.length()); pCol.updateTextSize(pCol.getCharactersCovered() - run.getLength() + s.length());
} } else {
else
{
pCol.updateTextSize(newSize); pCol.updateTextSize(newSize);
} }
if (run._isCharacterStyleShared()) if (run._isCharacterStyleShared()) {
{
cCol.updateTextSize(cCol.getCharactersCovered() - run.getLength() + s.length()); cCol.updateTextSize(cCol.getCharactersCovered() - run.getLength() + s.length());
} } else {
else
{
cCol.updateTextSize(newSize); cCol.updateTextSize(newSize);
} }
...@@ -478,30 +415,23 @@ public final class TextRun ...@@ -478,30 +415,23 @@ public final class TextRun
// As we go through, update the start position for all subsequent runs // As we go through, update the start position for all subsequent runs
// The building relies on the old text still being present // The building relies on the old text still being present
StringBuffer newText = new StringBuffer(); StringBuffer newText = new StringBuffer();
for (int i = 0; i < _rtRuns.length; i++) for (int i = 0; i < _rtRuns.length; i++) {
{
int newStartPos = newText.length(); int newStartPos = newText.length();
// Build up the new text // Build up the new text
if (i != runID) if (i != runID) {
{
// Not the affected run, so keep old text // Not the affected run, so keep old text
newText.append(_rtRuns[i].getRawText()); newText.append(_rtRuns[i].getRawText());
} } else {
else
{
// Affected run, so use new text // Affected run, so use new text
newText.append(s); newText.append(s);
} }
// Do we need to update the start position of this run? // Do we need to update the start position of this run?
// (Need to get the text before we update the start pos) // (Need to get the text before we update the start pos)
if (i <= runID) if (i <= runID) {
{
// Change is after this, so don't need to change start position // Change is after this, so don't need to change start position
} } else {
else
{
// Change has occured, so update start position // Change has occured, so update start position
_rtRuns[i].updateStartPosition(newStartPos); _rtRuns[i].updateStartPosition(newStartPos);
} }
...@@ -513,18 +443,16 @@ public final class TextRun ...@@ -513,18 +443,16 @@ public final class TextRun
/** /**
* Changes the text, and sets it all to have the same styling * Changes the text, and sets it all to have the same styling
* as the the first character has. * as the the first character has.
* If you care about styling, do setText on a RichTextRun instead * If you care about styling, do setText on a RichTextRun instead
*/ */
public void setRawText(String s) public void setRawText(String s) {
{
// Save the new text to the atoms // Save the new text to the atoms
storeText(s); storeText(s);
RichTextRun fst = _rtRuns[0]; RichTextRun fst = _rtRuns[0];
// Finally, zap and re-do the RichTextRuns // Finally, zap and re-do the RichTextRuns
for (int i = 0; i < _rtRuns.length; i++) for (int i = 0; i < _rtRuns.length; i++) {
{
_rtRuns[i] = null; _rtRuns[i] = null;
} }
_rtRuns = new RichTextRun[1]; _rtRuns = new RichTextRun[1];
...@@ -535,24 +463,19 @@ public final class TextRun ...@@ -535,24 +463,19 @@ public final class TextRun
// no change, stays with no styling // no change, stays with no styling
// If there is styling: // If there is styling:
// everthing gets the same style that the first block has // everthing gets the same style that the first block has
if (_styleAtom != null) if (_styleAtom != null) {
{
LinkedList pStyles = _styleAtom.getParagraphStyles(); LinkedList pStyles = _styleAtom.getParagraphStyles();
while (pStyles.size() > 1) while (pStyles.size() > 1) {
{
pStyles.removeLast(); pStyles.removeLast();
} }
LinkedList cStyles = _styleAtom.getCharacterStyles(); LinkedList cStyles = _styleAtom.getCharacterStyles();
while (cStyles.size() > 1) while (cStyles.size() > 1) {
{
cStyles.removeLast(); cStyles.removeLast();
} }
_rtRuns[0].setText(s); _rtRuns[0].setText(s);
} } else {
else
{
// Recreate rich text run with no styling // Recreate rich text run with no styling
_rtRuns[0] = new RichTextRun(this, 0, s.length()); _rtRuns[0] = new RichTextRun(this, 0, s.length());
} }
...@@ -563,20 +486,17 @@ public final class TextRun ...@@ -563,20 +486,17 @@ public final class TextRun
* Changes the text. * Changes the text.
* Converts '\r' into '\n' * Converts '\r' into '\n'
*/ */
public void setText(String s) public void setText(String s) {
{
String text = normalize(s); String text = normalize(s);
setRawText(text); setRawText(text);
} }
/** /**
* Ensure a StyleTextPropAtom is present for this run, * Ensure a StyleTextPropAtom is present for this run,
* by adding if required. Normally for internal TextRun use. * by adding if required. Normally for internal TextRun use.
*/ */
public void ensureStyleAtomPresent() public void ensureStyleAtomPresent() {
{ if (_styleAtom != null) {
if (_styleAtom != null)
{
// All there // All there
return; return;
} }
...@@ -589,21 +509,19 @@ public final class TextRun ...@@ -589,21 +509,19 @@ public final class TextRun
// Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom // Add the new StyleTextPropAtom after the TextCharsAtom / TextBytesAtom
Record addAfter = _byteAtom; Record addAfter = _byteAtom;
if (_byteAtom == null) if (_byteAtom == null) {
{
addAfter = _charAtom; addAfter = _charAtom;
} }
runAtomsParent.addChildAfter(_styleAtom, addAfter); runAtomsParent.addChildAfter(_styleAtom, addAfter);
// Feed this to our sole rich text run // Feed this to our sole rich text run
if (_rtRuns.length != 1) if (_rtRuns.length != 1) {
{
throw new IllegalStateException( throw new IllegalStateException(
"Needed to add StyleTextPropAtom when had many rich text runs"); "Needed to add StyleTextPropAtom when had many rich text runs");
} }
// These are the only styles for now // These are the only styles for now
_rtRuns[0].supplyTextProps((TextPropCollection)_styleAtom.getParagraphStyles().get(0), _rtRuns[0].supplyTextProps((TextPropCollection) _styleAtom.getParagraphStyles().get(0),
(TextPropCollection)_styleAtom.getCharacterStyles().get(0), false, false); (TextPropCollection) _styleAtom.getCharacterStyles().get(0), false, false);
} }
// Accesser methods follow // Accesser methods follow
...@@ -612,8 +530,7 @@ public final class TextRun ...@@ -612,8 +530,7 @@ public final class TextRun
* Returns the text content of the run, which has been made safe * Returns the text content of the run, which has been made safe
* for printing and other use. * for printing and other use.
*/ */
public String getText() public String getText() {
{
String rawText = getRawText(); String rawText = getRawText();
// PowerPoint seems to store files with \r as the line break // PowerPoint seems to store files with \r as the line break
...@@ -631,19 +548,17 @@ public final class TextRun ...@@ -631,19 +548,17 @@ public final class TextRun
{ {
text = text.replace((char)0x0B, ' '); text = text.replace((char)0x0B, ' ');
}*/ }*/
text = text.replace((char)0x0B, '\u000b'); text = text.replace((char) 0x0B, '\u000b');
return text; return text;
} }
/** /**
* Returns the raw text content of the run. This hasn't had any * Returns the raw text content of the run. This hasn't had any
* changes applied to it, and so is probably unlikely to print * changes applied to it, and so is probably unlikely to print
* out nicely. * out nicely.
*/ */
public String getRawText() public String getRawText() {
{ if (_isUnicode) {
if (_isUnicode)
{
return _charAtom.getText(); return _charAtom.getText();
} }
return _byteAtom.getText(); return _byteAtom.getText();
...@@ -651,31 +566,30 @@ public final class TextRun ...@@ -651,31 +566,30 @@ public final class TextRun
/** /**
* Fetch the rich text runs (runs of text with the same styling) that * Fetch the rich text runs (runs of text with the same styling) that
* are contained within this block of text * are contained within this block of text
*/ */
public RichTextRun[] getRichTextRuns() public RichTextRun[] getRichTextRuns() {
{
return _rtRuns; return _rtRuns;
} }
/** /**
* Returns the type of the text, from the TextHeaderAtom. * Returns the type of the text, from the TextHeaderAtom.
* Possible values can be seen from TextHeaderAtom * Possible values can be seen from TextHeaderAtom
* @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom *
*/ * @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom
public int getRunType() */
{ public int getRunType() {
return _headerAtom.getTextType(); return _headerAtom.getTextType();
} }
/** /**
* Changes the type of the text. Values should be taken * Changes the type of the text. Values should be taken
* from TextHeaderAtom. No checking is done to ensure you * from TextHeaderAtom. No checking is done to ensure you
* set this to a valid value! * set this to a valid value!
* @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom *
*/ * @see com.cherry.lib.doc.office.fc.hslf.record.TextHeaderAtom
public void setRunType(int type) */
{ public void setRunType(int type) {
_headerAtom.setTextType(type); _headerAtom.setTextType(type);
} }
...@@ -683,57 +597,48 @@ public final class TextRun ...@@ -683,57 +597,48 @@ public final class TextRun
* Supply the SlideShow we belong to. * Supply the SlideShow we belong to.
* Also passes it on to our child RichTextRuns * Also passes it on to our child RichTextRuns
*/ */
public void supplySlideShow(SlideShow ss) public void supplySlideShow(SlideShow ss) {
{
slideShow = ss; slideShow = ss;
if (_rtRuns != null) if (_rtRuns != null) {
{ for (int i = 0; i < _rtRuns.length; i++) {
for (int i = 0; i < _rtRuns.length; i++)
{
_rtRuns[i].supplySlideShow(slideShow); _rtRuns[i].supplySlideShow(slideShow);
} }
} }
} }
public void setSheet(Sheet sheet) public void setSheet(Sheet sheet) {
{
this._sheet = sheet; this._sheet = sheet;
} }
public Sheet getSheet() public Sheet getSheet() {
{
return this._sheet; return this._sheet;
} }
/** /**
* @return Shape ID * @return Shape ID
*/ */
protected int getShapeId() protected int getShapeId() {
{
return shapeId; return shapeId;
} }
/** /**
* @param id Shape ID * @param id Shape ID
*/ */
protected void setShapeId(int id) protected void setShapeId(int id) {
{
shapeId = id; shapeId = id;
} }
/** /**
* @return 0-based index of the text run in the SLWT container * @return 0-based index of the text run in the SLWT container
*/ */
protected int getIndex() protected int getIndex() {
{
return slwtIndex; return slwtIndex;
} }
/** /**
* @param id 0-based index of the text run in the SLWT container * @param id 0-based index of the text run in the SLWT container
*/ */
protected void setIndex(int id) protected void setIndex(int id) {
{
slwtIndex = id; slwtIndex = id;
} }
...@@ -743,8 +648,7 @@ public final class TextRun ...@@ -743,8 +648,7 @@ public final class TextRun
* @return the array of all hyperlinks in this text run * @return the array of all hyperlinks in this text run
* or <code>null</code> if not found. * or <code>null</code> if not found.
*/ */
public Hyperlink[] getHyperlinks() public Hyperlink[] getHyperlinks() {
{
return Hyperlink.find(this); return Hyperlink.find(this);
} }
...@@ -754,10 +658,8 @@ public final class TextRun ...@@ -754,10 +658,8 @@ public final class TextRun
* @param pos 0-based index in the text * @param pos 0-based index in the text
* @return RichTextRun or null if not found * @return RichTextRun or null if not found
*/ */
public RichTextRun getRichTextRunAt(int pos) public RichTextRun getRichTextRunAt(int pos) {
{ for (int i = 0; i < _rtRuns.length; i++) {
for (int i = 0; i < _rtRuns.length; i++)
{
int start = _rtRuns[i].getStartIndex(); int start = _rtRuns[i].getStartIndex();
int end = _rtRuns[i].getEndIndex(); int end = _rtRuns[i].getEndIndex();
if (pos >= start && pos < end) if (pos >= start && pos < end)
...@@ -766,16 +668,12 @@ public final class TextRun ...@@ -766,16 +668,12 @@ public final class TextRun
return null; return null;
} }
public TextRulerAtom getTextRuler() public TextRulerAtom getTextRuler() {
{ if (_ruler == null) {
if (_ruler == null)
{
if (_records != null) if (_records != null)
for (int i = 0; i < _records.length; i++) for (int i = 0; i < _records.length; i++) {
{ if (_records[i] instanceof TextRulerAtom) {
if (_records[i] instanceof TextRulerAtom) _ruler = (TextRulerAtom) _records[i];
{
_ruler = (TextRulerAtom)_records[i];
break; break;
} }
} }
...@@ -785,11 +683,9 @@ public final class TextRun ...@@ -785,11 +683,9 @@ public final class TextRun
} }
public TextRulerAtom createTextRuler() public TextRulerAtom createTextRuler() {
{
_ruler = getTextRuler(); _ruler = getTextRuler();
if (_ruler == null) if (_ruler == null) {
{
_ruler = TextRulerAtom.getParagraphInstance(); _ruler = TextRulerAtom.getParagraphInstance();
_headerAtom.getParentRecord().appendChildRecord(_ruler); _headerAtom.getParentRecord().appendChildRecord(_ruler);
} }
...@@ -799,8 +695,7 @@ public final class TextRun ...@@ -799,8 +695,7 @@ public final class TextRun
/** /**
* Returns a new string with line breaks converted into internal ppt representation * Returns a new string with line breaks converted into internal ppt representation
*/ */
public String normalize(String s) public String normalize(String s) {
{
String ns = s.replaceAll("\\r?\\n", "\r"); String ns = s.replaceAll("\\r?\\n", "\r");
return ns; return ns;
} }
...@@ -810,46 +705,39 @@ public final class TextRun ...@@ -810,46 +705,39 @@ public final class TextRun
* *
* @return text run records * @return text run records
*/ */
public Record[] getRecords() public Record[] getRecords() {
{
return _records; return _records;
} }
/** /**
*
* @return * @return
*/ */
public ExtendedParagraphAtom getExtendedParagraphAtom() public ExtendedParagraphAtom getExtendedParagraphAtom() {
{
return _extendedParagraphAtom; return _extendedParagraphAtom;
} }
/** /**
* get bullet and number ruler * get bullet and number ruler
*
* @param extendedParaAtom * @param extendedParaAtom
*/ */
public void setExtendedParagraphAtom(ExtendedParagraphAtom extendedParaAtom) public void setExtendedParagraphAtom(ExtendedParagraphAtom extendedParaAtom) {
{
_extendedParagraphAtom = extendedParaAtom; _extendedParagraphAtom = extendedParaAtom;
} }
/** /**
* get number type * get number type
*
* @return * @return
*/ */
public int getNumberingType(int characterIndex) public int getNumberingType(int characterIndex) {
{ if (_extendedParagraphAtom != null) {
if (_extendedParagraphAtom != null)
{
int index = getAutoNumberIndex(characterIndex); int index = getAutoNumberIndex(characterIndex);
if (index >= 0) if (index >= 0) {
{ LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList();
LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList(); if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size()) {
if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size())
{
AutoNumberTextProp paraProp = paraPropList.get(index); AutoNumberTextProp paraProp = paraPropList.get(index);
if (paraProp != null) if (paraProp != null) {
{
return paraProp.getNumberingType(); return paraProp.getNumberingType();
} }
} }
...@@ -857,24 +745,20 @@ public final class TextRun ...@@ -857,24 +745,20 @@ public final class TextRun
} }
return -1; return -1;
} }
/** /**
* get number start * get number start
*
* @return * @return
*/ */
public int getNumberingStart(int characterIndex) public int getNumberingStart(int characterIndex) {
{ if (_extendedParagraphAtom != null) {
if (_extendedParagraphAtom != null)
{
int index = getAutoNumberIndex(characterIndex); int index = getAutoNumberIndex(characterIndex);
if (index >= 0) if (index >= 0) {
{ LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList();
LinkedList<AutoNumberTextProp> paraPropList = _extendedParagraphAtom.getExtendedParagraphPropList(); if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size()) {
if (paraPropList != null && paraPropList.size() > 0 && index < paraPropList.size())
{
AutoNumberTextProp paraProp = paraPropList.get(index); AutoNumberTextProp paraProp = paraPropList.get(index);
if (paraProp != null) if (paraProp != null) {
{
return paraProp.getStart(); return paraProp.getStart();
} }
} }
...@@ -882,23 +766,18 @@ public final class TextRun ...@@ -882,23 +766,18 @@ public final class TextRun
} }
return 0; return 0;
} }
/** /**
* charcater startoffset * charcater startoffset
* @param charcterIndex *
* @return * @return
*/ */
public int getAutoNumberIndex(int characterIndex) public int getAutoNumberIndex(int characterIndex) {
{ if (_records != null) {
if (_records != null) for (int i = 0; i < _records.length; i++) {
{ if (_records[i] instanceof StyleTextPropAtom) {
for (int i = 0; i < _records.length; i++) StyleTextPropAtom stp = (StyleTextPropAtom) _records[i];
{ if (stp != null) {
if (_records[i] instanceof StyleTextPropAtom)
{
StyleTextPropAtom stp = (StyleTextPropAtom)_records[i];
if (stp != null)
{
return stp.getAutoNumberIndex(characterIndex); return stp.getAutoNumberIndex(characterIndex);
} }
} }
...@@ -906,55 +785,46 @@ public final class TextRun ...@@ -906,55 +785,46 @@ public final class TextRun
} }
return -1; return -1;
} }
/** /**
* *
*/ */
public void dispose() public void dispose() {
{
slideShow = null; slideShow = null;
_sheet = null; _sheet = null;
if (_headerAtom != null) if (_headerAtom != null) {
{
_headerAtom.dispose(); _headerAtom.dispose();
_headerAtom = null; _headerAtom = null;
} }
if (_byteAtom != null) if (_byteAtom != null) {
{
_byteAtom.dispose(); _byteAtom.dispose();
_byteAtom = null; _byteAtom = null;
} }
if (_charAtom != null) if (_charAtom != null) {
{
_charAtom.dispose(); _charAtom.dispose();
_charAtom = null; _charAtom = null;
} }
if (_styleAtom != null) if (_styleAtom != null) {
{
_styleAtom.dispose(); _styleAtom.dispose();
_styleAtom = null; _styleAtom = null;
} }
if (_ruler != null) if (_ruler != null) {
{
_ruler.dispose(); _ruler.dispose();
_ruler = null; _ruler = null;
} }
if (_extendedParagraphAtom != null) if (_extendedParagraphAtom != null) {
{
_extendedParagraphAtom.dispose(); _extendedParagraphAtom.dispose();
_extendedParagraphAtom = null; _extendedParagraphAtom = null;
} }
if (_rtRuns != null) if (_rtRuns != null) {
{ for (RichTextRun rt : _rtRuns) {
for (RichTextRun rt : _rtRuns)
{
rt.dispose(); rt.dispose();
} }
_rtRuns = null; _rtRuns = null;
} }
} }
// Note: These fields are protected to help with unit testing // Note: These fields are protected to help with unit testing
// Other classes shouldn't really go playing with them! // Other classes shouldn't really go playing with them!
protected TextHeaderAtom _headerAtom; protected TextHeaderAtom _headerAtom;
......
...@@ -29,7 +29,6 @@ import com.cherry.lib.doc.office.system.SysKit; ...@@ -29,7 +29,6 @@ import com.cherry.lib.doc.office.system.SysKit;
import com.cherry.lib.doc.office.system.beans.pagelist.APageListItem; import com.cherry.lib.doc.office.system.beans.pagelist.APageListItem;
import com.cherry.lib.doc.office.system.beans.pagelist.APageListView; import com.cherry.lib.doc.office.system.beans.pagelist.APageListView;
import com.cherry.lib.doc.office.system.beans.pagelist.IPageListViewListener; import com.cherry.lib.doc.office.system.beans.pagelist.IPageListViewListener;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
...@@ -275,8 +274,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener ...@@ -275,8 +274,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
} }
/** /**
* @param x 为100%的值
* @param y 为100%的值
* / * /
public long viewToModel(int x, int y, boolean isBack) public long viewToModel(int x, int y, boolean isBack)
{ {
...@@ -484,7 +481,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener ...@@ -484,7 +481,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
/** /**
* page list view moving position * page list view moving position
* @param position horizontal or vertical
*/ */
public int getPageListViewMovingPosition() public int getPageListViewMovingPosition()
{ {
...@@ -515,7 +511,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener ...@@ -515,7 +511,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
* @param e2 MotionEvent instance * @param e2 MotionEvent instance
* @param velocityX x axis velocity * @param velocityX x axis velocity
* @param velocityY y axis velocity * @param velocityY y axis velocity
* @param eventNethodType event method
* @see IMainFrame#ON_CLICK * @see IMainFrame#ON_CLICK
* @see IMainFrame#ON_DOUBLE_TAP * @see IMainFrame#ON_DOUBLE_TAP
* @see IMainFrame#ON_DOUBLE_TAP_EVENT * @see IMainFrame#ON_DOUBLE_TAP_EVENT
...@@ -653,7 +648,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener ...@@ -653,7 +648,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
/** /**
* 绘制页信息 * 绘制页信息
* @param canvas * @param canvas
* @param zoom
*/ */
private void drawPageNubmer(Canvas canvas) private void drawPageNubmer(Canvas canvas)
{ {
...@@ -692,8 +686,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener ...@@ -692,8 +686,6 @@ public class PGPrintMode extends FrameLayout implements IPageListViewListener
* set change page flag, Only when effectively the PageSize greater than ViewSize. * set change page flag, Only when effectively the PageSize greater than ViewSize.
* (for PPT, word print mode, PDF) * (for PPT, word print mode, PDF)
* *
* @param b = true, change page
* = false, don't change page
*/ */
public boolean isChangePage() public boolean isChangePage()
{ {
......
...@@ -7,14 +7,12 @@ import android.view.View ...@@ -7,14 +7,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.AlphaAnimation import android.view.animation.AlphaAnimation
import android.view.animation.LinearInterpolator import android.view.animation.LinearInterpolator
import android.widget.Toast import android.widget.ImageView
import androidx.core.view.updateLayoutParams import android.widget.ProgressBar
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.cherry.lib.doc.R import com.cherry.lib.doc.R
import com.cherry.lib.doc.util.ViewUtils.hide import com.cherry.lib.doc.util.ViewUtils.hide
import com.cherry.lib.doc.util.ViewUtils.show import com.cherry.lib.doc.util.ViewUtils.show
import kotlinx.android.synthetic.main.page_item_pdf.view.*
import kotlinx.android.synthetic.main.pdf_view_page_loading_layout.view.*
/* /*
* ----------------------------------------------------------------- * -----------------------------------------------------------------
...@@ -31,13 +29,14 @@ internal class PdfPageViewAdapter( ...@@ -31,13 +29,14 @@ internal class PdfPageViewAdapter(
private val renderer: PdfRendererCore?, private val renderer: PdfRendererCore?,
private val pageSpacing: Rect, private val pageSpacing: Rect,
private val enableLoadingForPages: Boolean private val enableLoadingForPages: Boolean
) : ) : RecyclerView.Adapter<PdfPageViewAdapter.PdfPageViewHolder>() {
RecyclerView.Adapter<PdfPageViewAdapter.PdfPageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder {
return PdfPageViewHolder( return PdfPageViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.page_item_pdf,parent, LayoutInflater.from(parent.context).inflate(
false) R.layout.page_item_pdf, parent,
false
)
) )
} }
...@@ -49,21 +48,22 @@ internal class PdfPageViewAdapter( ...@@ -49,21 +48,22 @@ internal class PdfPageViewAdapter(
holder.bindView() holder.bindView()
} }
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),View.OnAttachStateChangeListener {
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnAttachStateChangeListener {
fun bindView() { fun bindView() {
} }
private fun handleLoadingForPage(position: Int) { private fun handleLoadingForPage(position: Int) {
val progressBar = itemView.findViewById<ProgressBar>(R.id.pdf_view_page_loading_progress)
if (!enableLoadingForPages) { if (!enableLoadingForPages) {
itemView.pdf_view_page_loading_progress.hide() progressBar.hide()
return return
} }
if (renderer?.pageExistInCache(position) == true) { if (renderer?.pageExistInCache(position) == true) {
itemView.pdf_view_page_loading_progress.hide() progressBar.hide()
} else { } else {
itemView.pdf_view_page_loading_progress.show() progressBar.show()
} }
} }
...@@ -84,20 +84,22 @@ internal class PdfPageViewAdapter( ...@@ -84,20 +84,22 @@ internal class PdfPageViewAdapter(
// this.rightMargin = pageSpacing.right // this.rightMargin = pageSpacing.right
// this.bottomMargin = pageSpacing.bottom // this.bottomMargin = pageSpacing.bottom
// } // }
itemView.pageView.setImageBitmap(bitmap) val pageView = itemView.findViewById<ImageView>(R.id.pageView)
itemView.pageView.animation = AlphaAnimation(0F, 1F).apply { pageView.setImageBitmap(bitmap)
pageView.animation = AlphaAnimation(0F, 1F).apply {
interpolator = LinearInterpolator() interpolator = LinearInterpolator()
duration = 200 duration = 200
} }
itemView.pdf_view_page_loading_progress.hide() itemView.findViewById<ProgressBar>(R.id.pdf_view_page_loading_progress).hide()
} }
} }
} }
} }
override fun onViewDetachedFromWindow(p0: View) { override fun onViewDetachedFromWindow(p0: View) {
itemView.pageView.setImageBitmap(null) val pageView = itemView.findViewById<ImageView>(R.id.pageView)
itemView.pageView.clearAnimation() pageView.setImageBitmap(null)
pageView.clearAnimation()
} }
} }
} }
\ No newline at end of file
...@@ -14,12 +14,10 @@ import android.widget.Toast ...@@ -14,12 +14,10 @@ import android.widget.Toast
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.cherry.lib.doc.R import com.cherry.lib.doc.R
import com.cherry.lib.doc.databinding.ListItemPdfBinding
import com.cherry.lib.doc.interfaces.OnPdfItemClickListener import com.cherry.lib.doc.interfaces.OnPdfItemClickListener
import com.cherry.lib.doc.util.ViewUtils.hide import com.cherry.lib.doc.util.ViewUtils.hide
import com.cherry.lib.doc.util.ViewUtils.show import com.cherry.lib.doc.util.ViewUtils.show
import kotlinx.android.synthetic.main.doc_view.view.mIvPdf
import kotlinx.android.synthetic.main.list_item_pdf.view.*
import kotlinx.android.synthetic.main.pdf_view_page_loading_layout.view.*
/* /*
* ----------------------------------------------------------------- * -----------------------------------------------------------------
...@@ -41,8 +39,10 @@ internal class PdfViewAdapter( ...@@ -41,8 +39,10 @@ internal class PdfViewAdapter(
RecyclerView.Adapter<PdfViewAdapter.PdfPageViewHolder>() { RecyclerView.Adapter<PdfViewAdapter.PdfPageViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PdfPageViewHolder {
return PdfPageViewHolder( return PdfPageViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.list_item_pdf,parent, LayoutInflater.from(parent.context).inflate(
false) R.layout.list_item_pdf, parent,
false
)
) )
} }
...@@ -59,24 +59,24 @@ internal class PdfViewAdapter( ...@@ -59,24 +59,24 @@ internal class PdfViewAdapter(
holder.bindView() holder.bindView()
} }
inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),View.OnAttachStateChangeListener { inner class PdfPageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnAttachStateChangeListener {
val binding = ListItemPdfBinding.bind(itemView)
fun bindView() { fun bindView() {
itemView.container_view.setOnClickListener { binding.containerView.setOnClickListener {
listener?.OnPdfItemClick(adapterPosition) listener?.OnPdfItemClick(adapterPosition)
} }
} }
private fun handleLoadingForPage(position: Int) { private fun handleLoadingForPage(position: Int) {
if (!enableLoadingForPages) { if (!enableLoadingForPages) {
itemView.pdf_view_page_loading_progress.hide() binding.include.pdfViewPageLoadingProgress.hide()
return return
} }
if (renderer?.pageExistInCache(position) == true) { if (renderer?.pageExistInCache(position) == true) {
itemView.pdf_view_page_loading_progress.hide() binding.include.pdfViewPageLoadingProgress.hide()
} else { } else {
itemView.pdf_view_page_loading_progress.show() binding.include.pdfViewPageLoadingProgress.show()
} }
} }
...@@ -89,28 +89,28 @@ internal class PdfViewAdapter( ...@@ -89,28 +89,28 @@ internal class PdfViewAdapter(
renderer?.renderPage(adapterPosition) { bitmap: Bitmap?, pageNo: Int -> renderer?.renderPage(adapterPosition) { bitmap: Bitmap?, pageNo: Int ->
if (pageNo == adapterPosition) { if (pageNo == adapterPosition) {
bitmap?.let { bitmap?.let {
itemView.container_view.updateLayoutParams<ViewGroup.MarginLayoutParams> { binding.containerView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = height =
(itemView.container_view.width.toFloat() / ((bitmap.width.toFloat() / bitmap.height.toFloat()))).toInt() (binding.containerView.width.toFloat() / ((bitmap.width.toFloat() / bitmap.height.toFloat()))).toInt()
this.topMargin = pageSpacing.top this.topMargin = pageSpacing.top
this.leftMargin = pageSpacing.left this.leftMargin = pageSpacing.left
this.rightMargin = pageSpacing.right this.rightMargin = pageSpacing.right
this.bottomMargin = pageSpacing.bottom this.bottomMargin = pageSpacing.bottom
} }
itemView.pageView.setImageBitmap(bitmap) binding.pageView.setImageBitmap(bitmap)
itemView.pageView.animation = AlphaAnimation(0F, 1F).apply { binding.pageView.animation = AlphaAnimation(0F, 1F).apply {
interpolator = LinearInterpolator() interpolator = LinearInterpolator()
duration = 200 duration = 200
} }
itemView.pdf_view_page_loading_progress.hide() binding.include.pdfViewPageLoadingProgress.hide()
} }
} }
} }
} }
override fun onViewDetachedFromWindow(p0: View) { override fun onViewDetachedFromWindow(p0: View) {
itemView.pageView.setImageBitmap(null) binding.pageView.setImageBitmap(null)
itemView.pageView.clearAnimation() binding.pageView.clearAnimation()
} }
} }
......
...@@ -4,28 +4,22 @@ import android.annotation.SuppressLint ...@@ -4,28 +4,22 @@ import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.Rect import android.graphics.Rect
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.util.AttributeSet import android.util.AttributeSet
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.MimeTypeMap
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import coil.load import coil.load
import com.blankj.utilcode.util.UriUtils import com.blankj.utilcode.util.UriUtils
...@@ -34,23 +28,13 @@ import com.cherry.lib.doc.bean.DocEngine ...@@ -34,23 +28,13 @@ import com.cherry.lib.doc.bean.DocEngine
import com.cherry.lib.doc.bean.DocMovingOrientation import com.cherry.lib.doc.bean.DocMovingOrientation
import com.cherry.lib.doc.bean.DocSourceType import com.cherry.lib.doc.bean.DocSourceType
import com.cherry.lib.doc.bean.FileType import com.cherry.lib.doc.bean.FileType
import com.cherry.lib.doc.interfaces.OnDownloadListener import com.cherry.lib.doc.databinding.DocViewBinding
import com.cherry.lib.doc.interfaces.OnDocPageChangeListener import com.cherry.lib.doc.interfaces.OnDocPageChangeListener
import com.cherry.lib.doc.interfaces.OnPdfItemClickListener
import com.cherry.lib.doc.interfaces.OnWebLoadListener
import com.cherry.lib.doc.office.IOffice import com.cherry.lib.doc.office.IOffice
import com.cherry.lib.doc.pdf.PdfDownloader
import com.cherry.lib.doc.pdf.PdfPageViewAdapter
import com.cherry.lib.doc.pdf.PdfQuality
import com.cherry.lib.doc.pdf.PdfRendererCore
import com.cherry.lib.doc.pdf.PdfViewAdapter
import com.cherry.lib.doc.util.Constant
import com.cherry.lib.doc.util.FileUtils import com.cherry.lib.doc.util.FileUtils
import com.cherry.lib.doc.util.ViewUtils.hide import com.cherry.lib.doc.util.ViewUtils.hide
import com.cherry.lib.doc.util.ViewUtils.show import com.cherry.lib.doc.util.ViewUtils.show
import kotlinx.android.synthetic.main.doc_view.view.*
import java.io.File import java.io.File
import java.net.URLEncoder
/* /*
* ----------------------------------------------------------------- * -----------------------------------------------------------------
...@@ -63,18 +47,14 @@ import java.net.URLEncoder ...@@ -63,18 +47,14 @@ import java.net.URLEncoder
* ----------------------------------------------------------------- * -----------------------------------------------------------------
*/ */
class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClickListener { class DocView : FrameLayout {
private val TAG = "DocView" private val TAG = "DocView"
var mActivity: Activity? = null var mActivity: Activity? = null
var lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope var lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope
private var mPoiViewer:PoiViewer? = null private var mPoiViewer: PoiViewer? = null
private var pdfRendererCore: PdfRendererCore? = null
private var pdfViewAdapter: PdfViewAdapter? = null
private var pdfPageViewAdapter: PdfPageViewAdapter? = null
private var mMovingOrientation = DocMovingOrientation.HORIZONTAL private var mMovingOrientation = DocMovingOrientation.HORIZONTAL
private var quality = PdfQuality.NORMAL
private var engine = DocEngine.INTERNAL private var engine = DocEngine.INTERNAL
private var showDivider = true private var showDivider = true
private var showPageNum = true private var showPageNum = true
...@@ -87,7 +67,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -87,7 +67,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
var pbColor: Int = pbDefaultColor var pbColor: Int = pbDefaultColor
private var pdfRendererCoreInitialised = false private var pdfRendererCoreInitialised = false
var pageMargin: Rect = Rect(0,0,0,0) var pageMargin: Rect = Rect(0, 0, 0, 0)
var totalPageCount = 0 var totalPageCount = 0
...@@ -102,11 +82,13 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -102,11 +82,13 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
initView(attrs, defStyle) initView(attrs, defStyle)
} }
private lateinit var binding: DocViewBinding
fun initView(attrs: AttributeSet?, defStyle: Int) { fun initView(attrs: AttributeSet?, defStyle: Int) {
inflate(context, R.layout.doc_view, this) inflate(context, R.layout.doc_view, this)
binding = DocViewBinding.bind(this)
mIvPdf.setOnClickListener { binding.mIvPdf.setOnClickListener {
mLlBigPdfImage.hide() binding.mLlBigPdfImage.hide()
} }
val typedArray = val typedArray =
...@@ -114,9 +96,6 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -114,9 +96,6 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
val orientation = val orientation =
typedArray.getInt(R.styleable.DocView_dv_moving_orientation, DocMovingOrientation.HORIZONTAL.orientation) typedArray.getInt(R.styleable.DocView_dv_moving_orientation, DocMovingOrientation.HORIZONTAL.orientation)
mMovingOrientation = DocMovingOrientation.values().first { it.orientation == orientation } mMovingOrientation = DocMovingOrientation.values().first { it.orientation == orientation }
val ratio =
typedArray.getInt(R.styleable.DocView_dv_quality, PdfQuality.NORMAL.ratio)
quality = PdfQuality.values().first { it.ratio == ratio }
val engineValue = val engineValue =
typedArray.getInt(R.styleable.DocView_dv_engine, DocEngine.INTERNAL.value) typedArray.getInt(R.styleable.DocView_dv_engine, DocEngine.INTERNAL.value)
engine = DocEngine.values().first { it.value == engineValue } engine = DocEngine.values().first { it.value == engineValue }
...@@ -135,31 +114,33 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -135,31 +114,33 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
bottom = typedArray.getDimensionPixelSize(R.styleable.DocView_dv_page_marginBottom, bottom) bottom = typedArray.getDimensionPixelSize(R.styleable.DocView_dv_page_marginBottom, bottom)
} }
var layoutParams = mPlLoadProgress.layoutParams binding.mPdfPageNo.isVisible = showPageNum
val layoutParams = binding.mPlLoadProgress.layoutParams
layoutParams.height = pbHeight layoutParams.height = pbHeight
mPlLoadProgress.layoutParams = layoutParams binding.mPlLoadProgress.layoutParams = layoutParams
mPlLoadProgress.progressTintList = ColorStateList.valueOf(pbColor) binding.mPlLoadProgress.progressTintList = ColorStateList.valueOf(pbColor)
typedArray.recycle() typedArray.recycle()
runnable = Runnable {
mPdfPageNo.hide()
}
} }
fun openDoc(activity: Activity, docUrl: String?, docSourceType: Int, fun openDoc(
engine: DocEngine = this.engine) { activity: Activity, docUrl: String?, docSourceType: Int,
engine: DocEngine = this.engine
) {
mActivity = activity mActivity = activity
openDoc(activity, docUrl, docSourceType,-1,false,engine) openDoc(activity, docUrl, docSourceType, -1, false, engine)
} }
fun openDoc(activity: Activity?, docUrl: String?, @SuppressLint("ObsoleteSdkInt")
docSourceType: Int, fileType: Int, fun openDoc(
viewPdfInPage: Boolean = false, activity: Activity?, docUrl: String?,
engine: DocEngine = this.engine) { docSourceType: Int, fileType: Int,
viewPdfInPage: Boolean = false,
engine: DocEngine = this.engine
) {
var fileType = fileType var fileType = fileType
var docUrl = docUrl var docUrl = docUrl
var docSourceType = docSourceType var docSourceType = docSourceType
...@@ -184,7 +165,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -184,7 +165,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
Log.d(TAG, "file = null") Log.d(TAG, "file = null")
} }
} }
Log.e(TAG,"openDoc()......fileType = $fileType") Log.e(TAG, "openDoc()......fileType = $fileType")
mActivity = activity mActivity = activity
mViewPdfInPage = viewPdfInPage mViewPdfInPage = viewPdfInPage
if (docSourceType == DocSourceType.PATH) { if (docSourceType == DocSourceType.PATH) {
...@@ -192,77 +173,54 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -192,77 +173,54 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
} else { } else {
sourceFilePath = null sourceFilePath = null
} }
if (docSourceType == DocSourceType.URL && fileType != FileType.IMAGE) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP
|| engine == DocEngine.MICROSOFT
|| engine == DocEngine.XDOC
|| engine == DocEngine.GOOGLE) {
showByWeb(docUrl ?: "",engine)
return
}
downloadFile(docUrl ?: "")
return
}
var type = FileUtils.getFileTypeForUrl(docUrl) var type = FileUtils.getFileTypeForUrl(docUrl)
if (fileType > 0) { if (fileType > 0) {
type = fileType type = fileType
} }
when (type) { when (type) {
FileType.PDF -> { FileType.PDF -> {
Log.e(TAG,"openDoc()......PDF") Log.e(TAG, "openDoc()......PDF")
mDocWeb.hide() // binding.mDocWeb.hide()
mFlDocContainer.hide() binding.mFlDocContainer.hide()
mRvPdf.show() binding.mIvImage.hide()
mIvImage.hide()
showPdf(docSourceType,docUrl)
} }
FileType.IMAGE -> { FileType.IMAGE -> {
if (showPageNum) { if (showPageNum) {
showPageNum = false showPageNum = false
} }
Log.e(TAG,"openDoc()......") Log.e(TAG, "openDoc()......")
mDocWeb.hide() // binding.mDocWeb.hide()
mFlDocContainer.hide() binding.mFlDocContainer.hide()
mRvPdf.hide() binding.mIvImage.show()
mIvImage.show()
if (docSourceType == DocSourceType.PATH) { if (docSourceType == DocSourceType.PATH) {
Log.e(TAG,"openDoc()......PATH") Log.e(TAG, "openDoc()......PATH")
mIvImage.load(File(docUrl)) binding.mIvImage.load(File(docUrl))
} else { } else {
Log.e(TAG,"openDoc()......URL") Log.e(TAG, "openDoc()......URL")
mIvImage.load(docUrl) binding.mIvImage.load(docUrl)
} }
} }
FileType.NOT_SUPPORT -> { FileType.NOT_SUPPORT -> {
if (showPageNum) {
showPageNum = false
}
Log.e(TAG,"openDoc()......NOT_SUPPORT")
mDocWeb.show()
mFlDocContainer.hide()
mRvPdf.hide()
mIvImage.hide()
showByWeb(docUrl ?: "",this.engine)
} }
else -> { else -> {
Log.e(TAG,"openDoc()......ELSE") Log.e(TAG, "openDoc()......ELSE")
if (showPageNum) { if (showPageNum) {
showPageNum = false showPageNum = false
} }
mDocWeb.hide() binding.mFlDocContainer.show()
mFlDocContainer.show() binding.mIvImage.hide()
mRvPdf.hide() activity?.let { showDoc(it, binding.mFlDocContainer, docUrl, docSourceType, fileType) }
mIvImage.hide()
activity?.let { showDoc(it,mFlDocContainer,docUrl,docSourceType,fileType) }
} }
} }
} }
fun showDoc(activity: Activity, mDocContainer: ViewGroup?, url: String?, docSourceType: Int, fileType: Int) { fun showDoc(activity: Activity, mDocContainer: ViewGroup?, url: String?, docSourceType: Int, fileType: Int) {
Log.e(TAG,"showDoc()......") Log.e(TAG, "showDoc()......")
var iOffice: IOffice = object: IOffice() { val iOffice: IOffice = object : IOffice() {
override fun getActivity(): Activity { override fun getActivity(): Activity {
return activity return activity
} }
...@@ -277,7 +235,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -277,7 +235,7 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
RelativeLayout.LayoutParams.MATCH_PARENT RelativeLayout.LayoutParams.MATCH_PARENT
) )
) )
},200) }, 200)
} }
override fun openFileFailed() { override fun openFileFailed() {
...@@ -285,7 +243,9 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -285,7 +243,9 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
if (mPoiViewer == null) { if (mPoiViewer == null) {
mPoiViewer = PoiViewer(context) mPoiViewer = PoiViewer(context)
} }
mPoiViewer?.loadFile(mFlDocContainer, sourceFilePath) mPoiViewer?.loadFile(
binding.mFlDocContainer, sourceFilePath
)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
Toast.makeText(context, R.string.open_failed, Toast.LENGTH_SHORT).show() Toast.makeText(context, R.string.open_failed, Toast.LENGTH_SHORT).show()
...@@ -309,185 +269,28 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -309,185 +269,28 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
} }
} }
iOffice.openFile(url,docSourceType, fileType.toString()) //是否绘制页码
} iOffice.isDrawPageNumber
iOffice.openFile(url, docSourceType, fileType.toString())
fun showPdf(docSourceType: Int, url: String?) {
Log.e(TAG,"showPdf()......quality = $quality")
when (docSourceType) {
DocSourceType.URL -> {
Log.e(TAG,"showPdf()......URL")
initWithUrl(url = url ?: "", pdfQuality = quality)
}
DocSourceType.URI -> {
Log.e(TAG,"showPdf()......URI")
initWithUri(fileUri = url ?: "", pdfQuality = quality)
}
DocSourceType.PATH -> {
Log.e(TAG,"showPdf()......PATH")
initWithPath(path = url ?: "", pdfQuality = quality)
}
DocSourceType.ASSETS -> {
Log.e(TAG,"showPdf()......ASSETS")
initWithAssets(fileName = url ?: "", pdfQuality = quality)
}
}
}
private fun showPdf(file: File, pdfQuality: PdfQuality) {
Log.e(javaClass.simpleName,"initView-exists = ${file.exists()}")
Log.e(javaClass.simpleName,"initView-mViewPdfInPage = $mViewPdfInPage")
pdfRendererCore = PdfRendererCore(context, file, pdfQuality)
totalPageCount = pdfRendererCore?.getPageCount() ?: 0
pdfRendererCoreInitialised = true
pdfViewAdapter = PdfViewAdapter(pdfRendererCore, pageMargin, enableLoadingForPages,this)
pdfPageViewAdapter = PdfPageViewAdapter(pdfRendererCore, pageMargin, enableLoadingForPages)
mRvPdf.setEnableScale(true)
if (mViewPdfInPage) {
mRvPdf.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
mRvPdf.adapter = pdfPageViewAdapter
PagerSnapHelper().attachToRecyclerView(mRvPdf)
} else {
mRvPdf.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
mRvPdf.adapter = pdfViewAdapter
}
mRvPdf.itemAnimator = DefaultItemAnimator()
mRvPdf.addOnScrollListener(scrollListener)
if (showDivider && !mViewPdfInPage) {
DividerItemDecoration(context, DividerItemDecoration.VERTICAL).apply {
divider?.let { setDrawable(it) }
}.let { mRvPdf.addItemDecoration(it) }
}
}
fun initWithUrl(
url: String,
pdfQuality: PdfQuality = this.quality,
engine: DocEngine = this.engine,
lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope
) {
this.lifecycleScope = lifecycleScope
downloadFile(url, pdfQuality, lifecycleScope)
}
fun initWithPath(path: String, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
initWithFile(File(path), pdfQuality)
}
fun initWithFile(file: File, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
showPdf(file, pdfQuality)
}
fun initWithAssets(fileName: String, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
val file = FileUtils.fileFromAsset(context,fileName)
showPdf(file, pdfQuality)
}
fun initWithUri(fileUri: String, pdfQuality: PdfQuality = this.quality) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
throw UnsupportedOperationException("should be over API 21")
val file = FileUtils.fileFromUri(context,fileUri)
showPdf(file, pdfQuality)
}
fun downloadFile(url: String, pdfQuality: PdfQuality = this.quality,
lifecycleScope: LifecycleCoroutineScope = (context as AppCompatActivity).lifecycleScope) {
PdfDownloader(url, this)
}
@SuppressLint("SetJavaScriptEnabled")
private fun showByWeb(url: String,engine: DocEngine = this.engine) {
mDocWeb.mOnWebLoadListener = this
var engineUrl = "engine"
when (engine) {
DocEngine.MICROSOFT -> {
engineUrl = Constant.MICROSOFT_URL
}
DocEngine.XDOC -> {
engineUrl = Constant.XDOC_VIEW_URL
}
DocEngine.GOOGLE -> {
engineUrl = Constant.GOOGLE_URL
}
else -> {
engineUrl = Constant.XDOC_VIEW_URL
}
}
mDocWeb.loadUrl("$engineUrl${URLEncoder.encode(url, "UTF-8")}")
}
override fun getDownloadContext() = context
override fun onDownloadStart() {
Log.e(TAG,"initWithUrl-onDownloadStart()......")
}
override fun onDownloadProgress(currentBytes: Long, totalBytes: Long) {
var progress = (currentBytes.toFloat() / totalBytes.toFloat() * 100F).toInt()
if (progress >= 100) {
progress = 100
}
Log.e(TAG,"initWithUrl-onDownloadProgress()......progress = $progress")
showLoadingProgress(progress)
}
override fun onDownloadSuccess(absolutePath: String) {
Log.e(TAG,"initWithUrl-onDownloadSuccess()......")
showLoadingProgress(100)
sourceFilePath = absolutePath
openDoc(mActivity, absolutePath, DocSourceType.PATH,-1,mViewPdfInPage)
}
override fun onError(error: Throwable) {
error.printStackTrace()
Log.e(TAG,"initWithUrl-onError()......${error.localizedMessage}")
showLoadingProgress(100)
}
override fun getCoroutineScope() = lifecycleScope
override fun OnWebLoadProgress(progress: Int) {
showLoadingProgress(progress)
}
override fun onTitle(title: String?) {
} }
fun showLoadingProgress(progress: Int) {
if (progress == 100) {
mPlLoadProgress.hide()
} else {
mPlLoadProgress?.show()
mPlLoadProgress?.progress = progress
}
}
private val scrollListener = object : RecyclerView.OnScrollListener() { private val scrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
(recyclerView.layoutManager as LinearLayoutManager).run { (recyclerView.layoutManager as LinearLayoutManager).run {
var foundPosition : Int = findLastCompletelyVisibleItemPosition() var foundPosition: Int = findLastCompletelyVisibleItemPosition()
if (foundPosition != RecyclerView.NO_POSITION) if (foundPosition != RecyclerView.NO_POSITION)
mPdfPageNo.text = context.getString(R.string.pdfView_page_no,foundPosition + 1,totalPageCount) binding.mPdfPageNo.text = context.getString(R.string.pdfView_page_no, foundPosition + 1, totalPageCount)
if (showPageNum) { if (showPageNum) {
mPdfPageNo.visibility = View.VISIBLE binding.mPdfPageNo.visibility = View.VISIBLE
} }
if (foundPosition == 0 && !mViewPdfInPage) if (foundPosition == 0 && !mViewPdfInPage)
mPdfPageNo.postDelayed({ binding.mPdfPageNo.postDelayed({
mPdfPageNo.visibility = GONE binding.mPdfPageNo.visibility = GONE
}, 3000) }, 3000)
if (foundPosition != RecyclerView.NO_POSITION) { if (foundPosition != RecyclerView.NO_POSITION) {
...@@ -504,10 +307,10 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -504,10 +307,10 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE && !mViewPdfInPage) { if (newState == RecyclerView.SCROLL_STATE_IDLE && !mViewPdfInPage) {
mPdfPageNo.postDelayed(runnable, 3000) binding.mPdfPageNo.postDelayed(runnable, 3000)
} else { } else {
mPdfPageNo.removeCallbacks(runnable) binding.mPdfPageNo.removeCallbacks(runnable)
} }
} }
} }
...@@ -517,33 +320,9 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick ...@@ -517,33 +320,9 @@ class DocView : FrameLayout,OnDownloadListener, OnWebLoadListener,OnPdfItemClick
onDestroy() onDestroy()
} }
fun closePdfRender() {
try {
if (pdfRendererCoreInitialised) {
pdfRendererCore?.closePdfRender()
pdfRendererCoreInitialised = false
}
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun OnPdfItemClick(position: Int) {
mLlBigPdfImage.show()
mPbBigLoading.show()
mIvPdf.setImageBitmap(null)
pdfRendererCore?.renderPage(position,PdfQuality.ENHANCED) { bitmap: Bitmap?, pageNo: Int ->
mPbBigLoading.hide()
mIvPdf.setImageBitmap(bitmap)
mIvPdf.reset()
mPdfPageNo.visibility = GONE
}
}
fun onDestroy() { fun onDestroy() {
mPoiViewer?.recycle() mPoiViewer?.recycle()
closePdfRender()
mOnDocPageChangeListener = null mOnDocPageChangeListener = null
} }
} }
\ No newline at end of file
package com.cherry.lib.doc.widget
import android.annotation.SuppressLint
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Environment
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.webkit.*
import androidx.constraintlayout.widget.ConstraintLayout
import com.cherry.lib.doc.R
import com.cherry.lib.doc.interfaces.OnWebLoadListener
import kotlinx.android.synthetic.main.doc_web_view.view.*
/*
* -----------------------------------------------------------------
* Copyright (C) 2018-2028, by Victor, All rights reserved.
* -----------------------------------------------------------------
* File: ProgressWebView
* Author: Victor
* Date: 2022/3/1 18:28
* Description:
* -----------------------------------------------------------------
*/
class DocWebView : ConstraintLayout, DownloadListener {
val TAG = "DocWebView"
var isLastLoadSuccess = false//是否成功加载完成过web,成功过后的网络异常 不改变web
var isError = false
var openLinkBySysBrowser = false//是否使用系统浏览器打开http链接
var mOnWebLoadListener: OnWebLoadListener? = null
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {
initView()
}
fun initView() {
LayoutInflater.from(context).inflate(R.layout.doc_web_view, this, true)
mDocView.webChromeClient = DocWebChromeClient()
mDocView.webViewClient = DocWebViewClient()
//设置可以支持缩放
mDocView.settings.setSupportZoom(true)
//设置出现缩放工具
mDocView.settings.builtInZoomControls = true
//设定缩放控件隐藏
mDocView.settings.displayZoomControls = true
//设置可在大视野范围内上下左右拖动,并且可以任意比例缩放
mDocView.settings.useWideViewPort = true
//设置默认加载的可视范围是大视野范围
mDocView.settings.loadWithOverviewMode = true
//自适应屏幕 SINGLE_COLUMN:把所有内容放大到webview等宽的一列中 NORMAL:正常显示不做任何渲染。NARROW_COLUMNS:可能的话让所有列的宽度不超过屏幕宽度
mDocView.settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
mDocView.settings.javaScriptEnabled = true
mDocView.settings.domStorageEnabled = true
mDocView.settings.allowFileAccess = true
mDocView.settings.allowFileAccessFromFileURLs = true
mDocView.settings.allowUniversalAccessFromFileURLs = true
mDocView.settings.cacheMode = WebSettings.LOAD_NO_CACHE
mDocView.setDownloadListener(this)
}
private fun setProgress(newProgress: Int) {
mOnWebLoadListener?.OnWebLoadProgress(newProgress)
}
/**
* 千万不要更改这个 "SSDJsBirdge" 注意!!!!!
*/
@SuppressLint("JavascriptInterface")
fun addJavascriptInterface(jsInterface: Any) {
mDocView.addJavascriptInterface(jsInterface, "SSDJsBirdge")
}
fun reload() {
isError = false
mDocView.reload()
}
fun loadUrl(url: String) {
isError = false
try {
mDocView.loadUrl(url)
} catch (e: Exception) {
e.printStackTrace()
}
}
fun loadData(htmlData: String) {
mDocView.loadData(htmlData, "text/html", "utf-8")
}
fun loadData(htmlData: String, secondLinkBySysBrowser: Boolean) {
openLinkBySysBrowser = secondLinkBySysBrowser
mDocView.loadData(htmlData, "text/html", "utf-8")
}
fun downloadFile(url: String?, contentDisposition: String?, mimeType: String?) {
val request = DownloadManager.Request(Uri.parse(url))
// 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
request.allowScanningByMediaScanner()
// 设置通知的显示类型,下载进行时和完成后显示通知
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
// 设置通知栏的标题,如果不设置,默认使用文件名
request.setTitle("下载完成")
// 设置通知栏的描述
// request.setDescription("This is description");
// 允许在计费流量下下载
request.setAllowedOverMetered(true)
// 允许该记录在下载管理界面可见
request.setVisibleInDownloadsUi(true)
// 允许漫游时下载
request.setAllowedOverRoaming(true)
val fileName = URLUtil.guessFileName(url, contentDisposition, mimeType)
Log.e(TAG, "downloadFile()-fileName = $fileName")
request.setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().toString() + "/Download/", fileName)
val downloadManager = mDocView.context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
// 添加一个下载任务
val downloadId = downloadManager.enqueue(request)
}
override fun onDownloadStart(
url: String?,
userAgent: String?,
contentDisposition: String?,
mimeType: String?,
contentLength: Long
) {
Log.e(TAG, "onDownloadStart()......url = $url")
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
context.startActivity(intent)
// downloadFile(url,contentDisposition,mimeType)
}
fun canGoBack(): Boolean {
val canGoBack = mDocView.canGoBack()
if (canGoBack) {
mDocView.goBack()
}
return canGoBack
}
fun onPause() {
mDocView.pauseTimers()
}
fun onResume() {
mDocView.resumeTimers()
}
/**
* must be called on the main thread
*/
fun onDestroy() {
try {
mDocView.clearHistory();
mDocView.clearCache(true)
mDocView.loadUrl("about:blank") // clearView() should be changed to loadUrl("about:blank"), since clearView() is deprecated now
mDocView.freeMemory()
mDocView.pauseTimers()
mDocView.destroy() // Note that mWebView.destroy() and mWebView = null do the exact same thing
} catch (e: Exception) {
e.printStackTrace()
}
}
fun setWebViewBackgroundColor(isBlack: Boolean) {
if (isBlack) {
//防止加载html白屏(针对播放视频)
setBackgroundColor(Color.BLACK)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
onDestroy()
}
private inner class DocWebChromeClient : WebChromeClient() {
override fun onProgressChanged(view: WebView, newProgress: Int) {
super.onProgressChanged(view, newProgress)
setProgress(newProgress)
}
override fun onReceivedTitle(view: WebView, title: String) {
super.onReceivedTitle(view, title)
if (title.contains("html")) {
return
}
mOnWebLoadListener?.onTitle(title)
}
}
private inner class DocWebViewClient : WebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
//在访问失败的时候会首先回调onReceivedError,然后再回调onPageFinished。
if (!isError) {
isLastLoadSuccess = true
mOnWebLoadListener?.OnWebLoadProgress(100)
}
}
override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceError) {
super.onReceivedError(view, request, error)
//在访问失败的时候会首先回调onReceivedError,然后再回调onPageFinished。
isError = true
if (!isLastLoadSuccess) {//之前成功加载完成过,不会回调
mOnWebLoadListener?.OnWebLoadProgress(100)
}
}
}
}
\ No newline at end of file
...@@ -27,7 +27,7 @@ import java.util.* ...@@ -27,7 +27,7 @@ import java.util.*
* ----------------------------------------------------------------- * -----------------------------------------------------------------
*/ */
class PinchImageView: AppCompatImageView { class PinchImageView : AppCompatImageView {
companion object { companion object {
////////////////////////////////配置参数//////////////////////////////// ////////////////////////////////配置参数////////////////////////////////
/** /**
...@@ -557,14 +557,15 @@ class PinchImageView: AppCompatImageView { ...@@ -557,14 +557,15 @@ class PinchImageView: AppCompatImageView {
} }
////////////////////////////////初始化//////////////////////////////// ////////////////////////////////初始化////////////////////////////////
constructor(context: Context) :super(context) { constructor(context: Context) : super(context) {
initView() initView()
} }
constructor(context: Context,attrs: AttributeSet?) :super(context,attrs) {
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView() initView()
} }
constructor(context: Context, attrs: AttributeSet?, defStyle: Int): super(context, attrs, defStyle) { constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {
initView() initView()
} }
...@@ -742,38 +743,39 @@ class PinchImageView: AppCompatImageView { ...@@ -742,38 +743,39 @@ class PinchImageView: AppCompatImageView {
* *
* 在onTouchEvent末尾被执行. * 在onTouchEvent末尾被执行.
*/ */
private val mGestureDetector = GestureDetector(this@PinchImageView.getContext(), object : SimpleOnGestureListener() { private val mGestureDetector = GestureDetector(this@PinchImageView.context,
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { object : SimpleOnGestureListener() {
//只有在单指模式结束之后才允许执行fling override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
if (mPinchMode == PINCH_MODE_FREE && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) { //只有在单指模式结束之后才允许执行fling
fling(velocityX, velocityY) if (mPinchMode == PINCH_MODE_FREE && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) {
fling(velocityX, velocityY)
}
return true
} }
return true
}
override fun onLongPress(e: MotionEvent) { override fun onLongPress(e: MotionEvent) {
//触发长按 //触发长按
if (mOnLongClickListener != null) { if (mOnLongClickListener != null) {
mOnLongClickListener!!.onLongClick(this@PinchImageView) mOnLongClickListener!!.onLongClick(this@PinchImageView)
}
} }
}
override fun onDoubleTap(e: MotionEvent): Boolean { override fun onDoubleTap(e: MotionEvent): Boolean {
//当手指快速第二次按下触发,此时必须是单指模式才允许执行doubleTap //当手指快速第二次按下触发,此时必须是单指模式才允许执行doubleTap
if (mPinchMode == PINCH_MODE_SCROLL && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) { if (mPinchMode == PINCH_MODE_SCROLL && !(mScaleAnimator != null && mScaleAnimator!!.isRunning)) {
doubleTap(e.x, e.y) doubleTap(e.x, e.y)
}
return true
} }
return true
}
override fun onSingleTapConfirmed(e: MotionEvent): Boolean { override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
//触发点击 //触发点击
if (mOnClickListener != null) { if (mOnClickListener != null) {
mOnClickListener!!.onClick(this@PinchImageView) mOnClickListener!!.onClick(this@PinchImageView)
}
return true
} }
return true })
}
})
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
super.onTouchEvent(event) super.onTouchEvent(event)
...@@ -1220,7 +1222,11 @@ class PinchImageView: AppCompatImageView { ...@@ -1220,7 +1222,11 @@ class PinchImageView: AppCompatImageView {
* *
* 在给定时间内从一个矩阵的变化逐渐动画到另一个矩阵的变化 * 在给定时间内从一个矩阵的变化逐渐动画到另一个矩阵的变化
*/ */
private inner class ScaleAnimator @JvmOverloads constructor(start: Matrix, end: Matrix, duration: Long = SCALE_ANIMATOR_DURATION.toLong()) : ValueAnimator(), AnimatorUpdateListener { private inner class ScaleAnimator @JvmOverloads constructor(
start: Matrix,
end: Matrix,
duration: Long = SCALE_ANIMATOR_DURATION.toLong()
) : ValueAnimator(), AnimatorUpdateListener {
/** /**
* 开始矩阵 * 开始矩阵
*/ */
...@@ -1284,10 +1290,11 @@ class PinchImageView: AppCompatImageView { ...@@ -1284,10 +1290,11 @@ class PinchImageView: AppCompatImageView {
* @param <T> 对象池容纳的对象类型 * @param <T> 对象池容纳的对象类型
</T> */ </T> */
private abstract class ObjectsPool<T>( private abstract class ObjectsPool<T>(
/** /**
* 对象池的最大容量 * 对象池的最大容量
*/ */
private val mSize: Int) { private val mSize: Int
) {
/** /**
* 对象池队列 * 对象池队列
......
package com.cherry.lib.doc.widget; package com.cherry.lib.doc.widget;
import android.annotation.SuppressLint;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper; import android.content.ContextWrapper;
...@@ -41,6 +42,7 @@ public class PoiViewer { ...@@ -41,6 +42,7 @@ public class PoiViewer {
initCacheDir(); initCacheDir();
} }
@SuppressLint("SetJavaScriptEnabled")
private void initView() { private void initView() {
mProgressDialog = new ProgressDialog(mContext); mProgressDialog = new ProgressDialog(mContext);
mProgressDialog.setMessage("正在加载文件..."); mProgressDialog.setMessage("正在加载文件...");
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
xmlns:tools="http://schemas.android.com/tools">
<com.cherry.lib.doc.pdf.PinchZoomRecyclerView
android:id="@+id/mRvPdf"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:scrollbars="vertical"
tools:listitem="@layout/list_item_pdf" />
<FrameLayout <FrameLayout
android:id="@+id/mLlBigPdfImage" android:id="@+id/mLlBigPdfImage"
...@@ -23,15 +14,15 @@ ...@@ -23,15 +14,15 @@
<com.cherry.lib.doc.widget.PinchImageView <com.cherry.lib.doc.widget.PinchImageView
android:id="@+id/mIvPdf" android:id="@+id/mIvPdf"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent" />
<ProgressBar <ProgressBar
android:id="@+id/mPbBigLoading" android:id="@+id/mPbBigLoading"
android:layout_gravity="center"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_gravity="center"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"/> tools:visibility="visible" />
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
...@@ -40,33 +31,29 @@ ...@@ -40,33 +31,29 @@
android:layout_marginTop="50dp" android:layout_marginTop="50dp"
android:layout_marginEnd="30dp" android:layout_marginEnd="30dp"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:src="@mipmap/ic_big_close"/> android:src="@mipmap/ic_big_close"
tools:ignore="ContentDescription" />
</FrameLayout> </FrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/mFlDocContainer" android:id="@+id/mFlDocContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent" />
<com.cherry.lib.doc.widget.PinchImageView <com.cherry.lib.doc.widget.PinchImageView
android:id="@+id/mIvImage" android:id="@+id/mIvImage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="fitCenter"/> android:scaleType="fitCenter" />
<com.cherry.lib.doc.widget.DocWebView
android:id="@+id/mDocWeb"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ProgressBar <ProgressBar
android:id="@+id/mPlLoadProgress" android:id="@+id/mPlLoadProgress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="20dp"
style="?android:attr/progressBarStyleHorizontal"
android:progressDrawable="@drawable/pb_webview_layer" android:progressDrawable="@drawable/pb_webview_layer"
android:visibility="visible"/> android:visibility="visible" />
<TextView <TextView
android:id="@+id/mPdfPageNo" android:id="@+id/mPdfPageNo"
...@@ -79,7 +66,6 @@ ...@@ -79,7 +66,6 @@
android:paddingEnd="12dp" android:paddingEnd="12dp"
android:paddingBottom="4dp" android:paddingBottom="4dp"
android:textColor="#A19D9D" android:textColor="#A19D9D"
android:textSize="16sp" android:textSize="16sp" />
android:visibility="gone" />
</FrameLayout> </FrameLayout>
\ No newline at end of file
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
android:padding="0dp" android:padding="0dp"
android:scaleType="fitCenter" /> android:scaleType="fitCenter" />
<include layout="@layout/pdf_view_page_loading_layout" /> <include
android:id="@+id/include"
layout="@layout/pdf_view_page_loading_layout" />
</FrameLayout> </FrameLayout>
\ No newline at end of file
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