Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
P
PDF Viewer Scanner White
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
PDF Viewer Scanner White
Commits
c7a1e38b
Commit
c7a1e38b
authored
Sep 25, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
9fa8260b
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
415 additions
and
994 deletions
+415
-994
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+9
-4
MainActivity.kt
...va/com/base/pdfviewerscannerwhite/ui/main/MainActivity.kt
+5
-0
build.gradle
library/build.gradle
+4
-0
DocViewerActivity.kt
...ary/src/main/java/com/cherry/lib/doc/DocViewerActivity.kt
+11
-3
IOffice.java
library/src/main/java/com/cherry/lib/doc/office/IOffice.java
+1
-3
MovieShape.java
...a/com/cherry/lib/doc/office/fc/hslf/model/MovieShape.java
+35
-53
TextRun.java
...java/com/cherry/lib/doc/office/fc/hslf/model/TextRun.java
+190
-320
PGPrintMode.java
...ava/com/cherry/lib/doc/office/pg/control/PGPrintMode.java
+0
-8
PdfPageViewAdapter.kt
...rc/main/java/com/cherry/lib/doc/pdf/PdfPageViewAdapter.kt
+19
-17
PdfViewAdapter.kt
...ry/src/main/java/com/cherry/lib/doc/pdf/PdfViewAdapter.kt
+18
-18
DocView.kt
library/src/main/java/com/cherry/lib/doc/widget/DocView.kt
+64
-285
DocWebView.kt
...ary/src/main/java/com/cherry/lib/doc/widget/DocWebView.kt
+0
-221
PinchImageView.kt
...src/main/java/com/cherry/lib/doc/widget/PinchImageView.kt
+41
-34
PoiViewer.java
...ry/src/main/java/com/cherry/lib/doc/widget/PoiViewer.java
+2
-0
doc_view.xml
library/src/main/res/layout/doc_view.xml
+13
-27
list_item_pdf.xml
library/src/main/res/layout/list_item_pdf.xml
+3
-1
No files found.
app/src/main/AndroidManifest.xml
View file @
c7a1e38b
...
@@ -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"
...
...
app/src/main/java/com/base/pdfviewerscannerwhite/ui/main/MainActivity.kt
View file @
c7a1e38b
...
@@ -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
()
{
...
...
library/build.gradle
View file @
c7a1e38b
...
@@ -28,6 +28,10 @@ android {
...
@@ -28,6 +28,10 @@ android {
kotlinOptions
{
kotlinOptions
{
jvmTarget
=
'1.8'
jvmTarget
=
'1.8'
}
}
buildFeatures
{
viewBinding
=
true
}
}
}
dependencies
{
dependencies
{
...
...
library/src/main/java/com/cherry/lib/doc/DocViewerActivity.kt
View file @
c7a1e38b
...
@@ -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.m
DocView
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
)
{
)
{
va
r
intent
=
Intent
(
activity
,
DocViewerActivity
::
class
.
java
)
va
l
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"
)
...
...
library/src/main/java/com/cherry/lib/doc/office/IOffice.java
View file @
c7a1e38b
...
@@ -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
tru
e
;
return
fals
e
;
}
}
/**
/**
...
...
library/src/main/java/com/cherry/lib/doc/office/fc/hslf/model/MovieShape.java
View file @
c7a1e38b
...
@@ -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
();
}
}
}
}
...
...
library/src/main/java/com/cherry/lib/doc/office/fc/hslf/model/TextRun.java
View file @
c7a1e38b
...
@@ -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
;
...
...
library/src/main/java/com/cherry/lib/doc/office/pg/control/PGPrintMode.java
View file @
c7a1e38b
...
@@ -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
()
{
{
...
...
library/src/main/java/com/cherry/lib/doc/pdf/PdfPageViewAdapter.kt
View file @
c7a1e38b
...
@@ -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
android
x.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
library/src/main/java/com/cherry/lib/doc/pdf/PdfViewAdapter.kt
View file @
c7a1e38b
...
@@ -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_v
iew
.
setOnClickListener
{
binding
.
containerV
iew
.
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_p
rogress
.
hide
()
binding
.
include
.
pdfViewPageLoadingP
rogress
.
hide
()
return
return
}
}
if
(
renderer
?.
pageExistInCache
(
position
)
==
true
)
{
if
(
renderer
?.
pageExistInCache
(
position
)
==
true
)
{
itemView
.
pdf_view_page_loading_p
rogress
.
hide
()
binding
.
include
.
pdfViewPageLoadingP
rogress
.
hide
()
}
else
{
}
else
{
itemView
.
pdf_view_page_loading_p
rogress
.
show
()
binding
.
include
.
pdfViewPageLoadingP
rogress
.
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_v
iew
.
updateLayoutParams
<
ViewGroup
.
MarginLayoutParams
>
{
binding
.
containerV
iew
.
updateLayoutParams
<
ViewGroup
.
MarginLayoutParams
>
{
height
=
height
=
(
itemView
.
container_v
iew
.
width
.
toFloat
()
/
((
bitmap
.
width
.
toFloat
()
/
bitmap
.
height
.
toFloat
()))).
toInt
()
(
binding
.
containerV
iew
.
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_p
rogress
.
hide
()
binding
.
include
.
pdfViewPageLoadingP
rogress
.
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
()
}
}
}
}
...
...
library/src/main/java/com/cherry/lib/doc/widget/DocView.kt
View file @
c7a1e38b
...
@@ -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()......"
)
va
r
iOffice
:
IOffice
=
object
:
IOffice
()
{
va
l
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
library/src/main/java/com/cherry/lib/doc/widget/DocWebView.kt
deleted
100644 → 0
View file @
9fa8260b
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
library/src/main/java/com/cherry/lib/doc/widget/PinchImageView.kt
View file @
c7a1e38b
...
@@ -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
)
{
/**
/**
* 对象池队列
* 对象池队列
...
...
library/src/main/java/com/cherry/lib/doc/widget/PoiViewer.java
View file @
c7a1e38b
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
(
"正在加载文件..."
);
...
...
library/src/main/res/layout/doc_view.xml
View file @
c7a1e38b
<?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
library/src/main/res/layout/list_item_pdf.xml
View file @
c7a1e38b
...
@@ -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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment