停更
This commit is contained in:
parent
23a43c98f5
commit
24d9faba32
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -88,12 +88,12 @@ dependencies {
|
|||
// TinyPinyin核心包,约80KB
|
||||
implementation 'com.github.promeg:tinypinyin:2.0.3'
|
||||
implementation 'io.github.youth5201314:banner:2.2.2'
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.core:core-ktx:1.8.0'
|
||||
implementation 'com.github.deano2390:MaterialShowcaseView:1.3.4'
|
||||
implementation 'com.google.code.gson:gson:2.8.9'
|
||||
implementation 'com.google.code.gson:gson:2.9.1'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.6-native'
|
||||
implementation 'com.kongzue.stacklabel:stacklabelview:1.1.9'
|
||||
implementation files('libs/editor_0.8.aar')
|
||||
implementation 'io.github.Rosemoe.sora-editor:editor:0.16.5'
|
||||
implementation project(path: ':assistantCoreLibrary')
|
||||
implementation project(path: ':turretsDragView')
|
||||
implementation project(path: ':dialog')
|
||||
|
|
Binary file not shown.
|
@ -261,8 +261,8 @@
|
|||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".EditActivity"
|
||||
android:configChanges="orientation"
|
||||
android:exported="true"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:label="@string/mod_action1"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
|
|
|
@ -122,6 +122,7 @@ class CreateModActivity : BaseActivity<ActivityCreateModBinding>() {
|
|||
val fileWriter = FileWriter(mod_directory.absolutePath + "/mod-info.txt")
|
||||
fileWriter.write(stringBuilder.toString())
|
||||
fileWriter.close()
|
||||
setResult(RESULT_OK)
|
||||
finish()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.os.Bundle
|
|||
import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.*
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.coldmint.rust.pro.adapters.CreateUnitPageAdapter
|
||||
import com.coldmint.rust.pro.databinding.ActivityCreateUnitBinding
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
@ -38,43 +39,29 @@ class CreateUnitActivity : BaseActivity<ActivityCreateUnitBinding>() {
|
|||
}.attach()
|
||||
val root = bundle.getString("modPath")
|
||||
createUnitPageAdapter.setRootPath(root)
|
||||
val set = createUnitPageAdapter.setCreatePath(bundle.getString("createPath", root))
|
||||
// if (!set) {
|
||||
// //如果没有设置成功,当fragment没有附加到activity
|
||||
// viewBinding.toolbar.postDelayed({
|
||||
// createUnitPageAdapter.setCreatePath(bundle.getString("createPath", root))
|
||||
// }, 50)
|
||||
createUnitPageAdapter.setCreatePath(bundle.getString("createPath", root))
|
||||
// registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
// val resultCode = it.resultCode
|
||||
// when (requestCode) {
|
||||
// 1 -> if (resultCode == RESULT_OK) {
|
||||
// val directents = data!!.getStringExtra("Directents")
|
||||
// if (directents != null) {
|
||||
// createUnitPageAdapter.setCreatePath(directents)
|
||||
// }
|
||||
|
||||
|
||||
// loadlist()
|
||||
}
|
||||
}
|
||||
|
||||
// fun getmCreatePath(): String {
|
||||
// return mCreatePath
|
||||
// }
|
||||
// 2 -> if (resultCode == RESULT_OK) {
|
||||
// val path = data!!.getStringExtra("File")
|
||||
// val intent = Intent()
|
||||
// intent.putExtra("File", path)
|
||||
// setResult(RESULT_OK, intent)
|
||||
// finish()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
1 -> if (resultCode == RESULT_OK) {
|
||||
val directents = data!!.getStringExtra("Directents")
|
||||
if (directents != null) {
|
||||
createUnitPageAdapter.setCreatePath(directents)
|
||||
}
|
||||
}
|
||||
2 -> if (resultCode == RESULT_OK) {
|
||||
val path = data!!.getStringExtra("File")
|
||||
val intent = Intent()
|
||||
intent.putExtra("File", path)
|
||||
setResult(RESULT_OK, intent)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityCreateUnitBinding {
|
||||
return ActivityCreateUnitBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@ package com.coldmint.rust.pro
|
|||
import android.content.Intent
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.coldmint.rust.pro.adapters.GuideAdapter
|
||||
|
@ -13,11 +16,22 @@ import com.coldmint.rust.pro.databinding.ActivityCreationWizardBinding
|
|||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
|
||||
class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
|
||||
|
||||
lateinit var createMod: ActivityResultLauncher<Intent>
|
||||
|
||||
//创建向导类型(模组,模板包)
|
||||
lateinit var type: String
|
||||
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
|
||||
setReturnButton()
|
||||
title = getString(R.string.creation_assistant)
|
||||
createMod = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode == RESULT_OK) {
|
||||
finish()
|
||||
Log.d("创建单位", "收到了数据,关闭界面。")
|
||||
} else {
|
||||
Log.d("创建单位", "没有收到数据。")
|
||||
}
|
||||
}
|
||||
val temType = intent.getStringExtra("type")
|
||||
if (temType.isNullOrBlank()) {
|
||||
showToast("请传入类型")
|
||||
|
@ -118,15 +132,14 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
|
|||
val adapter = GuideAdapter(this, dataList)
|
||||
adapter.setItemEvent { i, itemGuideBinding, viewHolder, guideData ->
|
||||
itemGuideBinding.root.setOnClickListener {
|
||||
finish()
|
||||
when (guideData.titleRes) {
|
||||
R.string.create_mod_lable -> {
|
||||
startActivity(
|
||||
val startActivity =
|
||||
Intent(
|
||||
this,
|
||||
CreateModActivity::class.java
|
||||
)
|
||||
)
|
||||
createMod.launch(startActivity)
|
||||
}
|
||||
R.string.import_mod -> {
|
||||
val startIntent =
|
||||
|
@ -135,6 +148,7 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
|
|||
fileBundle.putString("type", "selectFile")
|
||||
startIntent.putExtra("data", fileBundle)
|
||||
startActivity(startIntent)
|
||||
finish()
|
||||
}
|
||||
R.string.import_mod_from_package_directory -> {
|
||||
val startIntent =
|
||||
|
@ -149,9 +163,11 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
|
|||
fileBundle.putString("rootpath", packDirectory)
|
||||
startIntent.putExtra("data", fileBundle)
|
||||
startActivity(startIntent)
|
||||
finish()
|
||||
}
|
||||
R.string.import_mod_from_recycle_bin -> {
|
||||
startActivity(Intent(this, RecyclingStationActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,10 +60,10 @@ import com.flask.colorpicker.ColorPickerView
|
|||
import com.flask.colorpicker.builder.ColorPickerDialogBuilder
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import io.github.rosemoe.sora.data.CompletionItem
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionItem
|
||||
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import io.github.rosemoe.sora.widget.EditorColorScheme
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
|
||||
|
@ -75,9 +75,6 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
private lateinit var rustLanguage: RustLanguage
|
||||
|
||||
private var fileAdapter: FileAdapter? = null
|
||||
val symbolChannel by lazy {
|
||||
viewBinding.codeEditor.createNewSymbolChannel()
|
||||
}
|
||||
|
||||
//是第一次启动嘛
|
||||
var isFirst = true
|
||||
|
@ -199,41 +196,41 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
rustLanguage.setEnglish(it)
|
||||
}
|
||||
|
||||
viewBinding.codeEditor.setItemListener { i, completionItem ->
|
||||
viewModel.executorService.submit {
|
||||
val extrasData = completionItem.extrasData
|
||||
if (extrasData != null) {
|
||||
val listData = extrasData.getString("list")
|
||||
if (listData != null) {
|
||||
val lineParser = LineParser(listData)
|
||||
lineParser.symbol = ","
|
||||
val list = ArrayList<CompletionItem>()
|
||||
lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
val temCodeInfo =
|
||||
CodeDataBase.getInstance(this).getCodeDao().findCodeByCode(lineData)
|
||||
if (temCodeInfo == null) {
|
||||
|
||||
} else {
|
||||
val completionItemConverter = CompletionItemConverter.instance
|
||||
completionItemConverter.init(this)
|
||||
list.add(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
temCodeInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
true
|
||||
}
|
||||
if (list.isNotEmpty()) {
|
||||
runOnUiThread {
|
||||
viewBinding.codeEditor.createEditorAutoCompleteList(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
// viewBinding.codeEditor.setItemListener { i, completionItem ->
|
||||
// viewModel.executorService.submit {
|
||||
// val extrasData = completionItem.extrasData
|
||||
// if (extrasData != null) {
|
||||
// val listData = extrasData.getString("list")
|
||||
// if (listData != null) {
|
||||
// val lineParser = LineParser(listData)
|
||||
// lineParser.symbol = ","
|
||||
// val list = ArrayList<CompletionItem>()
|
||||
// lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
// val temCodeInfo =
|
||||
// CodeDataBase.getInstance(this).getCodeDao().findCodeByCode(lineData)
|
||||
// if (temCodeInfo == null) {
|
||||
//
|
||||
// } else {
|
||||
// val completionItemConverter = CompletionItemConverter.instance
|
||||
// completionItemConverter.init(this)
|
||||
// list.add(
|
||||
// completionItemConverter.codeInfoToCompletionItem(
|
||||
// temCodeInfo
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// true
|
||||
// }
|
||||
// if (list.isNotEmpty()) {
|
||||
// runOnUiThread {
|
||||
// viewBinding.codeEditor.createEditorAutoCompleteList(list)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// true
|
||||
// }
|
||||
viewModel.openedSourceFileListLiveData.observe(this) {
|
||||
viewBinding.tabLayout.removeAllTabs()
|
||||
it.forEach {
|
||||
|
@ -314,11 +311,11 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
}
|
||||
|
||||
viewModel.codeLiveData.observe(this) {
|
||||
rustLanguage.autoCompleteProvider.setSourceFolder(
|
||||
FileOperator.getSuperDirectory(
|
||||
viewModel.getNowOpenFilePath()
|
||||
)
|
||||
)
|
||||
// rustLanguage.autoCompleteProvider.setSourceFolder(
|
||||
// FileOperator.getSuperDirectory(
|
||||
// viewModel.getNowOpenFilePath()
|
||||
// )
|
||||
// )
|
||||
//初始化加载路径数据(仅在第一次有效)
|
||||
editStartViewModel.initLoadPathLiveData(viewModel.getNowOpenFilePath())
|
||||
viewBinding.myProgressBar.isVisible = false
|
||||
|
@ -480,8 +477,8 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
loadStartObserve()
|
||||
loadEndObserve()
|
||||
initDrawerLayout()
|
||||
initCodeEditor()
|
||||
initCodeToolbar()
|
||||
initCodeEditor()
|
||||
initStartView()
|
||||
initEndView()
|
||||
showRenewalTip()
|
||||
|
@ -979,7 +976,7 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
builder.append(viewModel.convertDigital(r))
|
||||
builder.append(viewModel.convertDigital(g))
|
||||
builder.append(viewModel.convertDigital(b))
|
||||
symbolChannel.insertSymbol(builder.toString(), builder.length)
|
||||
viewBinding.codeEditor.insertText(builder.toString(), builder.length)
|
||||
}
|
||||
.setNegativeButton(R.string.dialog_cancel) { dialog, which -> }
|
||||
.build()
|
||||
|
@ -1000,107 +997,107 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
).show()
|
||||
}
|
||||
} else if (item == getString(R.string.code_tip)) {
|
||||
viewModel.executorService.submit {
|
||||
try {
|
||||
val list = ArrayList<CompletionItem>()
|
||||
//如果不包含:搜索键
|
||||
val lineNumber = viewBinding.codeEditor.selectedLineNumber
|
||||
val navigationList =
|
||||
viewBinding.codeEditor.textAnalyzeResult.navigation
|
||||
var section: String? = null
|
||||
if (navigationList != null && navigationList.isNotEmpty()) {
|
||||
for (navigation in navigationList) {
|
||||
if (navigation.line > lineNumber) {
|
||||
break
|
||||
} else {
|
||||
section = navigation.label
|
||||
}
|
||||
}
|
||||
}
|
||||
//如果不在任何节内
|
||||
if (section == null) {
|
||||
runOnUiThread {
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
viewBinding.recyclerview,
|
||||
this.getString(R.string.code_tip_error1),
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
return@submit
|
||||
}
|
||||
val trueSection =
|
||||
rustLanguage.autoCompleteProvider.getSectionType(section)
|
||||
val codeDataBase = CodeDataBase.getInstance(this)
|
||||
val lineData =
|
||||
viewBinding.codeEditor.text.getLine(lineNumber).toString()
|
||||
if (lineData.startsWith('[') && lineData.endsWith(']')) {
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
viewBinding.recyclerview,
|
||||
R.string.code_tip_error2,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
return@submit
|
||||
}
|
||||
val index = lineData.indexOf(':')
|
||||
if (index > -1) {
|
||||
//如果包含:
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
viewBinding.recyclerview,
|
||||
this.getString(R.string.can_not_tip_value),
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
return@submit
|
||||
} else {
|
||||
val codeInfoList = if (lineData.isBlank()) {
|
||||
codeDataBase.getCodeDao().findCodeBySection(trueSection)
|
||||
} else {
|
||||
val number = AppSettings.getValue(
|
||||
AppSettings.Setting.IdentifiersPromptNumber,
|
||||
40
|
||||
)
|
||||
codeDataBase.getCodeDao()
|
||||
.findCodeByKeyFromSection(lineData, trueSection, number)
|
||||
}
|
||||
if (codeInfoList != null && codeInfoList.isNotEmpty()) {
|
||||
val completionItemConverter =
|
||||
CompletionItemConverter.instance.init(this)
|
||||
codeInfoList.forEach {
|
||||
list.add(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
viewBinding.recyclerview,
|
||||
String.format(
|
||||
this.getString(R.string.code_tip_error3),
|
||||
SourceFile.getSectionType(section)
|
||||
),
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
runOnUiThread {
|
||||
viewBinding.codeEditor.createEditorAutoCompleteList(list)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
// viewModel.executorService.submit {
|
||||
// try {
|
||||
// val list = ArrayList<CompletionItem>()
|
||||
// //如果不包含:搜索键
|
||||
// val lineNumber = viewBinding.codeEditor.selectedLineNumber
|
||||
// val navigationList =
|
||||
// viewBinding.codeEditor.textAnalyzeResult.navigation
|
||||
// var section: String? = null
|
||||
// if (navigationList != null && navigationList.isNotEmpty()) {
|
||||
// for (navigation in navigationList) {
|
||||
// if (navigation.line > lineNumber) {
|
||||
// break
|
||||
// } else {
|
||||
// section = navigation.label
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //如果不在任何节内
|
||||
// if (section == null) {
|
||||
// runOnUiThread {
|
||||
// runOnUiThread {
|
||||
// Snackbar.make(
|
||||
// viewBinding.recyclerview,
|
||||
// this.getString(R.string.code_tip_error1),
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// }
|
||||
// return@submit
|
||||
// }
|
||||
// val trueSection =
|
||||
// rustLanguage.autoCompleteProvider.getSectionType(section)
|
||||
// val codeDataBase = CodeDataBase.getInstance(this)
|
||||
// val lineData =
|
||||
// viewBinding.codeEditor.text.getLine(lineNumber).toString()
|
||||
// if (lineData.startsWith('[') && lineData.endsWith(']')) {
|
||||
// runOnUiThread {
|
||||
// Snackbar.make(
|
||||
// viewBinding.recyclerview,
|
||||
// R.string.code_tip_error2,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// return@submit
|
||||
// }
|
||||
// val offset = lineData.indexOf(':')
|
||||
// if (offset > -1) {
|
||||
// //如果包含:
|
||||
// runOnUiThread {
|
||||
// Snackbar.make(
|
||||
// viewBinding.recyclerview,
|
||||
// this.getString(R.string.can_not_tip_value),
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// return@submit
|
||||
// } else {
|
||||
// val codeInfoList = if (lineData.isBlank()) {
|
||||
// codeDataBase.getCodeDao().findCodeBySection(trueSection)
|
||||
// } else {
|
||||
// val number = AppSettings.getValue(
|
||||
// AppSettings.Setting.IdentifiersPromptNumber,
|
||||
// 40
|
||||
// )
|
||||
// codeDataBase.getCodeDao()
|
||||
// .findCodeByKeyFromSection(lineData, trueSection, number)
|
||||
// }
|
||||
// if (codeInfoList != null && codeInfoList.isNotEmpty()) {
|
||||
// val completionItemConverter =
|
||||
// CompletionItemConverter.instance.init(this)
|
||||
// codeInfoList.forEach {
|
||||
// list.add(
|
||||
// completionItemConverter.codeInfoToCompletionItem(
|
||||
// it
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// runOnUiThread {
|
||||
// Snackbar.make(
|
||||
// viewBinding.recyclerview,
|
||||
// String.format(
|
||||
// this.getString(R.string.code_tip_error3),
|
||||
// SourceFile.getSectionType(section)
|
||||
// ),
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// runOnUiThread {
|
||||
// viewBinding.codeEditor.createEditorAutoCompleteList(list)
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
//
|
||||
// }
|
||||
} else {
|
||||
try {
|
||||
symbolChannel.insertSymbol(item, item.length)
|
||||
viewBinding.codeEditor.insertText(item, item.length)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
@ -1139,53 +1136,41 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
rustLanguage.setCodeEditor(viewBinding.codeEditor)
|
||||
val night = AppSettings.getValue(AppSettings.Setting.NightMode, false)
|
||||
val editorColorScheme = EditorColorScheme()
|
||||
if (night) {
|
||||
val backgroundColor = GlobalMethod.getThemeColor(this, android.R.attr.windowBackground)
|
||||
//代码(可识别的关键字)
|
||||
editorColorScheme.setColor(EditorColorScheme.KEYWORD, Color.rgb(178, 119, 49))
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.KEYWORD,
|
||||
GlobalMethod.getThemeColor(this, android.R.attr.colorSecondary)
|
||||
)
|
||||
//默认文本
|
||||
editorColorScheme.setColor(EditorColorScheme.TEXT_NORMAL, Color.rgb(169, 183, 198))
|
||||
//注释
|
||||
editorColorScheme.setColor(EditorColorScheme.COMMENT, Color.rgb(128, 128, 128))
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.COMMENT,
|
||||
GlobalMethod.getThemeColor(this, android.R.attr.textColorTertiary)
|
||||
)
|
||||
//节
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.FUNCTION_NAME,
|
||||
Color.rgb(152, 118, 170)
|
||||
GlobalMethod.getColorPrimary(this)
|
||||
)
|
||||
//错误
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.WHOLE_BACKGROUND,
|
||||
Color.rgb(60, 63, 65)
|
||||
backgroundColor
|
||||
)
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.LINE_NUMBER_BACKGROUND,
|
||||
Color.rgb(60, 63, 65)
|
||||
backgroundColor
|
||||
)
|
||||
} else {
|
||||
//代码(可识别的关键字)
|
||||
editorColorScheme.setColor(EditorColorScheme.KEYWORD, Color.rgb(42, 92, 170))
|
||||
//默认文本
|
||||
editorColorScheme.setColor(EditorColorScheme.TEXT_NORMAL, Color.BLACK)
|
||||
//注释
|
||||
editorColorScheme.setColor(EditorColorScheme.COMMENT, Color.rgb(128, 128, 128))
|
||||
//节
|
||||
editorColorScheme.setColor(EditorColorScheme.FUNCTION_NAME, Color.rgb(170, 33, 22))
|
||||
editorColorScheme.setColor(
|
||||
EditorColorScheme.WHOLE_BACKGROUND,
|
||||
Color.rgb(240, 240, 243)
|
||||
)
|
||||
|
||||
//变量名
|
||||
editorColorScheme.setColor(EditorColorScheme.LITERAL, Color.rgb(153, 50, 204))
|
||||
}
|
||||
viewBinding.codeEditor.colorScheme = editorColorScheme
|
||||
viewBinding.codeEditor.setAutoCompletionItemAdapter(RustCompletionAdapter())
|
||||
viewBinding.codeEditor.isVerticalScrollBarEnabled = false
|
||||
val path = viewModel.modClass?.modFile?.absolutePath ?: ""
|
||||
rustLanguage.autoCompleteProvider.setConfigurationFileConversion(
|
||||
path,
|
||||
"ROOT",
|
||||
path
|
||||
)
|
||||
// rustLanguage.autoCompleteProvider.setConfigurationFileConversion(
|
||||
// path,
|
||||
// "ROOT",
|
||||
// path
|
||||
// )
|
||||
viewBinding.codeEditor.setEditorLanguage(rustLanguage)
|
||||
|
||||
}
|
||||
|
@ -1262,49 +1247,49 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
}
|
||||
}
|
||||
R.id.code_navigation -> {
|
||||
viewModel.executorService.submit {
|
||||
val labels = viewBinding.codeEditor.textAnalyzeResult.navigation
|
||||
if (labels == null || labels.size == 0) {
|
||||
runOnUiThread {
|
||||
Snackbar.make(
|
||||
viewBinding.recyclerview,
|
||||
R.string.not_find_code_navigation,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
} else {
|
||||
val items = ArrayList<CharSequence>()
|
||||
var i = 0
|
||||
while (i < labels.size) {
|
||||
items.add(labels[i].label)
|
||||
i++
|
||||
}
|
||||
val tip = String.format(getString(R.string.navigation_tip), items.size)
|
||||
runOnUiThread {
|
||||
MaterialDialog(this).show {
|
||||
title(R.string.code_navigation).positiveButton(R.string.dialog_cancel)
|
||||
.message(text = tip)
|
||||
.listItems(
|
||||
items = items,
|
||||
waitForPositiveButton = false,
|
||||
selection = object : ItemListener {
|
||||
override fun invoke(
|
||||
dialog: MaterialDialog,
|
||||
index: Int,
|
||||
text: CharSequence
|
||||
) {
|
||||
viewBinding.codeEditor.jumpToLine(
|
||||
labels[index].line
|
||||
)
|
||||
viewBinding.codeEditor.moveSelectionEnd()
|
||||
dialog.dismiss()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// viewModel.executorService.submit {
|
||||
// val labels = viewBinding.codeEditor.textAnalyzeResult.navigation
|
||||
// if (labels == null || labels.size == 0) {
|
||||
// runOnUiThread {
|
||||
// Snackbar.make(
|
||||
// viewBinding.recyclerview,
|
||||
// R.string.not_find_code_navigation,
|
||||
// Snackbar.LENGTH_SHORT
|
||||
// ).show()
|
||||
// }
|
||||
// } else {
|
||||
// val items = ArrayList<CharSequence>()
|
||||
// var i = 0
|
||||
// while (i < labels.size) {
|
||||
// items.add(labels[i].label)
|
||||
// i++
|
||||
// }
|
||||
// val tip = String.format(getString(R.string.navigation_tip), items.size)
|
||||
// runOnUiThread {
|
||||
// MaterialDialog(this).show {
|
||||
// title(R.string.code_navigation).positiveButton(R.string.dialog_cancel)
|
||||
// .message(text = tip)
|
||||
// .listItems(
|
||||
// items = items,
|
||||
// waitForPositiveButton = false,
|
||||
// selection = object : ItemListener {
|
||||
// override fun invoke(
|
||||
// dialog: MaterialDialog,
|
||||
// offset: Int,
|
||||
// text: CharSequence
|
||||
// ) {
|
||||
// viewBinding.codeEditor.jumpToLine(
|
||||
// labels[offset].line
|
||||
// )
|
||||
// viewBinding.codeEditor.moveSelectionEnd()
|
||||
// dialog.dismiss()
|
||||
// }
|
||||
//
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
R.id.save_text -> {
|
||||
val openedSourceFile =
|
||||
|
@ -1534,24 +1519,24 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
|
|||
viewBinding.editDrawerlayout.closeDrawer(GravityCompat.END)
|
||||
}
|
||||
addAdditionalName -> {
|
||||
val labels =
|
||||
viewBinding.codeEditor.textAnalyzeResult.navigation
|
||||
var num = 1
|
||||
labels.forEach {
|
||||
val type = SourceFile.getSectionType(
|
||||
it.label.substring(
|
||||
1,
|
||||
it.label.length - 1
|
||||
)
|
||||
)
|
||||
if (type == sectionName) {
|
||||
num++
|
||||
}
|
||||
}
|
||||
val name = "_" + num.toString()
|
||||
viewBinding.codeEditor.setSelection(lineNum, columnNum)
|
||||
symbolChannel.insertSymbol(name, name.length)
|
||||
viewBinding.editDrawerlayout.closeDrawer(GravityCompat.END)
|
||||
// val labels =
|
||||
// viewBinding.codeEditor.textAnalyzeResult.navigation
|
||||
// var num = 1
|
||||
// labels.forEach {
|
||||
// val type = SourceFile.getSectionType(
|
||||
// it.label.substring(
|
||||
// 1,
|
||||
// it.label.length - 1
|
||||
// )
|
||||
// )
|
||||
// if (type == sectionName) {
|
||||
// num++
|
||||
// }
|
||||
// }
|
||||
// val name = "_" + num.toString()
|
||||
// viewBinding.codeEditor.setSelection(lineNum, columnNum)
|
||||
// viewBinding.codeEditor.insertText(name, name.length)
|
||||
// viewBinding.editDrawerlayout.closeDrawer(GravityCompat.END)
|
||||
}
|
||||
}
|
||||
false
|
||||
|
|
|
@ -142,7 +142,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
|
|||
// )
|
||||
// )
|
||||
// MaterialDialog(this).title(R.string.open_type)
|
||||
// .listItems(items = openList) { dialog, index, text ->
|
||||
// .listItems(items = openList) { dialog, offset, text ->
|
||||
// when (text) {
|
||||
// getString(R.string.edit_template) -> {
|
||||
// editTemplate(file)
|
||||
|
|
|
@ -59,23 +59,22 @@ class LibraryActivity : BaseActivity<ActivityLibraryBinding>() {
|
|||
"Apache License 2.0"
|
||||
)
|
||||
)
|
||||
// libInfoArrayList.add(
|
||||
// LibInfo(
|
||||
// "Kongzue StackLabel",
|
||||
// "空祖家的堆叠标签(以下碎念:一开始起名字“StackLabel”没想太多结果被人吐槽Stack是整齐堆叠的意思...........好吧这是我的锅不过现在要改也来不及了,好用就行了...吧?",
|
||||
// "https://github.com/kongzue/StackLabel",
|
||||
// "Apache License 2.0"
|
||||
// )
|
||||
// )
|
||||
libInfoArrayList.add(
|
||||
LibInfo(
|
||||
"Kongzue StackLabel",
|
||||
"空祖家的堆叠标签(以下碎念:一开始起名字“StackLabel”没想太多结果被人吐槽Stack是整齐堆叠的意思...........好吧这是我的锅不过现在要改也来不及了,好用就行了...吧?",
|
||||
"https://github.com/kongzue/StackLabel",
|
||||
"Apache License 2.0"
|
||||
)
|
||||
)
|
||||
val libInfo = LibInfo(
|
||||
"sora-editor",
|
||||
"A cool code editor library on Android with syntax-highlighting and auto-completion. (aka CodeEditor)",
|
||||
"https://github.com/Rosemoe/sora-editor",
|
||||
"LGPL 2.1"
|
||||
)
|
||||
libInfo.tip =
|
||||
"铁锈助手使用sora-editor的魔改版本。\n\n由ColdMint魔改自Rose的sora-editor编辑框。\n\n在原基础上新增功能:\n-列表控制api(用于实现连锁提示)\n-自定义列表适配器(用于适配视图)\n\n目前修改版本为0.8,由ColdMint维护。\n\n于2022-1-25日同步主项目。"
|
||||
libInfoArrayList.add(libInfo)
|
||||
)
|
||||
libInfoArrayList.add(
|
||||
LibInfo(
|
||||
"ColorPicker",
|
||||
|
|
|
@ -5,6 +5,8 @@ import com.coldmint.rust.pro.base.BaseActivity
|
|||
import org.json.JSONObject
|
||||
import android.os.Bundle
|
||||
import android.content.Intent
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import org.json.JSONException
|
||||
|
@ -28,14 +30,20 @@ import com.coldmint.rust.core.dataBean.IntroducingDataBean
|
|||
import com.coldmint.rust.core.dataBean.ListParserDataBean
|
||||
import com.coldmint.rust.core.dataBean.template.LocalTemplateFile
|
||||
import com.coldmint.rust.core.dataBean.template.TemplatePackage
|
||||
import com.coldmint.rust.core.dataBean.template.WebTemplateData
|
||||
import com.coldmint.rust.core.interfaces.ApiCallBack
|
||||
import com.coldmint.rust.core.interfaces.TemplateParser
|
||||
import com.coldmint.rust.core.templateParser.InputParser
|
||||
import com.coldmint.rust.core.templateParser.IntroducingParser
|
||||
import com.coldmint.rust.core.templateParser.ListParser
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.core.web.ServerConfiguration
|
||||
import com.coldmint.rust.core.web.TemplatePhp
|
||||
import com.coldmint.rust.pro.databinding.ActivityTemplateParserBinding
|
||||
import com.coldmint.rust.pro.tool.UnitAutoCompleteHelper
|
||||
import com.coldmint.rust.pro.viewmodel.TemplateParserViewModel
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.dialog.MaterialDialogs
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import com.google.gson.Gson
|
||||
import java.io.File
|
||||
|
@ -68,9 +76,8 @@ class TemplateParserActivity : BaseActivity<ActivityTemplateParserBinding>() {
|
|||
if (code.isBlank()) {
|
||||
code = getString(R.string.not_found_data2)
|
||||
}
|
||||
CoreDialog(this).setTitle(viewModel.getTemplateName(language)).setMessage(code)
|
||||
.setPositiveButton(R.string.dialog_ok) {
|
||||
|
||||
MaterialAlertDialogBuilder(this).setTitle(viewModel.getTemplateName(language))
|
||||
.setMessage(code).setPositiveButton(R.string.dialog_ok) { i, i2 ->
|
||||
}.show()
|
||||
}
|
||||
}
|
||||
|
@ -79,8 +86,51 @@ class TemplateParserActivity : BaseActivity<ActivityTemplateParserBinding>() {
|
|||
|
||||
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
|
||||
if (canUseView) {
|
||||
|
||||
setReturnButton()
|
||||
val unitAutoCompleteHelper = UnitAutoCompleteHelper(this)
|
||||
unitAutoCompleteHelper.onBindAutoCompleteTextView(viewBinding.fileNameInputView)
|
||||
viewBinding.fileNameInputView.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun afterTextChanged(p0: Editable?) {
|
||||
val text = p0.toString()
|
||||
if (text.isBlank()) {
|
||||
viewBinding.fileNameInputLayout.error = getString(R.string.file_name_error)
|
||||
} else {
|
||||
viewBinding.fileNameInputLayout.isErrorEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
viewBinding.fab.setOnClickListener {
|
||||
val name = viewBinding.fileNameInputView.text.toString()
|
||||
if (name.isNotBlank()) {
|
||||
val build = viewModel.buildFile(this, name)
|
||||
if (build) {
|
||||
setResult(RESULT_OK)
|
||||
finish()
|
||||
} else {
|
||||
Snackbar.make(
|
||||
viewBinding.fab,
|
||||
R.string.create_unit_failed,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
val createDirectory = intent.getStringExtra("createDirectory")
|
||||
if (createDirectory == null) {
|
||||
Toast.makeText(this, "没有设置创建目录", Toast.LENGTH_SHORT).show()
|
||||
finish()
|
||||
return
|
||||
}
|
||||
viewModel.setCreateDirectory(createDirectory)
|
||||
val link = intent.getStringExtra("link")
|
||||
if (link == null) {
|
||||
Toast.makeText(this, "请设置链接", Toast.LENGTH_SHORT).show()
|
||||
|
@ -99,8 +149,42 @@ class TemplateParserActivity : BaseActivity<ActivityTemplateParserBinding>() {
|
|||
viewBinding.nestedScrollView.isVisible = true
|
||||
title = viewModel.getTemplateName(language)
|
||||
} else {
|
||||
|
||||
Log.d("模板解析器", "加载网络模板$link")
|
||||
TemplatePhp.instance.getTemplate(link, object : ApiCallBack<WebTemplateData> {
|
||||
override fun onResponse(t: WebTemplateData) {
|
||||
if (t.code == ServerConfiguration.Success_Code) {
|
||||
viewModel.setTemplate(t.data)
|
||||
val templateParserList =
|
||||
viewModel.getTemplateParserList(this@TemplateParserActivity)
|
||||
templateParserList.forEach {
|
||||
viewBinding.base.addView(it.contextView)
|
||||
}
|
||||
viewBinding.linearLayout.isVisible = false
|
||||
viewBinding.nestedScrollView.isVisible = true
|
||||
title = viewModel.getTemplateName(language)
|
||||
} else {
|
||||
Toast.makeText(
|
||||
this@TemplateParserActivity,
|
||||
t.message,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(
|
||||
this@TemplateParserActivity,
|
||||
R.string.network_error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
finish()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,8 @@ class UserHomePageActivity : BaseActivity<ActivityUserHomePageBinding>() {
|
|||
viewBinding.loginTimeView.text = String.format(
|
||||
getString(R.string.user_info),
|
||||
spaceInfoData.data.loginTime,
|
||||
spaceInfoData.data.account
|
||||
spaceInfoData.data.account,
|
||||
spaceInfoData.data.location
|
||||
)
|
||||
|
||||
viewBinding.fab.isVisible = true
|
||||
|
|
|
@ -451,7 +451,7 @@ class ModActionAdapter(
|
|||
if (string.isNotEmpty() && string != oldname) {
|
||||
val newFile = File(FileOperator.getSuperDirectory(mod_file) + "/" + string)
|
||||
mod_file.renameTo(newFile)
|
||||
mModFragment.loadMods()
|
||||
mModFragment.loadModList()
|
||||
}
|
||||
true
|
||||
}.setNegativeButton(R.string.dialog_cancel) {
|
||||
|
@ -728,7 +728,7 @@ class ModActionAdapter(
|
|||
if (ok) {
|
||||
handler.post {
|
||||
materialDialog.dismiss()
|
||||
mModFragment.loadMods()
|
||||
mModFragment.loadModList()
|
||||
Snackbar.make(
|
||||
(mModFragment.view)!!,
|
||||
R.string.repair_complete,
|
||||
|
@ -764,7 +764,7 @@ class ModActionAdapter(
|
|||
)
|
||||
handler.post {
|
||||
materialDialog.dismiss()
|
||||
mModFragment.loadMods()
|
||||
mModFragment.loadModList()
|
||||
if (needShowSnackbar) {
|
||||
Snackbar.make(
|
||||
(mModFragment.view)!!,
|
||||
|
@ -889,7 +889,7 @@ class ModActionAdapter(
|
|||
repairThread.setModpath(unzip_path.absolutePath)
|
||||
repairThread.start()
|
||||
}
|
||||
mModFragment.loadMods()
|
||||
mModFragment.loadModList()
|
||||
}
|
||||
} else {
|
||||
handler.post {
|
||||
|
|
|
@ -11,16 +11,17 @@ import com.bumptech.glide.Glide
|
|||
import android.os.Build
|
||||
import com.coldmint.rust.pro.base.BaseAdapter
|
||||
import com.coldmint.rust.pro.databinding.ModListItemBinding
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
|
||||
/*模组适配器
|
||||
* 此适配器只能使用于ModFragment成员变量按需传递。
|
||||
* */
|
||||
class ModAdapter(context: Context, dataList: MutableList<ModClass>) :
|
||||
BaseAdapter<ModListItemBinding, ModClass>(context, dataList) {
|
||||
BaseAdapter<ModListItemBinding, ModClass>(context, dataList), PopupTextProvider {
|
||||
|
||||
init {
|
||||
dataList.sortBy {
|
||||
it.modName
|
||||
getInitial(it.modName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,4 +72,9 @@ class ModAdapter(context: Context, dataList: MutableList<ModClass>) :
|
|||
viewBinding.modUpTime.text = data.lastModificationTime
|
||||
viewBinding.modNameView.text = data.modName
|
||||
}
|
||||
|
||||
override fun getPopupText(position: Int): String {
|
||||
val s = dataList[position].modName
|
||||
return getInitial(s).toString()
|
||||
}
|
||||
}
|
|
@ -13,8 +13,12 @@ import android.graphics.BitmapFactory
|
|||
import android.content.Intent
|
||||
import com.coldmint.rust.pro.TemplateParserActivity
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.bumptech.glide.Glide
|
||||
import com.coldmint.rust.core.LocalTemplatePackage
|
||||
import com.coldmint.rust.core.dataBean.template.Template
|
||||
|
@ -28,7 +32,8 @@ class TemplateAdapter(
|
|||
private val context: Context,
|
||||
private val mGroup: List<TemplatePackage>,
|
||||
private val mItemList: List<List<Template>>,
|
||||
mEnvironmentLanguage: String
|
||||
mEnvironmentLanguage: String,
|
||||
private val startTemplateParserActivity: ActivityResultLauncher<Intent>
|
||||
) : BaseExpandableListAdapter() {
|
||||
private val layoutInflater: LayoutInflater = LayoutInflater.from(context)
|
||||
private val mEnvironmentLanguage: String
|
||||
|
@ -117,7 +122,9 @@ class TemplateAdapter(
|
|||
val intent = Intent(context, TemplateParserActivity::class.java)
|
||||
intent.putExtra("link", templateClass.getLink())
|
||||
intent.putExtra("isLocal", templateClass.isLocal())
|
||||
context.startActivity(intent)
|
||||
intent.putExtra("createDirectory", createPath)
|
||||
|
||||
startTemplateParserActivity.launch(intent)
|
||||
}
|
||||
return templateItemBinding.root
|
||||
}
|
||||
|
|
|
@ -340,14 +340,14 @@ class TemplateListAdapter(
|
|||
// holder.templateListItemBinding.delButton.setBackgroundColor(R.color.blue_200)
|
||||
// holder.templateListItemBinding.delButton.setText(R.string.del_moding)
|
||||
// }
|
||||
// val index = mFiles.indexOf(templateClass.directest)
|
||||
// mFiles.removeAt(index)
|
||||
// val offset = mFiles.indexOf(templateClass.directest)
|
||||
// mFiles.removeAt(offset)
|
||||
// FileOperator.delete_files(templateClass.directest)
|
||||
// mfragment.requireActivity().runOnUiThread {
|
||||
// if (mFiles.size == 0) {
|
||||
// mfragment.load_list(mRootPath, true)
|
||||
// } else {
|
||||
// notifyItemRemoved(index)
|
||||
// notifyItemRemoved(offset)
|
||||
// }
|
||||
// }
|
||||
// }.start()
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.coldmint.rust.pro.adapters
|
|||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.coldmint.rust.core.dataBean.webTemplate.WebTemplatePackageListData
|
||||
import com.coldmint.rust.core.dataBean.WebTemplatePackageListData
|
||||
import com.coldmint.rust.pro.R
|
||||
import com.coldmint.rust.pro.base.BaseAdapter
|
||||
import com.coldmint.rust.pro.databinding.ItemWebTemplateBinding
|
||||
|
|
|
@ -9,22 +9,19 @@ import com.coldmint.rust.core.interfaces.EnglishMode
|
|||
import com.coldmint.rust.core.tool.LineParser
|
||||
import com.coldmint.rust.core.tool.LocalVariableName
|
||||
import com.coldmint.rust.pro.R
|
||||
import io.github.rosemoe.sora.data.NavigationItem
|
||||
import io.github.rosemoe.sora.data.Span
|
||||
import io.github.rosemoe.sora.interfaces.CodeAnalyzer
|
||||
import io.github.rosemoe.sora.text.TextAnalyzeResult
|
||||
import io.github.rosemoe.sora.text.TextAnalyzer
|
||||
import io.github.rosemoe.sora.widget.EditorColorScheme
|
||||
import io.github.rosemoe.sora.lang.styling.Span
|
||||
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.text.StringBuilder
|
||||
|
||||
class RustAnalyzer() : CodeAnalyzer,EnglishMode {
|
||||
private val labels: ArrayList<NavigationItem> by lazy {
|
||||
ArrayList()
|
||||
}
|
||||
@Deprecated("已过时")
|
||||
class RustAnalyzer() : EnglishMode {
|
||||
// private val labels: ArrayList<NavigationItem> by lazy {
|
||||
// ArrayList()
|
||||
// }
|
||||
|
||||
companion object {
|
||||
/**
|
||||
|
@ -57,292 +54,292 @@ class RustAnalyzer() : CodeAnalyzer,EnglishMode {
|
|||
* @param colors TextAnalyzeResult
|
||||
* @param delegate Delegate
|
||||
*/
|
||||
override fun analyze(
|
||||
content: CharSequence,
|
||||
colors: TextAnalyzeResult,
|
||||
delegate: TextAnalyzer.AnalyzeThread.Delegate
|
||||
) {
|
||||
//添加换行符作为结束符
|
||||
val str = content.toString() + "\n"
|
||||
if (str.isBlank() || codeDataBase == null) {
|
||||
return
|
||||
}
|
||||
val lineParser = LineParser()
|
||||
lineParser.parserSymbol = true
|
||||
lineParser.symbol = "_"
|
||||
colors.addNormalIfNull()
|
||||
if (delegate.shouldAnalyze()) {
|
||||
labels.clear()
|
||||
localVariableNameList.clear()
|
||||
var codeBlockType: CompileConfiguration.CodeBlockType =
|
||||
CompileConfiguration.CodeBlockType.Key
|
||||
var lineNum = 0
|
||||
val keyBuilder = StringBuilder()
|
||||
val valueBuilder = StringBuilder()
|
||||
var column = 0
|
||||
var startIndex = -1
|
||||
//是否执行二次渲染,用于判断值是否合法
|
||||
var lineRendering = true
|
||||
var lastSection: String? = null
|
||||
val stringTokenizer = StringTokenizer(str, CodeCompiler2.split, true)
|
||||
while (stringTokenizer.hasMoreTokens()) {
|
||||
val code = stringTokenizer.nextToken()
|
||||
when (code) {
|
||||
"\n" -> {
|
||||
if (codeBlockType != CompileConfiguration.CodeBlockType.Note && codeBlockType != CompileConfiguration.CodeBlockType.Section && lineRendering) {
|
||||
renderLineContent(
|
||||
startIndex,
|
||||
lastSection,
|
||||
colors,
|
||||
lineNum,
|
||||
keyBuilder,
|
||||
valueBuilder
|
||||
)
|
||||
}
|
||||
lineNum++
|
||||
column = 0
|
||||
lineRendering = true
|
||||
startIndex = -1
|
||||
codeBlockType = CompileConfiguration.CodeBlockType.Key
|
||||
keyBuilder.clear()
|
||||
valueBuilder.clear()
|
||||
}
|
||||
" ", ",", "/" -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
|
||||
valueBuilder.append(code)
|
||||
}
|
||||
column += code.length
|
||||
}
|
||||
":" -> {
|
||||
if (lastSection != null && codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
codeBlockType = CompileConfiguration.CodeBlockType.Value
|
||||
colors.addIfNeeded(lineNum, column, EditorColorScheme.TEXT_NORMAL)
|
||||
column += code.length
|
||||
}
|
||||
}
|
||||
"\r" -> {
|
||||
}
|
||||
"(", ")", "=", "%", "." -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
if (codeBlockType == CompileConfiguration.CodeBlockType.Value || codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
|
||||
valueBuilder.append(code)
|
||||
}
|
||||
column += code.length
|
||||
}
|
||||
"}" -> {
|
||||
if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
|
||||
colors.addIfNeeded(
|
||||
lineNum,
|
||||
column,
|
||||
EditorColorScheme.TEXT_NORMAL
|
||||
)
|
||||
codeBlockType = CompileConfiguration.CodeBlockType.Value
|
||||
valueBuilder.append(code)
|
||||
}
|
||||
column += code.length
|
||||
}
|
||||
}
|
||||
"{" -> {
|
||||
if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
|
||||
lineRendering = false
|
||||
codeBlockType = CompileConfiguration.CodeBlockType.VariableName
|
||||
valueBuilder.append(code)
|
||||
}
|
||||
column += code.length
|
||||
}
|
||||
}
|
||||
else -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
|
||||
val symbol = "."
|
||||
val symbolIndex = code.indexOf(symbol)
|
||||
if (symbolIndex > -1) {
|
||||
//渲染 ${节.键} 的格式
|
||||
val sectionSpan =
|
||||
Span.obtain(column, EditorColorScheme.FUNCTION_NAME)
|
||||
colors.add(
|
||||
lineNum,
|
||||
sectionSpan
|
||||
)
|
||||
val symbolSpan =
|
||||
Span.obtain(
|
||||
column + symbolIndex,
|
||||
EditorColorScheme.TEXT_NORMAL
|
||||
)
|
||||
colors.add(
|
||||
lineNum,
|
||||
symbolSpan
|
||||
)
|
||||
val keySpan = Span.obtain(
|
||||
column + symbolIndex + symbol.length,
|
||||
EditorColorScheme.KEYWORD
|
||||
)
|
||||
colors.add(lineNum, keySpan)
|
||||
// override fun analyze(
|
||||
// content: CharSequence,
|
||||
// colors: TextAnalyzeResult,
|
||||
// delegate: TextAnalyzer.AnalyzeThread.Delegate
|
||||
// ) {
|
||||
// //添加换行符作为结束符
|
||||
// val str = content.toString() + "\n"
|
||||
// if (str.isBlank() || codeDataBase == null) {
|
||||
// return
|
||||
// }
|
||||
// val lineParser = LineParser()
|
||||
// lineParser.parserSymbol = true
|
||||
// lineParser.symbol = "_"
|
||||
// colors.addNormalIfNull()
|
||||
// if (delegate.shouldAnalyze()) {
|
||||
// labels.clear()
|
||||
// localVariableNameList.clear()
|
||||
// var codeBlockType: CompileConfiguration.CodeBlockType =
|
||||
// CompileConfiguration.CodeBlockType.Key
|
||||
// var lineNum = 0
|
||||
// val keyBuilder = StringBuilder()
|
||||
// val valueBuilder = StringBuilder()
|
||||
// var column = 0
|
||||
// var startIndex = -1
|
||||
// //是否执行二次渲染,用于判断值是否合法
|
||||
// var lineRendering = true
|
||||
// var lastSection: String? = null
|
||||
// val stringTokenizer = StringTokenizer(str, CodeCompiler2.split, true)
|
||||
// while (stringTokenizer.hasMoreTokens()) {
|
||||
// val code = stringTokenizer.nextToken()
|
||||
// when (code) {
|
||||
// "\n" -> {
|
||||
// if (codeBlockType != CompileConfiguration.CodeBlockType.Note && codeBlockType != CompileConfiguration.CodeBlockType.Section && lineRendering) {
|
||||
// renderLineContent(
|
||||
// startIndex,
|
||||
// lastSection,
|
||||
// colors,
|
||||
// lineNum,
|
||||
// keyBuilder,
|
||||
// valueBuilder
|
||||
// )
|
||||
// }
|
||||
// lineNum++
|
||||
// column = 0
|
||||
// lineRendering = true
|
||||
// startIndex = -1
|
||||
// codeBlockType = CompileConfiguration.CodeBlockType.Key
|
||||
// keyBuilder.clear()
|
||||
// valueBuilder.clear()
|
||||
// }
|
||||
// " ", ",", "/" -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
// if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
|
||||
// valueBuilder.append(code)
|
||||
// }
|
||||
// column += code.length
|
||||
// }
|
||||
// ":" -> {
|
||||
// if (lastSection != null && codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
// codeBlockType = CompileConfiguration.CodeBlockType.Value
|
||||
// colors.addIfNeeded(lineNum, column, EditorColorScheme.TEXT_NORMAL)
|
||||
// column += code.length
|
||||
// }
|
||||
// }
|
||||
// "\r" -> {
|
||||
// }
|
||||
// "(", ")", "=", "%", "." -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
// if (codeBlockType == CompileConfiguration.CodeBlockType.Value || codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
|
||||
// valueBuilder.append(code)
|
||||
// }
|
||||
// column += code.length
|
||||
// }
|
||||
// "}" -> {
|
||||
// if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
// if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
|
||||
// colors.addIfNeeded(
|
||||
// lineNum,
|
||||
// column,
|
||||
// EditorColorScheme.TEXT_NORMAL
|
||||
// )
|
||||
// codeBlockType = CompileConfiguration.CodeBlockType.Value
|
||||
// valueBuilder.append(code)
|
||||
// }
|
||||
// column += code.length
|
||||
// }
|
||||
// }
|
||||
// "{" -> {
|
||||
// if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
// if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
|
||||
// lineRendering = false
|
||||
// codeBlockType = CompileConfiguration.CodeBlockType.VariableName
|
||||
// valueBuilder.append(code)
|
||||
// }
|
||||
// column += code.length
|
||||
// }
|
||||
// }
|
||||
// else -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
|
||||
// if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
|
||||
// val symbol = "."
|
||||
// val symbolIndex = code.indexOf(symbol)
|
||||
// if (symbolIndex > -1) {
|
||||
// //渲染 ${节.键} 的格式
|
||||
// val sectionSpan =
|
||||
// Span.obtain(column, EditorColorScheme.FUNCTION_NAME)
|
||||
// colors.add(
|
||||
// lineNum,
|
||||
// sectionSpan
|
||||
// )
|
||||
// val symbolSpan =
|
||||
// Span.obtain(
|
||||
// column + symbolIndex,
|
||||
// EditorColorScheme.TEXT_NORMAL
|
||||
// )
|
||||
// colors.add(
|
||||
// lineNum,
|
||||
// symbolSpan
|
||||
// )
|
||||
// val keySpan = Span.obtain(
|
||||
// column + symbolIndex + symbol.length,
|
||||
// EditorColorScheme.KEYWORD
|
||||
// )
|
||||
// colors.add(lineNum, keySpan)
|
||||
//
|
||||
// } else {
|
||||
// //渲染 ${变量名} 的个格式
|
||||
// localVariableNameList.add(LocalVariableName(code, lineNum))
|
||||
// val span = Span.obtain(column, EditorColorScheme.LITERAL)
|
||||
// colors.add(
|
||||
// lineNum,
|
||||
// span
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// //不是变量名的话
|
||||
// if (code.startsWith("#")) {
|
||||
// codeBlockType = CompileConfiguration.CodeBlockType.Note
|
||||
// colors.addIfNeeded(lineNum, column, EditorColorScheme.COMMENT)
|
||||
// } else if (code.startsWith("[") && code.endsWith("]")) {
|
||||
// codeBlockType = CompileConfiguration.CodeBlockType.Section
|
||||
// lastSection = code
|
||||
// labels.add(
|
||||
// NavigationItem(
|
||||
// lineNum,
|
||||
// code.substring(1, code.length - 1)
|
||||
// )
|
||||
// )
|
||||
// val span = Span.obtain(0, EditorColorScheme.FUNCTION_NAME)
|
||||
// colors.add(
|
||||
// lineNum,
|
||||
// span
|
||||
// )
|
||||
// } else {
|
||||
// if (lastSection != null) {
|
||||
// //当代码属于某个节时渲染
|
||||
// if (codeBlockType == CompileConfiguration.CodeBlockType.Key) {
|
||||
// keyBuilder.append(code)
|
||||
// if (hasCode(code)) {
|
||||
// colors.addIfNeeded(
|
||||
// lineNum,
|
||||
// column,
|
||||
// EditorColorScheme.KEYWORD
|
||||
// )
|
||||
// val trueCode = getCode(code)
|
||||
// if (trueCode == "@define" || trueCode == "@global") {
|
||||
// codeBlockType =
|
||||
// CompileConfiguration.CodeBlockType.VariableName
|
||||
// }
|
||||
// } else {
|
||||
// if (code.contains("_")) {
|
||||
// val parser = LineParser(code)
|
||||
// parser.symbol = "_"
|
||||
// parser.parserSymbol = true
|
||||
// //局部渲染偏移
|
||||
// var offset = 0
|
||||
// parser.analyse { temLineNum, lineData, isEnd ->
|
||||
// if (lineData == parser.symbol) {
|
||||
// //是符号,添加符号跨度
|
||||
// colors.addIfNeeded(
|
||||
// lineNum, column + offset,
|
||||
// EditorColorScheme.TEXT_NORMAL
|
||||
// )
|
||||
// } else {
|
||||
// if (hasCode(lineData)) {
|
||||
// colors.addIfNeeded(
|
||||
// lineNum,
|
||||
// column + offset,
|
||||
// EditorColorScheme.KEYWORD
|
||||
// )
|
||||
// } else {
|
||||
// colors.addIfNeeded(
|
||||
// lineNum, column + offset,
|
||||
// EditorColorScheme.TEXT_NORMAL
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// offset += lineData.length
|
||||
// true
|
||||
// }
|
||||
// } else {
|
||||
// val span =
|
||||
// Span.obtain(
|
||||
// column,
|
||||
// EditorColorScheme.TEXT_NORMAL
|
||||
// )
|
||||
// colors.add(
|
||||
// lineNum,
|
||||
// span
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (startIndex == -1) {
|
||||
// startIndex = column
|
||||
// }
|
||||
// valueBuilder.append(getCode(code))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// column += code.length
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// colors.navigation = labels
|
||||
// colors.determine(lineNum)
|
||||
// }
|
||||
// }
|
||||
|
||||
} else {
|
||||
//渲染 ${变量名} 的个格式
|
||||
localVariableNameList.add(LocalVariableName(code, lineNum))
|
||||
val span = Span.obtain(column, EditorColorScheme.LITERAL)
|
||||
colors.add(
|
||||
lineNum,
|
||||
span
|
||||
)
|
||||
}
|
||||
} else {
|
||||
//不是变量名的话
|
||||
if (code.startsWith("#")) {
|
||||
codeBlockType = CompileConfiguration.CodeBlockType.Note
|
||||
colors.addIfNeeded(lineNum, column, EditorColorScheme.COMMENT)
|
||||
} else if (code.startsWith("[") && code.endsWith("]")) {
|
||||
codeBlockType = CompileConfiguration.CodeBlockType.Section
|
||||
lastSection = code
|
||||
labels.add(
|
||||
NavigationItem(
|
||||
lineNum,
|
||||
code.substring(1, code.length - 1)
|
||||
)
|
||||
)
|
||||
val span = Span.obtain(0, EditorColorScheme.FUNCTION_NAME)
|
||||
colors.add(
|
||||
lineNum,
|
||||
span
|
||||
)
|
||||
} else {
|
||||
if (lastSection != null) {
|
||||
//当代码属于某个节时渲染
|
||||
if (codeBlockType == CompileConfiguration.CodeBlockType.Key) {
|
||||
keyBuilder.append(code)
|
||||
if (hasCode(code)) {
|
||||
colors.addIfNeeded(
|
||||
lineNum,
|
||||
column,
|
||||
EditorColorScheme.KEYWORD
|
||||
)
|
||||
val trueCode = getCode(code)
|
||||
if (trueCode == "@define" || trueCode == "@global") {
|
||||
codeBlockType =
|
||||
CompileConfiguration.CodeBlockType.VariableName
|
||||
}
|
||||
} else {
|
||||
if (code.contains("_")) {
|
||||
val parser = LineParser(code)
|
||||
parser.symbol = "_"
|
||||
parser.parserSymbol = true
|
||||
//局部渲染偏移
|
||||
var offset = 0
|
||||
parser.analyse { temLineNum, lineData, isEnd ->
|
||||
if (lineData == parser.symbol) {
|
||||
//是符号,添加符号跨度
|
||||
colors.addIfNeeded(
|
||||
lineNum, column + offset,
|
||||
EditorColorScheme.TEXT_NORMAL
|
||||
)
|
||||
} else {
|
||||
if (hasCode(lineData)) {
|
||||
colors.addIfNeeded(
|
||||
lineNum,
|
||||
column + offset,
|
||||
EditorColorScheme.KEYWORD
|
||||
)
|
||||
} else {
|
||||
colors.addIfNeeded(
|
||||
lineNum, column + offset,
|
||||
EditorColorScheme.TEXT_NORMAL
|
||||
)
|
||||
}
|
||||
}
|
||||
offset += lineData.length
|
||||
true
|
||||
}
|
||||
} else {
|
||||
val span =
|
||||
Span.obtain(
|
||||
column,
|
||||
EditorColorScheme.TEXT_NORMAL
|
||||
)
|
||||
colors.add(
|
||||
lineNum,
|
||||
span
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (startIndex == -1) {
|
||||
startIndex = column
|
||||
}
|
||||
valueBuilder.append(getCode(code))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
column += code.length
|
||||
}
|
||||
}
|
||||
}
|
||||
colors.navigation = labels
|
||||
colors.determine(lineNum)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染行内容
|
||||
* @param startIndex Int 冒号的起初位置
|
||||
* @param lastSection String? 最后的节
|
||||
* @param colors TextAnalyzeResult 颜色渲染
|
||||
* @param lineNum Int 行号
|
||||
* @param keyBuilder StringBuilder
|
||||
* @param valueBuilder StringBuilder
|
||||
*/
|
||||
private fun renderLineContent(
|
||||
startIndex: Int,
|
||||
lastSection: String?,
|
||||
colors: TextAnalyzeResult,
|
||||
lineNum: Int,
|
||||
keyBuilder: StringBuilder,
|
||||
valueBuilder: StringBuilder
|
||||
) {
|
||||
//不在任何节内
|
||||
if (lastSection == null) {
|
||||
val valueErrorSpan =
|
||||
Span.obtain(
|
||||
0,
|
||||
EditorColorScheme.FUNCTION_NAME
|
||||
)
|
||||
valueErrorSpan.problemFlags = Span.FLAG_ERROR
|
||||
colors.add(lineNum, valueErrorSpan)
|
||||
return
|
||||
}
|
||||
if (startIndex > -1) {
|
||||
//值是否合法
|
||||
if (isValid(
|
||||
keyBuilder.toString(),
|
||||
valueBuilder.toString().trim()
|
||||
)
|
||||
) {
|
||||
if (hasCode(valueBuilder.toString().trim(), true)) {
|
||||
colors.addIfNeeded(
|
||||
lineNum,
|
||||
startIndex,
|
||||
EditorColorScheme.KEYWORD
|
||||
)
|
||||
} else {
|
||||
colors.addIfNeeded(
|
||||
lineNum,
|
||||
startIndex,
|
||||
EditorColorScheme.TEXT_NORMAL
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val valueErrorSpan =
|
||||
Span.obtain(
|
||||
startIndex,
|
||||
EditorColorScheme.FUNCTION_NAME
|
||||
)
|
||||
valueErrorSpan.problemFlags = Span.FLAG_ERROR
|
||||
colors.add(lineNum, valueErrorSpan)
|
||||
}
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * 渲染行内容
|
||||
// * @param startIndex Int 冒号的起初位置
|
||||
// * @param lastSection String? 最后的节
|
||||
// * @param colors TextAnalyzeResult 颜色渲染
|
||||
// * @param lineNum Int 行号
|
||||
// * @param keyBuilder StringBuilder
|
||||
// * @param valueBuilder StringBuilder
|
||||
// */
|
||||
// private fun renderLineContent(
|
||||
// startIndex: Int,
|
||||
// lastSection: String?,
|
||||
// colors: TextAnalyzeResult,
|
||||
// lineNum: Int,
|
||||
// keyBuilder: StringBuilder,
|
||||
// valueBuilder: StringBuilder
|
||||
// ) {
|
||||
// //不在任何节内
|
||||
// if (lastSection == null) {
|
||||
// val valueErrorSpan =
|
||||
// Span.obtain(
|
||||
// 0,
|
||||
// EditorColorScheme.FUNCTION_NAME
|
||||
// )
|
||||
// valueErrorSpan.problemFlags = Span.FLAG_ERROR
|
||||
// colors.add(lineNum, valueErrorSpan)
|
||||
// return
|
||||
// }
|
||||
// if (startIndex > -1) {
|
||||
// //值是否合法
|
||||
// if (isValid(
|
||||
// keyBuilder.toString(),
|
||||
// valueBuilder.toString().trim()
|
||||
// )
|
||||
// ) {
|
||||
// if (hasCode(valueBuilder.toString().trim(), true)) {
|
||||
// colors.addIfNeeded(
|
||||
// lineNum,
|
||||
// startIndex,
|
||||
// EditorColorScheme.KEYWORD
|
||||
// )
|
||||
// } else {
|
||||
// colors.addIfNeeded(
|
||||
// lineNum,
|
||||
// startIndex,
|
||||
// EditorColorScheme.TEXT_NORMAL
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// val valueErrorSpan =
|
||||
// Span.obtain(
|
||||
// startIndex,
|
||||
// EditorColorScheme.FUNCTION_NAME
|
||||
// )
|
||||
// valueErrorSpan.problemFlags = Span.FLAG_ERROR
|
||||
// colors.add(lineNum, valueErrorSpan)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
|
|
433
app/src/main/java/com/coldmint/rust/pro/edit/RustAutoComplete.kt
Normal file
433
app/src/main/java/com/coldmint/rust/pro/edit/RustAutoComplete.kt
Normal file
|
@ -0,0 +1,433 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.core.CodeCompiler2
|
||||
import com.coldmint.rust.core.SourceFile
|
||||
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||
import com.coldmint.rust.core.database.code.SectionInfo
|
||||
import com.coldmint.rust.core.database.file.FileDataBase
|
||||
import com.coldmint.rust.core.interfaces.EnglishMode
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.core.tool.LineParser
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionItem
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
import java.util.ArrayList
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* @author Cold Mint
|
||||
* @date 2022/1/25 17:32
|
||||
*/
|
||||
class RustAutoComplete(val context: Context) : EnglishMode {
|
||||
|
||||
private val debugKey = "自动完成器"
|
||||
private var codeDataBase: CodeDataBase? = null
|
||||
private val executorService = Executors.newCachedThreadPool()
|
||||
private var fileDataBase: FileDataBase? = null
|
||||
private var codeEditor: CodeEditor? = null
|
||||
|
||||
private var sectionNameMap: HashMap<String, String> = HashMap()
|
||||
|
||||
private val lineParser by lazy {
|
||||
val tem = LineParser()
|
||||
tem.symbol = ","
|
||||
tem
|
||||
}
|
||||
private val identifiersPromptNumber: Int by lazy {
|
||||
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
|
||||
}
|
||||
|
||||
//类型转换器
|
||||
private val completionItemConverter: CompletionItemConverter by lazy {
|
||||
CompletionItemConverter.instance.init(context)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
var keyWord = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为英文模式
|
||||
*/
|
||||
private var isEnglishMode = false
|
||||
|
||||
/**
|
||||
* 设置源文件目录
|
||||
* @param sourceFolder String
|
||||
*/
|
||||
fun setSourceFolder(sourceFolder: String) {
|
||||
DebugHelper.printLog(debugKey, "已设置源文件目录" + sourceFolder, "设置源文件目录")
|
||||
completionItemConverter.setSourceFilePath(sourceFolder)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件转换器配置
|
||||
* @param sourceFilePath String
|
||||
* @param rootCodeName String
|
||||
* @param modFolder String
|
||||
*/
|
||||
fun setConfigurationFileConversion(
|
||||
sourceFilePath: String,
|
||||
rootCodeName: String,
|
||||
modFolder: String
|
||||
) {
|
||||
completionItemConverter.configurationFileConversion(sourceFilePath, rootCodeName, modFolder)
|
||||
}
|
||||
|
||||
/**
|
||||
*设置文件数据库
|
||||
* @param fileDataBase FileDataBase?
|
||||
*/
|
||||
fun setFileDataBase(fileDataBase: FileDataBase?) {
|
||||
this.fileDataBase = fileDataBase
|
||||
}
|
||||
|
||||
|
||||
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
||||
this.codeDataBase = codeDataBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置代码编辑器
|
||||
* @param codeEditor CodeEditor?
|
||||
*/
|
||||
fun setCodeEditor(codeEditor: CodeEditor?) {
|
||||
this.codeEditor = codeEditor
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取节类型(永远返回英文)
|
||||
* @param section String
|
||||
* @return String
|
||||
*/
|
||||
fun getSectionType(section: String): String {
|
||||
if (sectionNameMap.containsKey(section)) {
|
||||
return sectionNameMap[section] ?: SourceFile.getSectionType(section)
|
||||
}
|
||||
val result = if (isEnglishMode) {
|
||||
SourceFile.getSectionType(section)
|
||||
} else {
|
||||
val sectionInfo = codeDataBase!!.getSectionDao()
|
||||
.findSectionInfoByTranslate(SourceFile.getSectionType(section))
|
||||
sectionInfo?.code ?: SourceFile.getSectionType(section)
|
||||
}
|
||||
sectionNameMap[section] = result
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 请求自动完成
|
||||
* @param prefix String?
|
||||
* @param completionPublisher CompletionPublisher
|
||||
* @param line Int
|
||||
* @param column Int
|
||||
*/
|
||||
fun requireAutoComplete(
|
||||
prefix: String?,
|
||||
completionPublisher: CompletionPublisher,
|
||||
line: Int,
|
||||
column: Int
|
||||
) {
|
||||
if (codeEditor == null) {
|
||||
throw NullPointerException("未绑定编辑框")
|
||||
}
|
||||
if (fileDataBase == null) {
|
||||
throw NullPointerException("未绑定文件数据库")
|
||||
|
||||
}
|
||||
if (codeDataBase == null) {
|
||||
throw NullPointerException("未绑定代码数据库")
|
||||
}
|
||||
if (prefix == null) {
|
||||
return
|
||||
}
|
||||
|
||||
keyWord = prefix
|
||||
val temCodeEditor: CodeEditor = codeEditor!!
|
||||
val lineData = temCodeEditor.text.getLineString(line)
|
||||
if (lineData.startsWith('[')) {
|
||||
//搜索节
|
||||
val name = lineData.subSequence(1, lineData.length).toString()
|
||||
val list = if (isEnglishMode) {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
||||
} else {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
||||
}
|
||||
list?.forEach {
|
||||
completionPublisher.addItem(completionItemConverter.sectionInfoToCompletionItem(it))
|
||||
}
|
||||
} else {
|
||||
val key = ":"
|
||||
val keyIndex = lineData.lastIndexOf(key)
|
||||
if (keyIndex > -1) {
|
||||
//检查是否可响应变量
|
||||
val start = "\${"
|
||||
val end = "}"
|
||||
val startIndex = lineData.lastIndexOf(start)
|
||||
if (startIndex > -1) {
|
||||
val endIndex = lineData.lastIndexOf(end)
|
||||
if (endIndex < startIndex) {
|
||||
//如果}的位置小于${的位置,说明没有闭合
|
||||
val keyWord =
|
||||
lineData.subSequence(startIndex + start.length, lineData.length)
|
||||
.toString()
|
||||
val previousText =
|
||||
lineData.subSequence(keyIndex + key.length, startIndex).toString()
|
||||
if (keyWord.isNotBlank()) {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
if (it.name.contains(keyWord)) {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
RustAutoComplete.keyWord = keyWord
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// val value =
|
||||
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
|
||||
// Log.d("值", value)
|
||||
//搜索值
|
||||
// frontIndex 前面冒号的位置
|
||||
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
|
||||
val keyValue = if (frontIndex > -1) {
|
||||
lineData.subSequence(frontIndex + key.length, keyIndex)
|
||||
} else {
|
||||
lineData.subSequence(0, keyIndex)
|
||||
}
|
||||
|
||||
val codeInfo =
|
||||
if (isEnglishMode) {
|
||||
codeDataBase!!.getCodeDao().findCodeByCode(keyValue.toString())
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao().findCodeByTranslate(keyValue.toString())
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + prefix + "]",
|
||||
"值检查"
|
||||
)
|
||||
if (codeInfo != null) {
|
||||
val typeInfo = completionItemConverter.getValueType(codeInfo.type)
|
||||
//获取代码的关联列表
|
||||
if (typeInfo != null && typeInfo.list.isNotBlank()) {
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
|
||||
)
|
||||
lineParser.text = typeInfo.list
|
||||
lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
//分析关联提示项目
|
||||
val temCodeInfo =
|
||||
codeDataBase!!.getCodeDao().findCodeByCode(lineData)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (temCodeInfo == null) {
|
||||
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
|
||||
val fileType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
)
|
||||
|
||||
val fileInfo = fileDataBase!!.getFileInfoDao()
|
||||
.searchFileInfoByNameAndType(
|
||||
prefix,
|
||||
fileType.toString(),
|
||||
identifiersPromptNumber
|
||||
)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
|
||||
?: -1) + "]个结果",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (fileInfo != null && fileInfo.isNotEmpty()) {
|
||||
for (fileTable in fileInfo) {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.fileTableToCompletionItem(
|
||||
fileTable
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
//用户自动值类型提示
|
||||
val customType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
fileDataBase!!.getValueDao()
|
||||
.searchValueByKey(
|
||||
prefix,
|
||||
customType,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
?.forEach {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.valueTableToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
|
||||
val type = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
val list = if (isEnglishMode
|
||||
) {
|
||||
codeDataBase!!.getCodeDao().findCodeByCodeInType(
|
||||
prefix,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao().findCodeByTranslateInType(
|
||||
prefix,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
|
||||
"值类型引用"
|
||||
)
|
||||
if (!list.isNullOrEmpty()) {
|
||||
list.forEach {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@section") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
val section = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
// codeEditor!!.textAnalyzeResult.navigation.forEach {
|
||||
// if (section == getSectionType(it.label)) {
|
||||
// result.add(
|
||||
// completionItemConverter.navigationItemToCompletionItem(
|
||||
// it
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
//无法分析的关联项目
|
||||
// result.add(
|
||||
// CompletionItem(
|
||||
// lineData,
|
||||
// String.format(
|
||||
// completionItemConverter.associatedTip,
|
||||
// codeInfo.translate
|
||||
// )
|
||||
// )
|
||||
// )
|
||||
}
|
||||
} else {
|
||||
|
||||
val show = if (isEnglishMode) {
|
||||
temCodeInfo.code.contains(prefix)
|
||||
} else {
|
||||
temCodeInfo.translate.contains(prefix)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + prefix + "关键字[" + show + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (show) {
|
||||
completionPublisher.addItem(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
temCodeInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//如果不包含:搜索键
|
||||
// val navigationList = temCodeEditor.textAnalyzeResult.navigation
|
||||
// var section: String? = null
|
||||
// if (navigationList != null && navigationList.isNotEmpty()) {
|
||||
// for (navigation in navigationList) {
|
||||
// if (navigation.line > line) {
|
||||
// break
|
||||
// } else {
|
||||
// section = navigation.label
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// //如果不在任何节内
|
||||
// if (section == null) {
|
||||
// return@submit
|
||||
// }
|
||||
// val trueSection = getSectionType(section)
|
||||
// val list = if (isEnglishMode) {
|
||||
// codeDataBase!!.getCodeDao().findCodeByEnglishCodeKeyFromSection(
|
||||
// prefix,
|
||||
// trueSection,
|
||||
// identifiersPromptNumber
|
||||
// )
|
||||
// } else {
|
||||
// codeDataBase!!.getCodeDao()
|
||||
// .findCodeByKeyFromSection(prefix, trueSection, identifiersPromptNumber)
|
||||
// }
|
||||
// if (list != null && list.isNotEmpty()) {
|
||||
// list.forEach {
|
||||
// result.add(
|
||||
// completionItemConverter.codeInfoToCompletionItem(it)
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun isEnglishMode(): Boolean {
|
||||
return isEnglishMode
|
||||
}
|
||||
|
||||
override fun setEnglish(englishMode: Boolean) {
|
||||
this.isEnglishMode = englishMode
|
||||
completionItemConverter.setEnglish(englishMode)
|
||||
}
|
||||
}
|
|
@ -1,439 +0,0 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.core.CodeCompiler2
|
||||
import com.coldmint.rust.core.SourceFile
|
||||
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||
import com.coldmint.rust.core.database.code.SectionInfo
|
||||
import com.coldmint.rust.core.database.file.FileDataBase
|
||||
import com.coldmint.rust.core.interfaces.EnglishMode
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import com.coldmint.rust.core.tool.LineParser
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.CompletionItemConverter
|
||||
import io.github.rosemoe.sora.data.CompletionItem
|
||||
import io.github.rosemoe.sora.interfaces.AutoCompleteProvider
|
||||
import io.github.rosemoe.sora.text.TextAnalyzeResult
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
import java.util.ArrayList
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* @author Cold Mint
|
||||
* @date 2022/1/25 17:32
|
||||
*/
|
||||
class RustAutoComplete2(val context: Context) : AutoCompleteProvider, EnglishMode {
|
||||
|
||||
private val result: ArrayList<CompletionItem> by lazy {
|
||||
ArrayList()
|
||||
}
|
||||
private val debugKey = "自动完成器"
|
||||
private var codeDataBase: CodeDataBase? = null
|
||||
private val executorService = Executors.newCachedThreadPool()
|
||||
private var fileDataBase: FileDataBase? = null
|
||||
private var codeEditor: CodeEditor? = null
|
||||
|
||||
private var sectionNameMap: HashMap<String, String> = HashMap()
|
||||
|
||||
private val lineParser by lazy {
|
||||
val tem = LineParser()
|
||||
tem.symbol = ","
|
||||
tem
|
||||
}
|
||||
private val identifiersPromptNumber: Int by lazy {
|
||||
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
|
||||
}
|
||||
|
||||
//类型转换器
|
||||
private val completionItemConverter: CompletionItemConverter by lazy {
|
||||
CompletionItemConverter.instance.init(context)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
var keyWord = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为英文模式
|
||||
*/
|
||||
private var isEnglishMode = false
|
||||
|
||||
/**
|
||||
* 设置源文件目录
|
||||
* @param sourceFolder String
|
||||
*/
|
||||
fun setSourceFolder(sourceFolder: String) {
|
||||
DebugHelper.printLog(debugKey, "已设置源文件目录" + sourceFolder, "设置源文件目录")
|
||||
completionItemConverter.setSourceFilePath(sourceFolder)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置文件转换器配置
|
||||
* @param sourceFilePath String
|
||||
* @param rootCodeName String
|
||||
* @param modFolder String
|
||||
*/
|
||||
fun setConfigurationFileConversion(
|
||||
sourceFilePath: String,
|
||||
rootCodeName: String,
|
||||
modFolder: String
|
||||
) {
|
||||
completionItemConverter.configurationFileConversion(sourceFilePath, rootCodeName, modFolder)
|
||||
}
|
||||
|
||||
/**
|
||||
*设置文件数据库
|
||||
* @param fileDataBase FileDataBase?
|
||||
*/
|
||||
fun setFileDataBase(fileDataBase: FileDataBase?) {
|
||||
this.fileDataBase = fileDataBase
|
||||
}
|
||||
|
||||
|
||||
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
||||
this.codeDataBase = codeDataBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置代码编辑器
|
||||
* @param codeEditor CodeEditor?
|
||||
*/
|
||||
fun setCodeEditor(codeEditor: CodeEditor?) {
|
||||
this.codeEditor = codeEditor
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取节类型(永远返回英文)
|
||||
* @param section String
|
||||
* @return String
|
||||
*/
|
||||
fun getSectionType(section: String): String {
|
||||
if (sectionNameMap.containsKey(section)) {
|
||||
return sectionNameMap[section] ?: SourceFile.getSectionType(section)
|
||||
}
|
||||
val result = if (isEnglishMode) {
|
||||
SourceFile.getSectionType(section)
|
||||
} else {
|
||||
val sectionInfo = codeDataBase!!.getSectionDao()
|
||||
.findSectionInfoByTranslate(SourceFile.getSectionType(section))
|
||||
sectionInfo?.code ?: SourceFile.getSectionType(section)
|
||||
}
|
||||
sectionNameMap[section] = result
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
override fun getAutoCompleteItems(
|
||||
prefix: String?,
|
||||
analyzeResult: TextAnalyzeResult?,
|
||||
line: Int,
|
||||
column: Int
|
||||
): MutableList<CompletionItem> {
|
||||
if (codeEditor == null) {
|
||||
throw NullPointerException("未绑定编辑框")
|
||||
return ArrayList<CompletionItem>()
|
||||
}
|
||||
if (fileDataBase == null) {
|
||||
throw NullPointerException("未绑定文件数据库")
|
||||
return ArrayList<CompletionItem>()
|
||||
}
|
||||
if (codeDataBase == null) {
|
||||
throw NullPointerException("未绑定代码数据库")
|
||||
return ArrayList<CompletionItem>()
|
||||
}
|
||||
if (prefix == null) {
|
||||
return ArrayList<CompletionItem>()
|
||||
}
|
||||
keyWord = prefix
|
||||
val future = executorService.submit {
|
||||
result.clear()
|
||||
val temCodeEditor: CodeEditor = codeEditor!!
|
||||
val lineData = temCodeEditor.text.getLineString(line)
|
||||
if (lineData.startsWith('[')) {
|
||||
//搜索节
|
||||
val name = lineData.subSequence(1, lineData.length).toString()
|
||||
val list = if (isEnglishMode) {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
|
||||
} else {
|
||||
codeDataBase!!.getSectionDao()
|
||||
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
|
||||
}
|
||||
list?.forEach {
|
||||
result.add(completionItemConverter.sectionInfoToCompletionItem(it))
|
||||
}
|
||||
} else {
|
||||
val key = ":"
|
||||
val keyIndex = lineData.lastIndexOf(key)
|
||||
if (keyIndex > -1) {
|
||||
//检查是否可响应变量
|
||||
val start = "\${"
|
||||
val end = "}"
|
||||
val startIndex = lineData.lastIndexOf(start)
|
||||
if (startIndex > -1) {
|
||||
val endIndex = lineData.lastIndexOf(end)
|
||||
if (endIndex < startIndex) {
|
||||
//如果}的位置小于${的位置,说明没有闭合
|
||||
val keyWord =
|
||||
lineData.subSequence(startIndex + start.length, lineData.length)
|
||||
.toString()
|
||||
val previousText =
|
||||
lineData.subSequence(keyIndex + key.length, startIndex).toString()
|
||||
if (keyWord.isNotBlank()) {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
if (it.name.contains(keyWord)) {
|
||||
result.add(
|
||||
completionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
RustAnalyzer.localVariableNameList.forEach {
|
||||
result.add(
|
||||
completionItemConverter.localVariableNameToCompletionItem(
|
||||
it, previousText
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
RustAutoComplete2.keyWord = keyWord
|
||||
return@submit
|
||||
}
|
||||
}
|
||||
|
||||
// val value =
|
||||
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
|
||||
// Log.d("值", value)
|
||||
//搜索值
|
||||
// frontIndex 前面冒号的位置
|
||||
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
|
||||
val keyValue = if (frontIndex > -1) {
|
||||
lineData.subSequence(frontIndex + key.length, keyIndex)
|
||||
} else {
|
||||
lineData.subSequence(0, keyIndex)
|
||||
}
|
||||
|
||||
val codeInfo =
|
||||
if (isEnglishMode) {
|
||||
codeDataBase!!.getCodeDao().findCodeByCode(keyValue.toString())
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao().findCodeByTranslate(keyValue.toString())
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + prefix + "]",
|
||||
"值检查"
|
||||
)
|
||||
if (codeInfo != null) {
|
||||
val typeInfo = completionItemConverter.getValueType(codeInfo.type)
|
||||
//获取代码的关联列表
|
||||
if (typeInfo != null && typeInfo.list.isNotBlank()) {
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
|
||||
)
|
||||
lineParser.text = typeInfo.list
|
||||
lineParser.analyse { lineNum, lineData, isEnd ->
|
||||
//分析关联提示项目
|
||||
val temCodeInfo =
|
||||
codeDataBase!!.getCodeDao().findCodeByCode(lineData)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (temCodeInfo == null) {
|
||||
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
|
||||
val fileType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
)
|
||||
|
||||
val fileInfo = fileDataBase!!.getFileInfoDao()
|
||||
.searchFileInfoByNameAndType(
|
||||
prefix,
|
||||
fileType.toString(),
|
||||
identifiersPromptNumber
|
||||
)
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
|
||||
?: -1) + "]个结果",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (fileInfo != null && fileInfo.isNotEmpty()) {
|
||||
for (fileTable in fileInfo) {
|
||||
result.add(
|
||||
completionItemConverter.fileTableToCompletionItem(
|
||||
fileTable
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
//用户自动值类型提示
|
||||
val customType = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
fileDataBase!!.getValueDao()
|
||||
.searchValueByKey(
|
||||
prefix,
|
||||
customType,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
?.forEach {
|
||||
result.add(
|
||||
completionItemConverter.valueTableToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
|
||||
val type = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
val list = if (isEnglishMode
|
||||
) {
|
||||
codeDataBase!!.getCodeDao().findCodeByCodeInType(
|
||||
prefix,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao().findCodeByTranslateInType(
|
||||
prefix,
|
||||
type,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
|
||||
"值类型引用"
|
||||
)
|
||||
if (!list.isNullOrEmpty()) {
|
||||
list.forEach {
|
||||
result.add(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (lineData.startsWith("@section") && lineData.endsWith(
|
||||
")"
|
||||
)
|
||||
) {
|
||||
val section = lineData.subSequence(
|
||||
lineData.indexOf('(') + 1,
|
||||
lineData.indexOf(')')
|
||||
).toString()
|
||||
codeEditor!!.textAnalyzeResult.navigation.forEach {
|
||||
if (section == getSectionType(it.label)) {
|
||||
result.add(
|
||||
completionItemConverter.navigationItemToCompletionItem(
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//无法分析的关联项目
|
||||
result.add(
|
||||
CompletionItem(
|
||||
lineData,
|
||||
String.format(
|
||||
completionItemConverter.associatedTip,
|
||||
codeInfo.translate
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
||||
val show = if (isEnglishMode) {
|
||||
temCodeInfo.code.contains(prefix)
|
||||
} else {
|
||||
temCodeInfo.translate.contains(prefix)
|
||||
}
|
||||
DebugHelper.printLog(
|
||||
debugKey,
|
||||
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + prefix + "关键字[" + show + "]",
|
||||
"关联提示列表分析"
|
||||
)
|
||||
if (show) {
|
||||
result.add(
|
||||
completionItemConverter.codeInfoToCompletionItem(
|
||||
temCodeInfo
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//如果不包含:搜索键
|
||||
val navigationList = temCodeEditor.textAnalyzeResult.navigation
|
||||
var section: String? = null
|
||||
if (navigationList != null && navigationList.isNotEmpty()) {
|
||||
for (navigation in navigationList) {
|
||||
if (navigation.line > line) {
|
||||
break
|
||||
} else {
|
||||
section = navigation.label
|
||||
}
|
||||
}
|
||||
}
|
||||
//如果不在任何节内
|
||||
if (section == null) {
|
||||
return@submit
|
||||
}
|
||||
val trueSection = getSectionType(section)
|
||||
val list = if (isEnglishMode) {
|
||||
codeDataBase!!.getCodeDao().findCodeByEnglishCodeKeyFromSection(
|
||||
prefix,
|
||||
trueSection,
|
||||
identifiersPromptNumber
|
||||
)
|
||||
} else {
|
||||
codeDataBase!!.getCodeDao()
|
||||
.findCodeByKeyFromSection(prefix, trueSection, identifiersPromptNumber)
|
||||
}
|
||||
if (list != null && list.isNotEmpty()) {
|
||||
list.forEach {
|
||||
result.add(
|
||||
completionItemConverter.codeInfoToCompletionItem(it)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return if (future.get() == null) {
|
||||
result
|
||||
} else {
|
||||
ArrayList<CompletionItem>()
|
||||
}
|
||||
}
|
||||
|
||||
override fun isEnglishMode(): Boolean {
|
||||
return isEnglishMode
|
||||
}
|
||||
|
||||
override fun setEnglish(englishMode: Boolean) {
|
||||
this.isEnglishMode = englishMode
|
||||
completionItemConverter.setEnglish(englishMode)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import com.coldmint.rust.core.dataBean.CompileConfiguration
|
||||
|
||||
/**
|
||||
* Rust代码标记
|
||||
* @property offset Int
|
||||
* @property codeBlockType CodeBlockType
|
||||
*/
|
||||
class RustCodeToken(
|
||||
var offset: Int = 0,
|
||||
var codeBlockType: CompileConfiguration.CodeBlockType = CompileConfiguration.CodeBlockType.Note
|
||||
) {
|
||||
|
||||
|
||||
}
|
|
@ -1,29 +1,30 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Color
|
||||
import android.graphics.Typeface
|
||||
import android.view.ViewGroup
|
||||
import android.view.LayoutInflater
|
||||
import com.coldmint.rust.pro.R
|
||||
import android.widget.TextView
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.Spanned
|
||||
import android.text.style.StyleSpan
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import com.bumptech.glide.Glide
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.util.TypedValue
|
||||
import androidx.core.view.isVisible
|
||||
import com.coldmint.rust.pro.databinding.EditItemBinding
|
||||
import com.coldmint.rust.pro.tool.GlobalMethod
|
||||
import io.github.rosemoe.sora.widget.EditorCompletionAdapter
|
||||
import io.github.rosemoe.sora.widget.component.EditorCompletionAdapter
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Rust完成适配器
|
||||
* @property layoutInflater (LayoutInflater..LayoutInflater?)
|
||||
* @property spannableStringBuilder SpannableStringBuilder
|
||||
* @property colorSpan ForegroundColorSpan
|
||||
* @property bold StyleSpan
|
||||
*/
|
||||
class RustCompletionAdapter : EditorCompletionAdapter() {
|
||||
private val layoutInflater by lazy {
|
||||
LayoutInflater.from(context)
|
||||
|
@ -39,20 +40,20 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
|
|||
isCurrentCursorPosition: Boolean
|
||||
): View {
|
||||
val editItem = EditItemBinding.inflate(layoutInflater, parent, false)
|
||||
val completionItem = getItem(position)
|
||||
val completionItem = getItem(position) as RustCompletionItem
|
||||
spannableStringBuilder.clear()
|
||||
val label = completionItem.label
|
||||
val label = completionItem.label.toString()
|
||||
spannableStringBuilder.append(label)
|
||||
//节补丁
|
||||
if (RustAutoComplete2.keyWord.startsWith('[') && RustAutoComplete2.keyWord.length > 1) {
|
||||
RustAutoComplete2.keyWord =
|
||||
RustAutoComplete2.keyWord.subSequence(1, RustAutoComplete2.keyWord.length)
|
||||
if (RustAutoComplete.keyWord.startsWith('[') && RustAutoComplete.keyWord.length > 1) {
|
||||
RustAutoComplete.keyWord =
|
||||
RustAutoComplete.keyWord.subSequence(1, RustAutoComplete.keyWord.length)
|
||||
.toString()
|
||||
}
|
||||
val start = label.lowercase(Locale.getDefault())
|
||||
.indexOf(RustAutoComplete2.keyWord.lowercase(Locale.getDefault()))
|
||||
.indexOf(RustAutoComplete.keyWord.lowercase(Locale.getDefault()))
|
||||
if (start > -1) {
|
||||
val end = start + RustAutoComplete2.keyWord.length
|
||||
val end = start + RustAutoComplete.keyWord.length
|
||||
spannableStringBuilder.setSpan(
|
||||
colorSpan,
|
||||
start,
|
||||
|
@ -63,8 +64,8 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
|
|||
}
|
||||
editItem.titleView.text = spannableStringBuilder
|
||||
editItem.contentView.text = completionItem.desc
|
||||
if (completionItem.extrasData != null && completionItem.extrasData.containsKey("sub")) {
|
||||
editItem.subTitleView.text = completionItem.extrasData.getString("sub")
|
||||
if (completionItem.subtitle != null) {
|
||||
editItem.subTitleView.text = completionItem.subtitle
|
||||
} else {
|
||||
editItem.subTitleView.isVisible = false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionItem
|
||||
import io.github.rosemoe.sora.text.Content
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
|
||||
/**
|
||||
* Rust完成器对象
|
||||
* @property label String
|
||||
* @constructor
|
||||
*/
|
||||
class RustCompletionItem(var title: String) : CompletionItem(title) {
|
||||
|
||||
|
||||
init {
|
||||
label = title
|
||||
}
|
||||
|
||||
constructor(title: String, commit: String, subtitle: String) : this(commit) {
|
||||
this.title = title
|
||||
this.label = commit
|
||||
this.subtitle = subtitle
|
||||
}
|
||||
|
||||
constructor(title: String, subtitle: String, icon: Drawable?) : this(title) {
|
||||
this.title = title
|
||||
this.label = title
|
||||
this.subtitle = subtitle
|
||||
}
|
||||
|
||||
constructor(title: String, commit: String, sub: String, icon: Drawable?) : this(commit) {
|
||||
this.title = title
|
||||
this.label = commit
|
||||
this.subtitle = sub
|
||||
this.icon = icon
|
||||
}
|
||||
|
||||
|
||||
var cursorOffset: Int = 0
|
||||
var subtitle: String? = null
|
||||
|
||||
|
||||
/**
|
||||
* 执行完成
|
||||
* @param p0 CodeEditor
|
||||
* @param p1 Content
|
||||
* @param p2 Int
|
||||
* @param p3 Int
|
||||
*/
|
||||
override fun performCompletion(p0: CodeEditor?, p1: Content?, p2: Int, p3: Int) {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import io.github.rosemoe.sora.lang.format.Formatter
|
||||
import io.github.rosemoe.sora.text.Content
|
||||
import io.github.rosemoe.sora.text.TextRange
|
||||
|
||||
class RustFormatter : Formatter {
|
||||
override fun format(p0: Content, p1: TextRange) {
|
||||
|
||||
}
|
||||
|
||||
override fun formatRegion(p0: Content, p1: TextRange, p2: TextRange) {
|
||||
|
||||
}
|
||||
|
||||
override fun setReceiver(p0: Formatter.FormatResultReceiver?) {
|
||||
|
||||
}
|
||||
|
||||
override fun isRunning(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun destroy() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package com.coldmint.rust.pro.edit
|
||||
|
||||
import com.coldmint.rust.core.dataBean.CompileConfiguration
|
||||
import io.github.rosemoe.sora.lang.analysis.AsyncIncrementalAnalyzeManager
|
||||
import io.github.rosemoe.sora.lang.analysis.IncrementalAnalyzeManager
|
||||
import io.github.rosemoe.sora.lang.styling.CodeBlock
|
||||
import io.github.rosemoe.sora.lang.styling.Span
|
||||
import io.github.rosemoe.sora.lang.styling.TextStyle
|
||||
import io.github.rosemoe.sora.text.Content
|
||||
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
|
||||
|
||||
/**
|
||||
* Rust增量分析器
|
||||
*/
|
||||
class RustIncrementalAnalyzeManager :
|
||||
AsyncIncrementalAnalyzeManager<Int, RustCodeToken>() {
|
||||
override fun getInitialState(): Int {
|
||||
//获取初始状态
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun stateEquals(state: Int?, another: Int?): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun tokenizeLine(
|
||||
line: CharSequence?,
|
||||
state: Int?,
|
||||
lineIndex: Int
|
||||
): IncrementalAnalyzeManager.LineTokenizeResult<Int, RustCodeToken> {
|
||||
if (line.isNullOrBlank()) {
|
||||
return IncrementalAnalyzeManager.LineTokenizeResult(0, null)
|
||||
}
|
||||
val tokens = ArrayList<RustCodeToken>()
|
||||
if (line.startsWith("#")) {
|
||||
//是注释
|
||||
tokens.add(RustCodeToken())
|
||||
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
|
||||
}
|
||||
|
||||
val index = line.lastIndexOf(':')
|
||||
if (index > 0) {
|
||||
//是代码
|
||||
tokens.add(RustCodeToken(0, CompileConfiguration.CodeBlockType.Key))
|
||||
tokens.add(RustCodeToken(index, CompileConfiguration.CodeBlockType.Symbol))
|
||||
tokens.add(RustCodeToken(index + 1, CompileConfiguration.CodeBlockType.Value))
|
||||
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
|
||||
}
|
||||
|
||||
|
||||
if (line.startsWith('[') && line.endsWith(']')) {
|
||||
//是节
|
||||
tokens.add(RustCodeToken(0, CompileConfiguration.CodeBlockType.Section))
|
||||
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
|
||||
}
|
||||
|
||||
tokens.add(RustCodeToken())
|
||||
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
|
||||
}
|
||||
|
||||
override fun generateSpansForLine(tokens: IncrementalAnalyzeManager.LineTokenizeResult<Int, RustCodeToken>?): MutableList<Span> {
|
||||
val spans = ArrayList<Span>()
|
||||
val tokenList = tokens?.tokens
|
||||
if (tokenList == null || tokenList.isEmpty()) {
|
||||
spans.add(
|
||||
Span.obtain(
|
||||
0,
|
||||
TextStyle.makeStyle(EditorColorScheme.COMMENT)
|
||||
)
|
||||
)
|
||||
return spans
|
||||
}
|
||||
tokenList.forEach {
|
||||
when (it.codeBlockType) {
|
||||
CompileConfiguration.CodeBlockType.Section -> {
|
||||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(
|
||||
EditorColorScheme.FUNCTION_NAME,
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
CompileConfiguration.CodeBlockType.Value -> {
|
||||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(EditorColorScheme.COMMENT)
|
||||
)
|
||||
)
|
||||
}
|
||||
CompileConfiguration.CodeBlockType.Symbol -> {
|
||||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(EditorColorScheme.COMMENT)
|
||||
)
|
||||
)
|
||||
}
|
||||
CompileConfiguration.CodeBlockType.Key -> {
|
||||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(EditorColorScheme.KEYWORD)
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
spans.add(
|
||||
Span.obtain(
|
||||
it.offset,
|
||||
TextStyle.makeStyle(EditorColorScheme.COMMENT)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return spans
|
||||
}
|
||||
|
||||
override fun computeBlocks(
|
||||
text: Content?,
|
||||
delegate: CodeBlockAnalyzeDelegate?
|
||||
): MutableList<CodeBlock> {
|
||||
return ArrayList<CodeBlock>()
|
||||
}
|
||||
|
||||
}
|
|
@ -2,29 +2,42 @@ package com.coldmint.rust.pro.edit
|
|||
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.core.CodeCompiler2
|
||||
import com.coldmint.rust.core.dataBean.dataset.CodeDataBean
|
||||
import android.os.Bundle
|
||||
import com.coldmint.rust.core.database.code.CodeDataBase
|
||||
import com.coldmint.rust.core.database.file.FileDataBase
|
||||
import com.coldmint.rust.core.interfaces.EnglishMode
|
||||
|
||||
import io.github.rosemoe.sora.data.CompletionItem
|
||||
import io.github.rosemoe.sora.interfaces.AutoCompleteProvider
|
||||
import io.github.rosemoe.sora.interfaces.CodeAnalyzer
|
||||
import io.github.rosemoe.sora.interfaces.EditorLanguage
|
||||
import io.github.rosemoe.sora.interfaces.NewlineHandler
|
||||
import com.coldmint.rust.core.tool.DebugHelper
|
||||
import io.github.rosemoe.sora.lang.Language
|
||||
import io.github.rosemoe.sora.lang.analysis.AnalyzeManager
|
||||
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
|
||||
import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete
|
||||
import io.github.rosemoe.sora.lang.format.Formatter
|
||||
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandleResult
|
||||
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler
|
||||
import io.github.rosemoe.sora.text.CharPosition
|
||||
import io.github.rosemoe.sora.text.Content
|
||||
import io.github.rosemoe.sora.text.ContentReference
|
||||
import io.github.rosemoe.sora.text.TextRange
|
||||
import io.github.rosemoe.sora.widget.CodeEditor
|
||||
import io.github.rosemoe.sora.widget.SymbolPairMatch
|
||||
|
||||
class RustLanguage(
|
||||
private val context: Context,
|
||||
) : EditorLanguage, EnglishMode {
|
||||
) : Language, EnglishMode {
|
||||
private val mRustAnalyzer: RustAnalyzer by lazy {
|
||||
RustAnalyzer()
|
||||
}
|
||||
private val autoComplete: RustAutoComplete2 = RustAutoComplete2(context)
|
||||
|
||||
private val autoComplete by lazy {
|
||||
RustAutoComplete(context)
|
||||
}
|
||||
|
||||
// private val autoComplete: RustAutoComplete = RustAutoComplete(context)
|
||||
private var isEnglishMode = false
|
||||
private val rustAnalyzeManager by lazy {
|
||||
RustIncrementalAnalyzeManager()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置代码数据库
|
||||
|
@ -32,7 +45,7 @@ class RustLanguage(
|
|||
*/
|
||||
fun setCodeDataBase(codeDataBase: CodeDataBase) {
|
||||
mRustAnalyzer.setCodeDataBase(codeDataBase)
|
||||
autoComplete.setCodeDataBase(codeDataBase)
|
||||
// autoComplete.setCodeDataBase(codeDataBase)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,61 +53,83 @@ class RustLanguage(
|
|||
* @param codeEditor
|
||||
*/
|
||||
fun setCodeEditor(codeEditor: CodeEditor?) {
|
||||
autoComplete.setCodeEditor(codeEditor)
|
||||
// autoComplete.setCodeEditor(codeEditor)
|
||||
}
|
||||
|
||||
fun setFileDataBase(fileDataBase: FileDataBase) {
|
||||
autoComplete.setFileDataBase(fileDataBase)
|
||||
// autoComplete.setFileDataBase(fileDataBase)
|
||||
}
|
||||
|
||||
|
||||
//语法分析器
|
||||
override fun getAnalyzer(): CodeAnalyzer {
|
||||
return mRustAnalyzer
|
||||
}
|
||||
// override fun getAnalyzer(): CodeAnalyzer {
|
||||
// return mRustAnalyzer
|
||||
// }
|
||||
|
||||
//自动完成器
|
||||
override fun getAutoCompleteProvider(): RustAutoComplete2 {
|
||||
return autoComplete
|
||||
}
|
||||
// override fun getAutoCompleteProvider(): RustAutoComplete {
|
||||
// return autoComplete
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 是否为自动完成字符
|
||||
*
|
||||
* @param ch 字符
|
||||
* @return 逻辑值
|
||||
*/
|
||||
override fun isAutoCompleteChar(ch: Char): Boolean {
|
||||
return when (ch) {
|
||||
':', '.', '_', ' ', ',' -> false
|
||||
else -> true
|
||||
}
|
||||
// /**
|
||||
// * 是否为自动完成字符
|
||||
// *
|
||||
// * @param ch 字符
|
||||
// * @return 逻辑值
|
||||
// */
|
||||
// override fun isAutoCompleteChar(ch: Char): Boolean {
|
||||
// return when (ch) {
|
||||
// ':', '.', '_', ' ', ',' -> false
|
||||
// else -> true
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
override fun getAnalyzeManager(): AnalyzeManager {
|
||||
return rustAnalyzeManager
|
||||
}
|
||||
|
||||
//获取分割进度
|
||||
override fun getIndentAdvance(content: String): Int {
|
||||
override fun getInterruptionLevel(): Int {
|
||||
return Language.INTERRUPTION_LEVEL_STRONG
|
||||
}
|
||||
|
||||
override fun requireAutoComplete(
|
||||
p0: ContentReference,
|
||||
p1: CharPosition,
|
||||
p2: CompletionPublisher,
|
||||
p3: Bundle
|
||||
) {
|
||||
val line = p0.getLine(p1.getLine())
|
||||
p2.addItem(RustCompletionItem("121221"))
|
||||
p2.updateList()
|
||||
// autoComplete.requireAutoComplete(line,p2,p1.getLine(),p1.getColumn())
|
||||
}
|
||||
|
||||
override fun getIndentAdvance(p0: ContentReference, p1: Int, p2: Int): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
//用标签
|
||||
override fun useTab(): Boolean {
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
//格式化
|
||||
override fun format(text: CharSequence): CharSequence {
|
||||
return CodeCompiler2.format(text.toString())
|
||||
override fun getFormatter(): Formatter {
|
||||
return RustFormatter()
|
||||
}
|
||||
|
||||
//符号配对之间的匹配
|
||||
override fun getSymbolPairs(): SymbolPairMatch? {
|
||||
override fun getSymbolPairs(): SymbolPairMatch {
|
||||
return SymbolPairMatch()
|
||||
}
|
||||
|
||||
override fun getNewlineHandlers(): Array<NewlineHandler>? {
|
||||
//行处理程序,按下回车时
|
||||
return null
|
||||
}
|
||||
|
||||
//获取新线的处理程序
|
||||
override fun getNewlineHandlers(): Array<NewlineHandler> {
|
||||
return arrayOf()
|
||||
|
||||
override fun destroy() {
|
||||
}
|
||||
|
||||
override fun isEnglishMode(): Boolean {
|
||||
|
@ -103,7 +138,7 @@ class RustLanguage(
|
|||
|
||||
override fun setEnglish(englishMode: Boolean) {
|
||||
mRustAnalyzer.setEnglish(englishMode)
|
||||
autoComplete.setEnglish(englishMode)
|
||||
// autoComplete.setEnglish(englishMode)
|
||||
isEnglishMode = englishMode
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,25 @@
|
|||
package com.coldmint.rust.pro.fragments
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ExpandableListView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
import com.coldmint.rust.core.LocalTemplatePackage
|
||||
import com.coldmint.rust.core.dataBean.template.LocalTemplateFile
|
||||
import com.coldmint.rust.core.dataBean.template.Template
|
||||
import com.coldmint.rust.core.dataBean.template.TemplatePackage
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.pro.FileManagerActivity
|
||||
import com.coldmint.rust.pro.R
|
||||
|
@ -35,8 +41,10 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
|
|||
InstalledTemplateViewModel()
|
||||
}
|
||||
|
||||
private lateinit var startTemplateParserActivity: ActivityResultLauncher<Intent>
|
||||
|
||||
var mTemplateAdapter: TemplateAdapter? = null
|
||||
|
||||
private lateinit var mTemplateAdapter: TemplateAdapter
|
||||
|
||||
|
||||
/**
|
||||
|
@ -69,19 +77,32 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
|
|||
//这里做关于父项的相关操作......
|
||||
val numView = view.findViewById<TextView>(R.id.template_num)
|
||||
val templateClass =
|
||||
mTemplateAdapter!!.getGroup(groupPosition) as LocalTemplatePackage
|
||||
mTemplateAdapter.getGroup(groupPosition) as TemplatePackage
|
||||
CoreDialog(requireContext()).setTitle(R.string.template_info)
|
||||
.setMessage(
|
||||
templateClass.getInfo()?.description
|
||||
?: requireContext().getString(R.string.describe)
|
||||
).setCancelable(false).setPositiveButton(R.string.delete_title) {
|
||||
templateClass.getDescription()
|
||||
).setCancelable(false).setPositiveButton(
|
||||
if (templateClass.isLocal()) {
|
||||
R.string.delete_title
|
||||
} else {
|
||||
R.string.de_subscription
|
||||
}
|
||||
) {
|
||||
numView.setText(R.string.del_moding)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val scope = CoroutineScope(Job())
|
||||
scope.launch {
|
||||
FileOperator.delete_files(templateClass.directest)
|
||||
handler.post {
|
||||
templateClass.delete(
|
||||
AppSettings.getValue(
|
||||
AppSettings.Setting.Token,
|
||||
""
|
||||
)
|
||||
) {
|
||||
if (it) {
|
||||
viewModel.loadTemplate(requireContext())
|
||||
} else {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
R.string.delete_error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
}.setNegativeButton(R.string.dialog_cancel) {
|
||||
|
@ -92,11 +113,25 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
|
|||
}
|
||||
true
|
||||
}
|
||||
|
||||
viewBinding.swipeRefreshLayout.setOnRefreshListener {
|
||||
viewModel.loadTemplate(requireContext())
|
||||
viewBinding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) {
|
||||
initAction()
|
||||
startTemplateParserActivity =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
Log.d("启动模板解析器", "收到成功回调,关闭界面。")
|
||||
requireActivity().finish()
|
||||
} else {
|
||||
Log.w("启动模板解析器", "未收到有效回调。")
|
||||
}
|
||||
}
|
||||
viewModel.createPathLiveData.observe(this) {
|
||||
var relativePath = FileOperator.getRelativePath(
|
||||
it,
|
||||
|
@ -112,16 +147,24 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
|
|||
(requireContext().getText(R.string.unit_path) as String),
|
||||
relativePath
|
||||
)
|
||||
mTemplateAdapter?.setCreatePath(it)
|
||||
if (this::mTemplateAdapter.isInitialized) {
|
||||
mTemplateAdapter.setCreatePath(it)
|
||||
Log.d("创建目录观察者", "模板适配器设置目录为${it}。")
|
||||
} else {
|
||||
Log.e("创建目录观察者", "模板适配器没有设置目录。")
|
||||
}
|
||||
}
|
||||
viewModel.setLoadCallBack {
|
||||
mTemplateAdapter = TemplateAdapter(
|
||||
requireContext(),
|
||||
viewModel.getGroupData(),
|
||||
viewModel.getItemData(),
|
||||
viewModel.environmentLanguage
|
||||
viewModel.environmentLanguage, startTemplateParserActivity
|
||||
)
|
||||
viewBinding.expandableList.setAdapter(mTemplateAdapter!!)
|
||||
viewBinding.expandableList.setAdapter(mTemplateAdapter)
|
||||
val path = viewModel.createPathLiveData.value.toString()
|
||||
mTemplateAdapter.setCreatePath(path)
|
||||
Log.d("创建目录观察者", "模板适配器设置目录为${path}。")
|
||||
}
|
||||
viewModel.loadTemplate(requireContext())
|
||||
}
|
||||
|
|
|
@ -27,17 +27,25 @@ import com.coldmint.rust.pro.databinding.ModFragmentBinding
|
|||
import com.coldmint.rust.pro.databinding.ModListItemBinding
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.coldmint.rust.pro.tool.GlobalMethod
|
||||
import com.coldmint.rust.pro.viewmodel.ModViewModel
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.dialog.MaterialDialogs
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import me.zhanghai.android.fastscroll.FastScrollScrollView
|
||||
import me.zhanghai.android.fastscroll.FastScrollerBuilder
|
||||
import java.io.File
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class ModFragment : BaseFragment<ModFragmentBinding>() {
|
||||
val viewModel: ModViewModel by lazy {
|
||||
ModViewModel()
|
||||
}
|
||||
lateinit var modAdapter: ModAdapter
|
||||
val needRecycling by lazy {
|
||||
if (GlobalMethod.isActive) {
|
||||
|
@ -49,88 +57,6 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
|
|||
false
|
||||
}
|
||||
}
|
||||
val executorService = Executors.newSingleThreadExecutor()
|
||||
|
||||
//初始化视图
|
||||
fun loadMods() {
|
||||
val useProgressBar = !this::modAdapter.isInitialized || modAdapter.itemCount == 0
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
thread {
|
||||
if (useProgressBar) {
|
||||
handler.post {
|
||||
viewBinding.progressBar.isVisible = true
|
||||
viewBinding.modError.isVisible = false
|
||||
viewBinding.modErrorIcon.isVisible = false
|
||||
viewBinding.modList.isVisible = false
|
||||
}
|
||||
}
|
||||
val mod_directory = File(AppSettings.getValue(AppSettings.Setting.ModFolder, ""))
|
||||
if (!mod_directory.exists()) {
|
||||
mod_directory.mkdirs()
|
||||
}
|
||||
val files = mod_directory.listFiles()
|
||||
val thisContent = requireContext()
|
||||
if (files != null && files.isNotEmpty()) {
|
||||
val data = ArrayList<ModClass>()
|
||||
for (t in files) {
|
||||
if (ModClass.isMod(t)) {
|
||||
data.add(ModClass(t))
|
||||
}
|
||||
}
|
||||
if (data.isEmpty()) {
|
||||
handler.post {
|
||||
showNotFindMod()
|
||||
}
|
||||
return@thread
|
||||
}
|
||||
if (useProgressBar) {
|
||||
modAdapter = ModAdapter(thisContent, data)
|
||||
} else {
|
||||
modAdapter.setNewDataList(data)
|
||||
}
|
||||
modAdapter.setItemChangeEvent { changeType, i, modClass, i2 ->
|
||||
if (i2 == 0) {
|
||||
handler.post { loadMods() }
|
||||
}
|
||||
}
|
||||
// modAdapter.
|
||||
modAdapter.setItemEvent { i, modListItemBinding, viewHolder, modClass ->
|
||||
modListItemBinding.root.setOnClickListener {
|
||||
onClickItemWork(modListItemBinding, modClass)
|
||||
}
|
||||
modListItemBinding.root.setOnLongClickListener {
|
||||
modAdapter.showDeleteItemDialog(
|
||||
modClass.modName,
|
||||
viewHolder.adapterPosition,
|
||||
onClickPositiveButton = { d, b ->
|
||||
delFile(handler, modClass, viewHolder.adapterPosition)
|
||||
false
|
||||
})
|
||||
false
|
||||
}
|
||||
}
|
||||
if (useProgressBar) {
|
||||
handler.postDelayed({
|
||||
viewBinding.modList.isVisible = true
|
||||
viewBinding.modError.isVisible = false
|
||||
viewBinding.modErrorIcon.isVisible = false
|
||||
viewBinding.progressBar.isVisible = false
|
||||
|
||||
viewBinding.modList.adapter = modAdapter
|
||||
}, MainActivity.hideViewDelay)
|
||||
} else {
|
||||
handler.post {
|
||||
modAdapter.notifyDataSetChanged()
|
||||
viewBinding.modList.adapter = modAdapter
|
||||
}
|
||||
}
|
||||
} else {
|
||||
handler.post {
|
||||
showNotFindMod()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
|
@ -142,7 +68,8 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
|
|||
modClass: ModClass,
|
||||
index: Int? = null
|
||||
) {
|
||||
executorService.submit {
|
||||
val scope = CoroutineScope(Job())
|
||||
scope.run {
|
||||
val targetFile = modClass.modFile
|
||||
val errorFolder =
|
||||
File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName)
|
||||
|
@ -249,9 +176,64 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载模组列表
|
||||
*/
|
||||
fun loadModList() {
|
||||
val scope = CoroutineScope(Job())
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
scope.run {
|
||||
val dataList = viewModel.loadMod()
|
||||
handler.post {
|
||||
viewBinding.progressBar.isVisible = true
|
||||
viewBinding.modErrorIcon.isVisible = false
|
||||
viewBinding.modError.isVisible = false
|
||||
viewBinding.swipeRefreshLayout.isVisible = false
|
||||
}
|
||||
if (dataList == null) {
|
||||
handler.post {
|
||||
viewBinding.modError.setText(R.string.not_find_mod)
|
||||
viewBinding.modError.isVisible = true
|
||||
viewBinding.modErrorIcon.isVisible = true
|
||||
viewBinding.swipeRefreshLayout.isVisible = false
|
||||
viewBinding.progressBar.isVisible = false
|
||||
}
|
||||
} else {
|
||||
handler.post {
|
||||
viewBinding.swipeRefreshLayout.isVisible = true
|
||||
viewBinding.progressBar.isVisible = false
|
||||
viewBinding.modErrorIcon.isVisible = false
|
||||
viewBinding.modError.isVisible = false
|
||||
modAdapter = ModAdapter(requireContext(), dataList)
|
||||
FastScrollerBuilder(viewBinding.modList).useMd2Style()
|
||||
.setPopupTextProvider(modAdapter).build()
|
||||
modAdapter.setItemEvent { i, modListItemBinding, viewHolder, modClass ->
|
||||
|
||||
modListItemBinding.root.setOnClickListener {
|
||||
onClickItemWork(modListItemBinding, modClass)
|
||||
}
|
||||
|
||||
modListItemBinding.root.setOnLongClickListener {
|
||||
modAdapter.showDeleteItemDialog(
|
||||
modClass.modName,
|
||||
viewHolder.adapterPosition,
|
||||
onClickPositiveButton = { d, b ->
|
||||
delFile(handler, modClass, viewHolder.adapterPosition)
|
||||
false
|
||||
})
|
||||
false
|
||||
}
|
||||
}
|
||||
viewBinding.modList.adapter = modAdapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
loadMods()
|
||||
loadModList()
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
|
@ -346,16 +328,16 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
|
|||
bottomSheetDialog.show()
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示没有找到模组
|
||||
*/
|
||||
fun showNotFindMod() {
|
||||
viewBinding.modError.setText(R.string.not_find_mod)
|
||||
viewBinding.modError.isVisible = true
|
||||
viewBinding.modErrorIcon.isVisible = true
|
||||
viewBinding.modList.isVisible = false
|
||||
viewBinding.progressBar.isVisible = false
|
||||
}
|
||||
// /**
|
||||
// * 显示没有找到模组
|
||||
// */
|
||||
// fun showNotFindMod() {
|
||||
// viewBinding.modError.setText(R.string.not_find_mod)
|
||||
// viewBinding.modError.isVisible = true
|
||||
// viewBinding.modErrorIcon.isVisible = true
|
||||
// viewBinding.modList.isVisible = false
|
||||
// viewBinding.progressBar.isVisible = false
|
||||
// }
|
||||
|
||||
override fun getViewBindingObject(layoutInflater: LayoutInflater): ModFragmentBinding {
|
||||
return ModFragmentBinding.inflate(layoutInflater)
|
||||
|
@ -369,5 +351,10 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
|
|||
DividerItemDecoration.VERTICAL
|
||||
)
|
||||
)
|
||||
viewBinding.swipeRefreshLayout.setOnRefreshListener {
|
||||
loadModList()
|
||||
viewBinding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
viewModel.loadMod()
|
||||
}
|
||||
}
|
|
@ -2,12 +2,17 @@ package com.coldmint.rust.pro.fragments
|
|||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.coldmint.rust.core.dataBean.webTemplate.WebTemplatePackageListData
|
||||
import com.coldmint.dialog.CoreDialog
|
||||
import com.coldmint.rust.core.dataBean.ApiResponse
|
||||
import com.coldmint.rust.core.dataBean.WebTemplatePackageListData
|
||||
import com.coldmint.rust.core.interfaces.ApiCallBack
|
||||
import com.coldmint.rust.core.web.ServerConfiguration
|
||||
import com.coldmint.rust.core.web.TemplatePhp
|
||||
import com.coldmint.rust.pro.R
|
||||
import com.coldmint.rust.pro.adapters.WebTemplateAdapter
|
||||
import com.coldmint.rust.pro.base.BaseFragment
|
||||
import com.coldmint.rust.pro.databinding.FragmentTemplateCommunityBinding
|
||||
|
@ -45,6 +50,75 @@ class TemplateCommunityFragment : BaseFragment<FragmentTemplateCommunityBinding>
|
|||
viewBinding.loadView.isVisible = false
|
||||
viewBinding.errorLayout.isVisible = false
|
||||
val adapter = WebTemplateAdapter(requireContext(), t.data)
|
||||
adapter.setItemEvent { i, itemWebTemplateBinding, viewHolder, data ->
|
||||
itemWebTemplateBinding.button.setOnClickListener {
|
||||
var subscribe = data.subscribe
|
||||
if (subscribe) {
|
||||
CoreDialog(requireContext()).setTitle(R.string.de_subscription)
|
||||
.setMessage(
|
||||
String.format(
|
||||
getString(R.string.de_subscription_msg),
|
||||
data.name
|
||||
)
|
||||
).setPositiveButton(R.string.dialog_ok) {
|
||||
//退订
|
||||
TemplatePhp.instance.deleteSubscription(token, data.id,
|
||||
object : ApiCallBack<ApiResponse> {
|
||||
override fun onResponse(t: ApiResponse) {
|
||||
if (t.code == ServerConfiguration.Success_Code) {
|
||||
itemWebTemplateBinding.button.setText(R.string.subscription)
|
||||
data.subscribe = false
|
||||
} else {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
t.message,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
R.string.network_error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
})
|
||||
}.setNegativeButton(R.string.dialog_cancel) {
|
||||
|
||||
}.setCancelable(false).show()
|
||||
} else {
|
||||
TemplatePhp.instance.subscription(token, data.id,
|
||||
object : ApiCallBack<ApiResponse> {
|
||||
override fun onResponse(t: ApiResponse) {
|
||||
if (t.code == ServerConfiguration.Success_Code) {
|
||||
itemWebTemplateBinding.button.setText(R.string.de_subscription)
|
||||
data.subscribe = true
|
||||
} else {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
t.message,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: Exception) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
R.string.network_error,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
viewBinding.recyclerView.adapter = adapter
|
||||
FastScrollerBuilder(viewBinding.recyclerView).useMd2Style()
|
||||
.setPopupTextProvider(adapter).build()
|
||||
|
|
|
@ -14,8 +14,7 @@ import com.coldmint.rust.core.tool.FileOperator
|
|||
import com.coldmint.rust.core.tool.LocalVariableName
|
||||
import com.coldmint.rust.core.web.Dynamic
|
||||
import com.coldmint.rust.pro.R
|
||||
import io.github.rosemoe.sora.data.CompletionItem
|
||||
import io.github.rosemoe.sora.data.NavigationItem
|
||||
import com.coldmint.rust.pro.edit.RustCompletionItem
|
||||
import java.io.File
|
||||
import java.lang.StringBuilder
|
||||
|
||||
|
@ -129,9 +128,9 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
/**
|
||||
* 节信息转换为自动完成对象
|
||||
* @param sectionInfo SectionInfo
|
||||
* @return CompletionItem
|
||||
* @return RustCompletionItem
|
||||
*/
|
||||
fun sectionInfoToCompletionItem(sectionInfo: SectionInfo): CompletionItem {
|
||||
fun sectionInfoToCompletionItem(sectionInfo: SectionInfo): RustCompletionItem {
|
||||
if (!isInitComplete) {
|
||||
NullPointerException("没有初始化。")
|
||||
}
|
||||
|
@ -147,14 +146,14 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
"[" + sectionInfo.translate + end
|
||||
}
|
||||
val completionItem = if (isEnglishMode) {
|
||||
CompletionItem(
|
||||
RustCompletionItem(
|
||||
sectionInfo.code,
|
||||
commit,
|
||||
section,
|
||||
boxDrawable
|
||||
)
|
||||
} else {
|
||||
CompletionItem(
|
||||
RustCompletionItem(
|
||||
sectionInfo.translate,
|
||||
commit,
|
||||
section,
|
||||
|
@ -173,18 +172,18 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
* 本地变量转自动完成对象
|
||||
* @param localVariableName LocalVariableName
|
||||
* @param previousText String? 之前的内容(冒号后面的值)
|
||||
* @return CompletionItem
|
||||
* @return RustCompletionItem
|
||||
*/
|
||||
fun localVariableNameToCompletionItem(
|
||||
localVariableName: LocalVariableName,
|
||||
previousText: String? = null
|
||||
): CompletionItem {
|
||||
): RustCompletionItem {
|
||||
val commit = if (previousText == null) {
|
||||
"\${" + localVariableName.name + "}"
|
||||
} else {
|
||||
previousText + "\${" + localVariableName.name + "}"
|
||||
}
|
||||
return CompletionItem(
|
||||
return RustCompletionItem(
|
||||
localVariableName.name,
|
||||
commit,
|
||||
variableName, boxDrawable
|
||||
|
@ -194,21 +193,21 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
/**
|
||||
* 转换代码信息到自动完成对象
|
||||
* @param codeInfo CodeInfo
|
||||
* @return CompletionItem
|
||||
* @return RustCompletionItem
|
||||
*/
|
||||
fun codeInfoToCompletionItem(codeInfo: CodeInfo): CompletionItem {
|
||||
fun codeInfoToCompletionItem(codeInfo: CodeInfo): RustCompletionItem {
|
||||
if (!isInitComplete) {
|
||||
NullPointerException("没有初始化。")
|
||||
}
|
||||
val typeInfo = getValueType(codeInfo.type)
|
||||
val completionItem = if (isEnglishMode) {
|
||||
CompletionItem(
|
||||
RustCompletionItem(
|
||||
codeInfo.code,
|
||||
codeInfo.code + typeInfo?.external,
|
||||
codeInfo.description, boxDrawable
|
||||
)
|
||||
} else {
|
||||
CompletionItem(
|
||||
RustCompletionItem(
|
||||
codeInfo.translate,
|
||||
codeInfo.translate + typeInfo?.external,
|
||||
codeInfo.description, boxDrawable
|
||||
|
@ -218,7 +217,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
if (typeList != null && typeList.isNotBlank()) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("list", typeList)
|
||||
completionItem.extrasData = bundle
|
||||
// completionItem.extrasData = bundle
|
||||
}
|
||||
val offset = typeInfo?.offset
|
||||
if (offset != null && offset.isNotBlank()) {
|
||||
|
@ -260,7 +259,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
* @param valueTable ValueTable
|
||||
* @return CompletionItem
|
||||
*/
|
||||
fun valueTableToCompletionItem(valueTable: ValueTable): CompletionItem {
|
||||
fun valueTableToCompletionItem(valueTable: ValueTable): RustCompletionItem {
|
||||
if (isInitComplete) {
|
||||
NullPointerException("没有初始化。")
|
||||
}
|
||||
|
@ -278,7 +277,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
}
|
||||
}
|
||||
}
|
||||
return CompletionItem(valueTable.keyWord, desc, boxDrawable)
|
||||
return RustCompletionItem(valueTable.keyWord, desc, boxDrawable)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,23 +285,23 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
* @param navigationItem NavigationItem
|
||||
* @return CompletionItem
|
||||
*/
|
||||
fun navigationItemToCompletionItem(navigationItem: NavigationItem): CompletionItem {
|
||||
val name = SourceFile.getAbsoluteSectionName(navigationItem.label)
|
||||
val type = SourceFile.getSectionType(navigationItem.label)
|
||||
return CompletionItem(
|
||||
name,
|
||||
name,
|
||||
type,
|
||||
boxDrawable
|
||||
)
|
||||
}
|
||||
// fun navigationItemToCompletionItem(navigationItem: NavigationItem): RustCompletionItem {
|
||||
// val name = SourceFile.getAbsoluteSectionName(navigationItem.label)
|
||||
// val type = SourceFile.getSectionType(navigationItem.label)
|
||||
// return RustCompletionItem(
|
||||
// name,
|
||||
// name,
|
||||
// type,
|
||||
// boxDrawable
|
||||
// )
|
||||
// }
|
||||
|
||||
/**
|
||||
* 文件信息转自动完成对象
|
||||
* @param fileTable FileTable
|
||||
* @return CompletionItem
|
||||
*/
|
||||
fun fileTableToCompletionItem(fileTable: FileTable): CompletionItem {
|
||||
fun fileTableToCompletionItem(fileTable: FileTable): RustCompletionItem {
|
||||
if (!isInitComplete) {
|
||||
NullPointerException("没有初始化。")
|
||||
}
|
||||
|
@ -335,7 +334,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
}
|
||||
}
|
||||
val completionItem =
|
||||
CompletionItem(
|
||||
RustCompletionItem(
|
||||
fileTable.fileName,
|
||||
stringBuilder.toString(),
|
||||
fileTable.type, drawable
|
||||
|
@ -353,7 +352,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
|
|||
if (rootCodeName == null) {
|
||||
throw NullPointerException("未设置Root名称")
|
||||
}
|
||||
return CompletionItem(
|
||||
return RustCompletionItem(
|
||||
fileTable.fileName,
|
||||
fileTable.fileName,
|
||||
fileTable.type, fileDrawable
|
||||
|
|
|
@ -4,12 +4,16 @@ import android.content.Context
|
|||
import android.util.Log
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.coldmint.rust.core.LocalTemplatePackage
|
||||
import com.coldmint.rust.core.dataBean.SubscriptionData
|
||||
import com.coldmint.rust.core.dataBean.template.LocalTemplateFile
|
||||
import com.coldmint.rust.core.dataBean.template.Template
|
||||
import com.coldmint.rust.core.dataBean.template.TemplatePackage
|
||||
import com.coldmint.rust.core.interfaces.ApiCallBack
|
||||
import com.coldmint.rust.core.interfaces.FileFinderListener
|
||||
import com.coldmint.rust.core.tool.FileFinder2
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.core.web.ServerConfiguration
|
||||
import com.coldmint.rust.core.web.TemplatePhp
|
||||
import com.coldmint.rust.pro.base.BaseViewModel
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import org.json.JSONException
|
||||
|
@ -80,8 +84,36 @@ class InstalledTemplateViewModel : BaseViewModel() {
|
|||
fun loadTemplate(context: Context) {
|
||||
groupList.clear()
|
||||
itemList.clear()
|
||||
val token = AppSettings.getValue(AppSettings.Setting.Token,"")
|
||||
TemplatePhp.instance.getSubscriptionDataList(token,object :ApiCallBack<SubscriptionData>{
|
||||
override fun onResponse(t: SubscriptionData) {
|
||||
if (t.code == ServerConfiguration.Success_Code){
|
||||
Log.d("加载网络订阅模板", "正在处理。")
|
||||
t.data.forEach {
|
||||
groupList.add(it)
|
||||
val temList = ArrayList<Template>()
|
||||
itemList.add(temList)
|
||||
it.templateList.forEach {
|
||||
temList.add(it)
|
||||
}
|
||||
}
|
||||
loadLocalTemplate(context)
|
||||
loadCallBack?.invoke()
|
||||
}else{
|
||||
Log.w("加载网络订阅模板", t.message)
|
||||
loadLocalTemplate(context)
|
||||
loadCallBack?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: Exception) {
|
||||
e.printStackTrace()
|
||||
Log.e("加载网络订阅模板", e.toString())
|
||||
loadLocalTemplate(context)
|
||||
loadCallBack?.invoke()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,7 +166,7 @@ class InstalledTemplateViewModel : BaseViewModel() {
|
|||
Log.d("加载本地模板", "已成功分配" + file.absolutePath)
|
||||
}
|
||||
} else {
|
||||
Log.e("加载本地模板", "无法分配" + file.absolutePath)
|
||||
Log.w("加载本地模板", "无法分配" + file.absolutePath)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.coldmint.rust.pro.viewmodel
|
||||
|
||||
import android.os.Environment
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.core.ModClass
|
||||
import com.coldmint.rust.pro.base.BaseViewModel
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* 模组ViewModel
|
||||
*/
|
||||
class ModViewModel : BaseViewModel() {
|
||||
|
||||
/**
|
||||
* 加载模组
|
||||
*/
|
||||
fun loadMod(): ArrayList<ModClass>? {
|
||||
val key = "加载模组列表"
|
||||
val modFolder = File(
|
||||
AppSettings.getValue(
|
||||
AppSettings.Setting.ModFolder,
|
||||
Environment.getExternalStorageDirectory().absolutePath + "/rustedWarfare/units/"
|
||||
)
|
||||
)
|
||||
if (modFolder.exists()) {
|
||||
if (!modFolder.isDirectory) {
|
||||
Log.e(key, "模组文件夹${modFolder},不是文件夹。")
|
||||
return null
|
||||
}
|
||||
val fileList = modFolder.listFiles()
|
||||
if (fileList.isNullOrEmpty()) {
|
||||
Log.e(key, "模组文件夹${modFolder},为空。")
|
||||
return null
|
||||
}
|
||||
|
||||
val arrayList = ArrayList<ModClass>()
|
||||
fileList.forEach {
|
||||
val isMod = ModClass.isMod(it)
|
||||
if (isMod) {
|
||||
arrayList.add(ModClass(it))
|
||||
Log.d(key, "已添加${it.absolutePath}。")
|
||||
} else {
|
||||
Log.e(key, "${it.absolutePath} 不是模组。")
|
||||
}
|
||||
}
|
||||
return if (arrayList.isEmpty()){
|
||||
return null
|
||||
}else{
|
||||
arrayList
|
||||
}
|
||||
} else {
|
||||
Log.e(key, "模组文件夹${modFolder}不存在。")
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.coldmint.rust.pro.viewmodel
|
|||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.coldmint.rust.core.SourceFile
|
||||
import com.coldmint.rust.core.dataBean.InputParserDataBean
|
||||
import com.coldmint.rust.core.dataBean.IntroducingDataBean
|
||||
import com.coldmint.rust.core.dataBean.ListParserDataBean
|
||||
|
@ -11,16 +12,24 @@ import com.coldmint.rust.core.interfaces.TemplateParser
|
|||
import com.coldmint.rust.core.templateParser.InputParser
|
||||
import com.coldmint.rust.core.templateParser.IntroducingParser
|
||||
import com.coldmint.rust.core.templateParser.ListParser
|
||||
import com.coldmint.rust.core.tool.FileOperator
|
||||
import com.coldmint.rust.pro.base.BaseViewModel
|
||||
import com.coldmint.rust.pro.tool.AppSettings
|
||||
import com.google.gson.Gson
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
|
||||
class TemplateParserViewModel : BaseViewModel() {
|
||||
|
||||
//json数据
|
||||
private var jsonData: JSONObject? = null
|
||||
private var template: Template? = null
|
||||
private lateinit var arrayList :ArrayList<TemplateParser>
|
||||
|
||||
|
||||
//创建目录
|
||||
private var createDirectory: String? = null
|
||||
|
||||
/**
|
||||
* 设置模板数据
|
||||
|
@ -32,6 +41,15 @@ class TemplateParserViewModel : BaseViewModel() {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置创建目录
|
||||
* @param path String
|
||||
*/
|
||||
fun setCreateDirectory(path: String) {
|
||||
createDirectory = path
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取源代码
|
||||
* @return String
|
||||
|
@ -51,14 +69,105 @@ class TemplateParserViewModel : BaseViewModel() {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建文件
|
||||
* @param context Context
|
||||
* @param fileName String
|
||||
* @return Boolean
|
||||
*/
|
||||
fun buildFile(context: Context, fileName: String): Boolean {
|
||||
if (createDirectory == null) {
|
||||
Log.e("构建文件", "没有设置创建目录。")
|
||||
return false
|
||||
}
|
||||
val index = fileName.lastIndexOf('.')
|
||||
val independentFolder = AppSettings.getValue(AppSettings.Setting.IndependentFolder, true)
|
||||
val createPath = if (independentFolder) {
|
||||
val folderName =
|
||||
if (index > -1) {
|
||||
fileName.substring(0 until index)
|
||||
} else {
|
||||
fileName
|
||||
}
|
||||
"$createDirectory/$folderName"
|
||||
} else {
|
||||
createDirectory
|
||||
}
|
||||
Log.d("构建文件", "是否需要独立创建文件夹${independentFolder} 文件夹目录${createPath}")
|
||||
val folder = File(createPath)
|
||||
if (folder.exists()) {
|
||||
Log.e("构建文件", "创建目录${createPath}已存在。")
|
||||
return false
|
||||
}
|
||||
folder.mkdirs()
|
||||
val path = File(
|
||||
createPath + "/" + if (index > -1) {
|
||||
fileName
|
||||
} else {
|
||||
"$fileName.ini"
|
||||
}
|
||||
)
|
||||
if (path.exists()) {
|
||||
Log.e("构建文件", "目标文件${path}已存在。")
|
||||
return false
|
||||
}
|
||||
return FileOperator.writeFile(path, generatingCode(context))
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
* @return String
|
||||
*/
|
||||
private fun generatingCode(context: Context): String {
|
||||
val staticCode = getCode()
|
||||
//如果为空,那么返回空
|
||||
if (staticCode.isBlank()) {
|
||||
Log.e("获取模板解析器", "静态代码为空。")
|
||||
return staticCode
|
||||
}
|
||||
|
||||
val sourceFile = SourceFile(staticCode)
|
||||
val parserList = getTemplateParserList(context)
|
||||
if (parserList.isEmpty()) {
|
||||
Log.w("生成代码", "此模板没有解析器,返回静态代码。")
|
||||
return staticCode
|
||||
} else {
|
||||
parserList.forEach {
|
||||
if (it.needParse) {
|
||||
val input = it.getInput()
|
||||
if (input.isBlank()) {
|
||||
Log.w("生成代码", "模板${it.code}输入为空,跳过处理。")
|
||||
} else {
|
||||
Log.d("生成代码", "已将${it.code}的值设置为${input}。")
|
||||
val section = it.section
|
||||
if (section == null) {
|
||||
sourceFile.writeValue(it.code, input)
|
||||
} else {
|
||||
sourceFile.writeValueFromSection(it.code, input, section)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.d("生成代码", "模板${it.code}无需处理。")
|
||||
}
|
||||
}
|
||||
return sourceFile.text
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取模板解析器列表
|
||||
* @param context Context
|
||||
* @return ArrayList<TemplateParser>
|
||||
*/
|
||||
fun getTemplateParserList(context: Context): ArrayList<TemplateParser> {
|
||||
if (this::arrayList.isInitialized)
|
||||
{
|
||||
Log.d("获取模板解析器","已经被调用了一次,返回成员变量")
|
||||
return arrayList
|
||||
}
|
||||
arrayList = ArrayList()
|
||||
val gson = Gson()
|
||||
val arrayList = ArrayList<TemplateParser>()
|
||||
val jsonArray = jsonData?.getJSONArray("action")
|
||||
if (jsonArray == null) {
|
||||
Log.e("获取模板解析器", "此模板没有action,无法读取。")
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="200dp"
|
||||
android:height="200dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M823.3,303.6c-12.5,-12.4 -32.9,-12.4 -45.3,0L429.1,652.5 246,459.3c-12.5,-12.4 -32.9,-12.4 -45.3,0 -12.4,12.5 -12.4,32.9 0,45.3l205.8,215.8c6.2,6.2 14.4,9.3 22.6,9.3 8.2,0 16.4,-3.1 22.7,-9.3l371.5,-371.5c12.4,-12.5 12.4,-32.8 0,-45.3z"
|
||||
android:fillColor="#FF000000"/>
|
||||
</vector>
|
6
app/src/main/res/drawable/ic_outline_location_on_24.xml
Normal file
6
app/src/main/res/drawable/ic_outline_location_on_24.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
|
||||
</vector>
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
|
|
@ -6,51 +6,34 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:fitsSystemWindows="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/coordinator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:windowBackground"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?android:attr/windowBackground"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:id="@id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarStyle" />
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:id="@id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:windowBackground"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:contentDescription="@string/action"
|
||||
app:tabMode="scrollable"
|
||||
app:tabTextAppearance="@style/TabLayoutTextStyle" />
|
||||
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_above="@+id/recyclerview"
|
||||
android:layout_below="@id/coordinator"
|
||||
android:gravity="center"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/myProgressBar"
|
||||
|
@ -61,12 +44,12 @@
|
|||
android:id="@+id/codeEditor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
android:layout_above="@id/recyclerview"
|
||||
android:layout_below="@id/appBarLayout" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:id="@id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
|
@ -78,5 +61,4 @@
|
|||
<include layout="@layout/edit_end" />
|
||||
|
||||
<include layout="@layout/edit_start" />
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
@ -7,12 +7,11 @@
|
|||
android:animateLayoutChanges="true"
|
||||
android:fitsSystemWindows="false">
|
||||
|
||||
<com.google.android.material.circularreveal.coordinatorlayout.CircularRevealCoordinatorLayout
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/rootLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -27,13 +26,21 @@
|
|||
android:id="@+id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:tabMode="fixed"
|
||||
app:tabTextAppearance="@style/TabLayoutTextStyle">
|
||||
android:background="@android:color/transparent"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="已安装" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="模板社区" />
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<fragment
|
||||
|
@ -41,6 +48,8 @@
|
|||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
|
@ -55,16 +64,15 @@
|
|||
android:text="@string/create"
|
||||
app:icon="@drawable/add" />
|
||||
|
||||
|
||||
</com.google.android.material.circularreveal.coordinatorlayout.CircularRevealCoordinatorLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<com.google.android.material.navigation.NavigationView
|
||||
android:id="@+id/navaiagtion"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
app:elevation="2dp"
|
||||
android:fitsSystemWindows="false"
|
||||
app:elevation="2dp"
|
||||
app:menu="@menu/menu_drawer_left" />
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
|
@ -8,6 +8,7 @@
|
|||
android:fitsSystemWindows="true"
|
||||
tools:context=".OrderListActivity">
|
||||
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -18,6 +19,16 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/transparent"
|
||||
app:tabMode="scrollable">
|
||||
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
|
@ -31,8 +42,6 @@
|
|||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
|
||||
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -47,19 +56,13 @@
|
|||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/contentLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
app:tabMode="scrollable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/viewPager2"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -68,6 +71,5 @@
|
|||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -86,7 +86,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -94,6 +94,7 @@
|
|||
android:layout_alignParentBottom="true"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/complete" />
|
||||
app:icon="@drawable/build"
|
||||
android:text="@string/build_unit"/>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -5,41 +5,33 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:windowBackground"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarStyle"
|
||||
app:layout_collapseMode="pin"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
android:layout_height="?attr/actionBarSize" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMode="fixed"
|
||||
app:tabTextAppearance="@style/TabLayoutTextStyle">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/all_units" />
|
||||
android:text="全部" />
|
||||
|
||||
<com.google.android.material.tabs.TabItem
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/recently_opened" />
|
||||
android:text="最近" />
|
||||
|
||||
</com.google.android.material.tabs.TabLayout>
|
||||
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
||||
|
@ -47,17 +39,18 @@
|
|||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/add" />
|
||||
android:text="@string/create_unit"
|
||||
app:icon="@drawable/add" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="80dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:windowBackground"
|
||||
android:padding="8dp">
|
||||
|
||||
|
@ -10,14 +10,13 @@
|
|||
android:layout_width="45dp"
|
||||
android:layout_height="45dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:src="@drawable/image" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toRightOf="@id/iconView"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/iconView"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
@ -30,6 +35,8 @@
|
|||
<ExpandableListView
|
||||
android:id="@+id/expandableList"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
|
||||
<TextView
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:id="@+id/describeView"
|
||||
style="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -23,21 +23,29 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/modError"
|
||||
style="@style/TextAppearance.Material3.TitleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/not_find_mod"
|
||||
style="@style/TextAppearance.Material3.TitleLarge"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:visibility="gone"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/modList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:visibility="gone" />
|
||||
android:layout_marginRight="8dp" />
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -786,7 +786,7 @@
|
|||
<string name="change_server_complete">The server has changed.</string>
|
||||
<string name="order_manager">The order management</string>
|
||||
<string name="log_out">logout</string>
|
||||
<string name="user_info">%1$s uid:%2$s</string>
|
||||
<string name="user_info">%1$s uid:%2$s location:%3$s</string>
|
||||
<string name="use_coupon">Will use coupons to create orders, still continue\? (After creating the order, use the coupon)</string>
|
||||
<string name="use">use</string>
|
||||
<string name="account_or_email">Account/email</string>
|
||||
|
|
|
@ -785,7 +785,7 @@
|
|||
<string name="change_server_complete">サーバーを変更しました。</string>
|
||||
<string name="order_manager">注文管理</string>
|
||||
<string name="log_out">掲載</string>
|
||||
<string name="user_info">最近ログイン:%1$s uid:%2$s</string>
|
||||
<string name="user_info">最近ログイン:%1$s uid:%2$s 住所:%3$s</string>
|
||||
<string name="use_coupon">クーポンを使った注文を作成しますが、継続しますか\?(注文作成完了後、クーポンを消費)</string>
|
||||
<string name="use">使用</string>
|
||||
<string name="account_or_email">アカウント/ eメール</string>
|
||||
|
|
|
@ -785,7 +785,7 @@
|
|||
<string name="change_server_complete">Сервер был изменен.</string>
|
||||
<string name="order_manager">Управление заказом</string>
|
||||
<string name="log_out">напечата</string>
|
||||
<string name="user_info">Зарегистрировано недавно :% $uid:% $2</string>
|
||||
<string name="user_info">Зарегистрировано недавно :%1$s uid:%2$s местожительство:%3$s</string>
|
||||
<string name="use_coupon">Мы используем купоны, чтобы создать порядок. (после создания заказа, купоны будут расходуться)</string>
|
||||
<string name="use">использова</string>
|
||||
<string name="account_or_email">Номер счета/письмо</string>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<string name="create_unit_complete">单位创建完成</string>
|
||||
<string name="create_unit_failed">单位创建失败</string>
|
||||
<string name="create_uniting">正在构建单位...</string>
|
||||
<string name="build_unit">构建单位</string>
|
||||
<string name="dialog_ok">确定</string>
|
||||
<string name="activation_app">激活铁锈助手</string>
|
||||
<string name="activation_app_tip">您的激活时间已过,请激活铁锈助手。</string>
|
||||
|
@ -98,7 +99,7 @@
|
|||
<string name="enter_file_path">请输入文件路径。</string>
|
||||
<string name="create_bookmark">创建书签</string>
|
||||
<string name="name_error">请输入模组名称。</string>
|
||||
<string name="unit_name_error">请输入单位名称。</string>
|
||||
<string name="file_name_error">请输入文件名称。</string>
|
||||
<string name="action_name_error">请输入活动名称。</string>
|
||||
<string name="database_null">此数据集无法加载,错误原因:%1$s。</string>
|
||||
<string name="describe_error">请输入描述。</string>
|
||||
|
@ -748,6 +749,7 @@
|
|||
<string name="undo">撤销</string>
|
||||
<string name="redo">重做</string>
|
||||
<string name="del_mod">删除</string>
|
||||
<string name="delete_error">删除失败。</string>
|
||||
<string name="need_save">[未保存]%1$s</string>
|
||||
<string name="game_data_and_synchronization">游戏数据与同步</string>
|
||||
<string name="game_data_and_synchronization_describe">管理已同步的游戏数据。</string>
|
||||
|
@ -800,7 +802,7 @@
|
|||
<string name="change_server_complete">已更改服务器。</string>
|
||||
<string name="order_manager">订单管理</string>
|
||||
<string name="log_out">登出</string>
|
||||
<string name="user_info">最近登录:%1$s uid:%2$s</string>
|
||||
<string name="user_info">最近登录:%1$s uid:%2$s ip归属地:%3$s</string>
|
||||
<string name="use_coupon">将使用优惠券创建订单,仍继续嘛?(创建订单完成后,将优惠券消耗)</string>
|
||||
<string name="use">使用</string>
|
||||
<string name="account_or_email">账号/电子邮件</string>
|
||||
|
@ -873,6 +875,7 @@
|
|||
<string name="template_id">模板id</string>
|
||||
<string name="subscription">订阅</string>
|
||||
<string name="de_subscription">退订</string>
|
||||
<string name="de_subscription_msg">要退订%1$s嘛?</string>
|
||||
<!-- <string name="search_suggestions_null">无搜索建议。</string>-->
|
||||
<!-- <string name="search_suggestions_number">共%1$d个搜索建议。</string>-->
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.coldmint.rust.core
|
||||
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.coldmint.rust.core.dataBean.TemplateDataBean
|
||||
import com.coldmint.rust.core.dataBean.template.TemplateInfo
|
||||
import com.coldmint.rust.core.dataBean.template.TemplatePackage
|
||||
|
@ -64,6 +66,18 @@ class LocalTemplatePackage(val directest: File) : TemplatePackage {
|
|||
return info?.name ?: directest.name
|
||||
}
|
||||
|
||||
override fun getDescription(): String {
|
||||
val info = getInfo()
|
||||
return info?.description ?: ""
|
||||
}
|
||||
|
||||
override fun delete(token: String, func: (Boolean) -> Unit) {
|
||||
func.invoke(FileOperator.delete_files(directest))
|
||||
}
|
||||
|
||||
override fun isLocal(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -497,10 +497,10 @@ class SourceFile(text: String) {
|
|||
stringBuilder.append(value)
|
||||
stringBuilder.append(sinfo.substring(endnum, sinfo.length - 1))
|
||||
stringBuilder.append(info.substring(sectionendnum, info.length - 2))
|
||||
if (hasSymbol) {
|
||||
text = stringBuilder.toString()
|
||||
text = if (hasSymbol) {
|
||||
stringBuilder.toString()
|
||||
} else {
|
||||
text = stringBuilder.substring(1)
|
||||
stringBuilder.substring(1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ data class CompileConfiguration(
|
|||
* Reference 引用是一种特殊的数据类型,编译器会尝试编译此值,若无法编译则使用原始值
|
||||
*/
|
||||
enum class CodeBlockType {
|
||||
Key, Value, Section, Note, VariableName, Reference
|
||||
Key, Value, Section, Note, VariableName, Reference, Symbol
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
package com.coldmint.rust.core.dataBean
|
||||
|
||||
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.core.dataBean.template.Template
|
||||
import com.coldmint.rust.core.dataBean.template.TemplatePackage
|
||||
import com.coldmint.rust.core.interfaces.ApiCallBack
|
||||
import com.coldmint.rust.core.web.ServerConfiguration
|
||||
import com.coldmint.rust.core.web.TemplatePhp
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 订阅信息
|
||||
* @property code Int
|
||||
* @property `data` List<Data>
|
||||
* @property message String
|
||||
* @constructor
|
||||
*/
|
||||
data class SubscriptionData(
|
||||
@SerializedName("code")
|
||||
val code: Int,
|
||||
@SerializedName("data")
|
||||
val `data`: List<Data>,
|
||||
@SerializedName("message")
|
||||
val message: String
|
||||
) {
|
||||
data class Data(
|
||||
@SerializedName("appVersionName")
|
||||
val appVersionName: String,
|
||||
@SerializedName("appVersionNumber")
|
||||
val appVersionNumber: String,
|
||||
@SerializedName("createTime")
|
||||
val createTime: String,
|
||||
@SerializedName("describe")
|
||||
val describe: String,
|
||||
@SerializedName("developer")
|
||||
val developer: String,
|
||||
@SerializedName("id")
|
||||
val id: String,
|
||||
@SerializedName("modificationTime")
|
||||
val modificationTime: String,
|
||||
@SerializedName("name")
|
||||
val name1: String,
|
||||
@SerializedName("public")
|
||||
val `public`: String,
|
||||
@SerializedName("subscriptionNumber")
|
||||
val subscriptionNumber: String,
|
||||
@SerializedName("templateList")
|
||||
val templateList: List<Template>,
|
||||
@SerializedName("templateNumber")
|
||||
val templateNumber: String,
|
||||
@SerializedName("versionName")
|
||||
val versionName: String,
|
||||
@SerializedName("versionNumber")
|
||||
val versionNumber: String
|
||||
) : TemplatePackage {
|
||||
data class Template(
|
||||
@SerializedName("content")
|
||||
val content: String,
|
||||
@SerializedName("createTime")
|
||||
val createTime: String,
|
||||
@SerializedName("deleted")
|
||||
val deleted: String,
|
||||
@SerializedName("developer")
|
||||
val developer: String,
|
||||
@SerializedName("id")
|
||||
val id: String,
|
||||
@SerializedName("modificationTime")
|
||||
val modificationTime: String,
|
||||
@SerializedName("packageId")
|
||||
val packageId: String,
|
||||
@SerializedName("title")
|
||||
val title: String
|
||||
) : com.coldmint.rust.core.dataBean.template.Template {
|
||||
|
||||
private val jsonObject: JSONObject by lazy {
|
||||
JSONObject(content)
|
||||
}
|
||||
|
||||
override fun getJson(): JSONObject {
|
||||
return jsonObject
|
||||
}
|
||||
|
||||
override fun getName(language: String): String {
|
||||
return title
|
||||
}
|
||||
|
||||
override fun getIcon(): Any? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun isLocal(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getLink(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return name1
|
||||
}
|
||||
|
||||
override fun getDescription(): String {
|
||||
return describe
|
||||
}
|
||||
|
||||
override fun delete(token: String, func: (Boolean) -> Unit) {
|
||||
TemplatePhp.instance.deleteSubscription(token, id, object : ApiCallBack<ApiResponse> {
|
||||
override fun onResponse(t: ApiResponse) {
|
||||
if (t.code == ServerConfiguration.Success_Code) {
|
||||
Log.d("取消订阅", "成功。")
|
||||
func.invoke(true)
|
||||
} else {
|
||||
Log.e("取消订阅", t.message)
|
||||
func.invoke(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: Exception) {
|
||||
e.printStackTrace()
|
||||
Log.e("取消订阅", e.toString())
|
||||
func.invoke(false)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override fun isLocal(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.coldmint.rust.core.dataBean.webTemplate
|
||||
package com.coldmint.rust.core.dataBean
|
||||
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
@ -22,10 +22,6 @@ data class WebTemplatePackageListData(
|
|||
val describe: String,
|
||||
@SerializedName("developer")
|
||||
val developer: String,
|
||||
@SerializedName("downloadNumber")
|
||||
val downloadNumber: Int,
|
||||
@SerializedName("templateNumber")
|
||||
val templateNumber: Int,
|
||||
@SerializedName("id")
|
||||
val id: String,
|
||||
@SerializedName("modificationTime")
|
||||
|
@ -33,12 +29,16 @@ data class WebTemplatePackageListData(
|
|||
@SerializedName("name")
|
||||
val name: String,
|
||||
@SerializedName("public")
|
||||
val `public`: Boolean,
|
||||
val `public`: String,
|
||||
@SerializedName("subscribe")
|
||||
var subscribe: Boolean,
|
||||
@SerializedName("subscriptionNumber")
|
||||
val subscriptionNumber: String,
|
||||
@SerializedName("templateNumber")
|
||||
val templateNumber: String,
|
||||
@SerializedName("versionName")
|
||||
val versionName: String,
|
||||
@SerializedName("versionNumber")
|
||||
val versionNumber: String,
|
||||
@SerializedName("subscribe")
|
||||
val subscribe: Boolean
|
||||
val versionNumber: String
|
||||
)
|
||||
}
|
|
@ -12,5 +12,24 @@ interface TemplatePackage {
|
|||
fun getName(): String
|
||||
|
||||
|
||||
/**
|
||||
* 获取描述
|
||||
* @return String
|
||||
*/
|
||||
fun getDescription(): String
|
||||
|
||||
/**
|
||||
* 实现删除方法,本地模板删除,远程模板退订
|
||||
* @return Boolean
|
||||
*/
|
||||
fun delete(token: String, func: (Boolean) -> Unit)
|
||||
|
||||
|
||||
/**
|
||||
* 是否为本地模板包
|
||||
* @return Boolean
|
||||
*/
|
||||
fun isLocal():Boolean
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package com.coldmint.rust.core.dataBean.template
|
||||
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 网络模板详情
|
||||
* @property code Int
|
||||
* @property `data` Data
|
||||
* @property message String
|
||||
* @constructor
|
||||
*/
|
||||
data class WebTemplateData(
|
||||
@SerializedName("code")
|
||||
val code: Int,
|
||||
@SerializedName("data")
|
||||
val `data`: Data,
|
||||
@SerializedName("message")
|
||||
val message: String
|
||||
) {
|
||||
data class Data(
|
||||
@SerializedName("content")
|
||||
val content: String,
|
||||
@SerializedName("createTime")
|
||||
val createTime: String,
|
||||
@SerializedName("deleted")
|
||||
val deleted: String,
|
||||
@SerializedName("developer")
|
||||
val developer: String,
|
||||
@SerializedName("id")
|
||||
val id: String,
|
||||
@SerializedName("modificationTime")
|
||||
val modificationTime: String,
|
||||
@SerializedName("packageId")
|
||||
val packageId: String,
|
||||
@SerializedName("title")
|
||||
val title: String,
|
||||
) : Template {
|
||||
private lateinit var jsonObject: JSONObject
|
||||
|
||||
override fun getJson(): JSONObject {
|
||||
if (!this::jsonObject.isInitialized) {
|
||||
jsonObject = JSONObject(content)
|
||||
}
|
||||
return jsonObject
|
||||
}
|
||||
|
||||
override fun getName(language: String): String {
|
||||
return if (getJson().has("name_$language")) {
|
||||
return getJson().getString("name_$language")
|
||||
} else {
|
||||
return getJson().getString("name")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIcon(): Any? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun isLocal(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getLink(): String {
|
||||
return id
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ data class SpaceInfoData(
|
|||
val praise: Int,
|
||||
val expirationTime: String,
|
||||
val userName: String,
|
||||
val gender: Int
|
||||
val gender: Int,
|
||||
val location: String
|
||||
)
|
||||
}
|
|
@ -10,7 +10,7 @@ interface TemplateParser {
|
|||
/**
|
||||
* 实现获取用户输入
|
||||
*/
|
||||
val input: String
|
||||
fun getInput(): String
|
||||
|
||||
/**
|
||||
* 实现实例化视图
|
||||
|
|
|
@ -18,8 +18,10 @@ class InputParser(val context: Context, val data: InputParserDataBean) : Templat
|
|||
private val parserInputBinding: ParserInputBinding =
|
||||
ParserInputBinding.inflate(LayoutInflater.from(context))
|
||||
|
||||
override val input: String
|
||||
get() = parserInputBinding.inputView.text.toString()
|
||||
override fun getInput(): String {
|
||||
return parserInputBinding.inputView.text.toString()
|
||||
}
|
||||
|
||||
|
||||
override val contextView: View
|
||||
get() {
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.coldmint.rust.core.databinding.ParserIntroduceBinding
|
|||
import com.coldmint.rust.core.interfaces.TemplateParser
|
||||
|
||||
/**
|
||||
* 注释
|
||||
* @author Cold Mint
|
||||
* @date 2021/12/17 14:55
|
||||
*/
|
||||
|
@ -24,9 +25,11 @@ class IntroducingParser(
|
|||
LayoutInflater.from(context)
|
||||
)
|
||||
|
||||
override fun getInput(): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
override val input: String
|
||||
get() = ""
|
||||
override val contextView: View
|
||||
get() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
|
|
|
@ -18,8 +18,7 @@ class ListParser(val context: Context, val data: ListParserDataBean) : TemplateP
|
|||
)
|
||||
private val itemList: List<String> = data.itemList.split(",")
|
||||
private val dataList: List<String>? = data.dataList?.split(",")
|
||||
override val input: String
|
||||
get() {
|
||||
override fun getInput(): String {
|
||||
val index = parserListBinding.spacer.selectedItemPosition
|
||||
return if (dataList != null && dataList.size == itemList.size) {
|
||||
dataList[index]
|
||||
|
@ -28,6 +27,7 @@ class ListParser(val context: Context, val data: ListParserDataBean) : TemplateP
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
override val contextView: View
|
||||
get() {
|
||||
val adapter =
|
||||
|
|
|
@ -4,7 +4,9 @@ import android.os.Handler
|
|||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import com.coldmint.rust.core.dataBean.ApiResponse
|
||||
import com.coldmint.rust.core.dataBean.webTemplate.WebTemplatePackageListData
|
||||
import com.coldmint.rust.core.dataBean.SubscriptionData
|
||||
import com.coldmint.rust.core.dataBean.WebTemplatePackageListData
|
||||
import com.coldmint.rust.core.dataBean.template.WebTemplateData
|
||||
import com.coldmint.rust.core.interfaces.ApiCallBack
|
||||
import com.google.gson.Gson
|
||||
import okhttp3.*
|
||||
|
@ -21,57 +23,8 @@ class TemplatePhp {
|
|||
|
||||
private constructor()
|
||||
|
||||
/**
|
||||
* 发送错误报告
|
||||
* @param website 网址(如果程序已崩溃,需要重新读取设置的网址)
|
||||
* @param message String 消息
|
||||
* @param versionName 版本名
|
||||
* @param versionNumber 版本号
|
||||
* @param apiCallBack ApiCallBack<CouponListDataBean>
|
||||
*/
|
||||
fun send(
|
||||
message: String,
|
||||
versionName: String,
|
||||
versionNumber: Int,
|
||||
apiCallBack: ApiCallBack<ApiResponse>, website: String = ServerConfiguration.website
|
||||
) {
|
||||
val okHttpClient = ServerConfiguration.initOkHttpClient()
|
||||
val requestBodyBuilder: FormBody.Builder =
|
||||
FormBody.Builder().add("message", message).add("versionName", versionName)
|
||||
.add("versionNumber", versionNumber.toString())
|
||||
val requestBody = requestBodyBuilder.build()
|
||||
val request =
|
||||
Request.Builder()
|
||||
.url(website + "php/error.php?action=send")
|
||||
.post(requestBody).build()
|
||||
val call = okHttpClient.newCall(request)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val gson = Gson()
|
||||
call.enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
e.printStackTrace()
|
||||
handler.post { apiCallBack.onFailure(e) }
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
try {
|
||||
val data = response.body!!.string()
|
||||
Log.d("错误反馈数据", data)
|
||||
val finalApiResponse =
|
||||
gson.fromJson(data, ApiResponse::class.java)
|
||||
handler.post {
|
||||
apiCallBack.onResponse(finalApiResponse)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
handler.post {
|
||||
apiCallBack.onFailure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*获取公开的模板包列表
|
||||
|
@ -118,6 +71,188 @@ class TemplatePhp {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*获取模板详情
|
||||
* @param apiCallBack ApiCallBack<CouponListDataBean>
|
||||
*/
|
||||
fun getTemplate(
|
||||
id: String,
|
||||
apiCallBack: ApiCallBack<WebTemplateData>
|
||||
) {
|
||||
val okHttpClient = ServerConfiguration.initOkHttpClient()
|
||||
val requestBodyBuilder: FormBody.Builder =
|
||||
FormBody.Builder().add("id", id)
|
||||
val requestBody = requestBodyBuilder.build()
|
||||
val request =
|
||||
Request.Builder()
|
||||
.url(ServerConfiguration.website + "php/template.php?action=getTemplate")
|
||||
.post(requestBody).build()
|
||||
val call = okHttpClient.newCall(request)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val gson = Gson()
|
||||
call.enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
e.printStackTrace()
|
||||
handler.post { apiCallBack.onFailure(e) }
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
try {
|
||||
val data = response.body!!.string()
|
||||
Log.d("获取网络模板详情", data)
|
||||
val finalWebTemplatePackageListData =
|
||||
gson.fromJson(data, WebTemplateData::class.java)
|
||||
handler.post {
|
||||
apiCallBack.onResponse(finalWebTemplatePackageListData)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
handler.post {
|
||||
apiCallBack.onFailure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*获用户订阅的模板列表
|
||||
* @param apiCallBack ApiCallBack<SubscriptionData>
|
||||
*/
|
||||
fun getSubscriptionDataList(
|
||||
token: String,
|
||||
apiCallBack: ApiCallBack<SubscriptionData>
|
||||
) {
|
||||
val okHttpClient = ServerConfiguration.initOkHttpClient()
|
||||
val requestBodyBuilder: FormBody.Builder =
|
||||
FormBody.Builder().add("token", token)
|
||||
val requestBody = requestBodyBuilder.build()
|
||||
val request =
|
||||
Request.Builder()
|
||||
.url(ServerConfiguration.website + "php/template.php?action=getSubscriptionData")
|
||||
.post(requestBody).build()
|
||||
val call = okHttpClient.newCall(request)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val gson = Gson()
|
||||
call.enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
e.printStackTrace()
|
||||
handler.post { apiCallBack.onFailure(e) }
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
try {
|
||||
val data = response.body!!.string()
|
||||
Log.d("获取网络订阅", data)
|
||||
val finalSubscriptionData =
|
||||
gson.fromJson(data, SubscriptionData::class.java)
|
||||
handler.post {
|
||||
apiCallBack.onResponse(finalSubscriptionData)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
handler.post {
|
||||
apiCallBack.onFailure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*订阅模板
|
||||
* @param apiCallBack ApiCallBack<CouponListDataBean>
|
||||
*/
|
||||
fun subscription(
|
||||
token: String,
|
||||
packageId: String,
|
||||
apiCallBack: ApiCallBack<ApiResponse>
|
||||
) {
|
||||
val okHttpClient = ServerConfiguration.initOkHttpClient()
|
||||
val requestBodyBuilder: FormBody.Builder =
|
||||
FormBody.Builder().add("token", token).add("packageId", packageId)
|
||||
val requestBody = requestBodyBuilder.build()
|
||||
val request =
|
||||
Request.Builder()
|
||||
.url(ServerConfiguration.website + "php/template.php?action=subscription")
|
||||
.post(requestBody).build()
|
||||
val call = okHttpClient.newCall(request)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val gson = Gson()
|
||||
call.enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
e.printStackTrace()
|
||||
handler.post { apiCallBack.onFailure(e) }
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
try {
|
||||
val data = response.body!!.string()
|
||||
Log.d("订阅模板", data)
|
||||
val finalApiResponse =
|
||||
gson.fromJson(data, ApiResponse::class.java)
|
||||
handler.post {
|
||||
apiCallBack.onResponse(finalApiResponse)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
handler.post {
|
||||
apiCallBack.onFailure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
*退订模板
|
||||
* @param apiCallBack ApiCallBack<CouponListDataBean>
|
||||
*/
|
||||
fun deleteSubscription(
|
||||
token: String,
|
||||
packageId: String,
|
||||
apiCallBack: ApiCallBack<ApiResponse>
|
||||
) {
|
||||
val okHttpClient = ServerConfiguration.initOkHttpClient()
|
||||
val requestBodyBuilder: FormBody.Builder =
|
||||
FormBody.Builder().add("token", token).add("packageId", packageId)
|
||||
val requestBody = requestBodyBuilder.build()
|
||||
val request =
|
||||
Request.Builder()
|
||||
.url(ServerConfiguration.website + "php/template.php?action=deleteSubscription")
|
||||
.post(requestBody).build()
|
||||
val call = okHttpClient.newCall(request)
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
val gson = Gson()
|
||||
call.enqueue(object : Callback {
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
e.printStackTrace()
|
||||
handler.post { apiCallBack.onFailure(e) }
|
||||
}
|
||||
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
try {
|
||||
val data = response.body!!.string()
|
||||
Log.d("退订模板", data)
|
||||
val finalApiResponse =
|
||||
gson.fromJson(data, ApiResponse::class.java)
|
||||
handler.post {
|
||||
apiCallBack.onResponse(finalApiResponse)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
handler.post {
|
||||
apiCallBack.onFailure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模板包
|
||||
* @param id String 模板包id
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/title"
|
||||
android:visibility="gone" />
|
||||
android:text="@string/title" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/checkbox"
|
||||
|
@ -64,6 +63,7 @@
|
|||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user