Replaced build actions menu with 'Run tasks' action

This commit is contained in:
Akash Yadav
2022-10-25 21:52:34 +05:30
parent 7f3606df8f
commit ba9c7c9cfb
42 changed files with 1037 additions and 456 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<profile name="Gradle Imported" enabled="true">
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.auto.value/auto-value/1.9/fd4ec236e20ae0895c30e83260f611bcbc185086/auto-value-1.9.jar" />
<entry name="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.auto.value/auto-value/1.10/e97ada61b651d7dff21931c2cc1b158e870cb417/auto-value-1.10.jar" />
</processorPath>
<module name="AndroidIDE.build-tools.google-java-format.main" />
</profile>
Binary file not shown.
@@ -1,40 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class BuildAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.build)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run)
}
override val id: String = "editor_build"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"build")
return true
}
}
@@ -1,44 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.ActionMenu
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class BuildActionMenu() : BaseBuildAction(), ActionMenu {
constructor(context: Context) : this() {
label = context.getString(R.string.build_tasks)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run)
addAction(BuildAction(context))
addAction(AssembleDebugAction(context))
addAction(AssembleReleaseAction(context))
addAction(CreateAABAction(context))
addAction(CleanAction(context))
addAction(RebuildAction(context))
}
override val children: MutableSet<ActionItem> = mutableSetOf()
override val id: String = "editor_buildTasks"
}
@@ -1,39 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class CleanAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.clean_project)
icon = ContextCompat.getDrawable(context, R.drawable.ic_clean)
}
override val id: String = "editor_clean"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"clean")
return true
}
}
@@ -1,39 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class CreateAABAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.create_aab)
icon = ContextCompat.getDrawable(context, R.drawable.ic_bundle)
}
override val id: String = "editor_createAAB"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"bundle")
return true
}
}
@@ -1,39 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class RebuildAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.clean_amp_build)
icon = ContextCompat.getDrawable(context, R.drawable.ic_rebuild)
}
override val id: String = "editor_cleanAndBuild"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"clean", "build")
return true
}
}
@@ -1,42 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.ActionMenu
import com.itsaky.androidide.actions.BaseBuildAction
import com.itsaky.androidide.actions.lint.LintTaskMenu
/** @author Akash Yadav */
class RunActionMenu() : BaseBuildAction(), ActionMenu {
override val children: MutableSet<ActionItem> = mutableSetOf()
constructor(context: Context) : this() {
label = context.getString(R.string.run)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run)
addAction(BuildActionMenu(context))
addAction(LintTaskMenu(context))
}
override val id: String = "editor_runMenu"
}
@@ -1,40 +1,52 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class AssembleReleaseAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.build_release)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run_release)
}
override val id: String = "editor_assembleRelease"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"assembleRelease")
return true
}
}
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.build
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
import com.itsaky.androidide.fragments.RunTasksDialogFragment
import com.itsaky.androidide.resources.R
/** @author Akash Yadav */
class RunTasksAction() : BaseBuildAction() {
override val id: String = "ide.build.runTasks"
private var dialog: RunTasksDialogFragment? = null
constructor(context: Context) : this() {
label = context.getString(R.string.title_run_tasks)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run_tasks)
}
override fun execAction(data: ActionData): Any {
dialog?.dismiss()
dialog = null
dialog = RunTasksDialogFragment()
return dialog!!
}
override fun postExec(data: ActionData, result: Any) {
if (result !is RunTasksDialogFragment) {
return
}
val activity = getActivity(data)!!
result.show(activity.supportFragmentManager, this.id)
}
}
@@ -1,39 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.lint
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class LintDebugAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.lint_debug)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run_debug)
}
override val id: String = "editor_lintDebug"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"lintDebug")
return true
}
}
@@ -1,39 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.lint
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class LintReleaseAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.lint_release)
icon = ContextCompat.getDrawable(context, R.drawable.ic_run_release)
}
override val id: String = "editor_lintRelease"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"lintRelease")
return true
}
}
@@ -1,41 +0,0 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.lint
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionItem
import com.itsaky.androidide.actions.ActionMenu
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class LintTaskMenu() : BaseBuildAction(), ActionMenu {
constructor(context: Context) : this() {
label = context.getString(R.string.lint_tasks)
icon = ContextCompat.getDrawable(context, R.drawable.ic_lint)
addAction(LintAction(context))
addAction(LintDebugAction(context))
addAction(LintReleaseAction(context))
}
override val children: MutableSet<ActionItem> = mutableSetOf()
override val id: String = "editor_lintTasks"
}
@@ -0,0 +1,93 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters
import androidx.recyclerview.widget.RecyclerView
import com.blankj.utilcode.util.ThreadUtils
import com.itsaky.androidide.progress.ProgressManager
import com.itsaky.androidide.utils.StopWatch
/**
* Filterable [RecyclerView.Adapter].
*
* @author Akash Yadav
*/
abstract class FilterableRecyclerViewAdapter<V : RecyclerView.ViewHolder, D>(val items: List<D>) :
RecyclerView.Adapter<V>() {
protected var filtered: List<D> = mutableListOf<D>().apply { addAll(items) }
private var filterThread: FilterThread<D>? = null
/**
* Filter the list with the given query.
*
* @param query The query.
*/
fun filter(query: String?) {
filterThread?.let { ProgressManager.instance.cancel(it) }
filterThread =
FilterThread(this.items, query?.trim(), this::onFilter).apply {
start()
join()
}
filterThread!!.let {
ThreadUtils.runOnUiThread {
this.filtered = it.filtered
notifyDataSetChanged()
}
}
}
/** Get the list item at given index. */
fun getItem(index: Int): D {
return filtered[index]
}
override fun getItemCount(): Int {
return filtered.size
}
/** Get the query candidate for the given list item. */
abstract fun getQueryCandidate(item: D): String
/** Called on every item when filtering the data. */
protected open fun onFilter(item: D, query: String): Boolean {
return getQueryCandidate(item).contains(query, ignoreCase = true)
}
private class FilterThread<E>(
val items: List<E>,
val query: String?,
val onFilter: (E, String) -> Boolean
) : Thread("TaskFilterThread") {
lateinit var filtered: List<E>
override fun run() {
this.filtered =
if (query.isNullOrBlank()) {
items
} else
items.filter {
ProgressManager.abortIfCancelled()
onFilter(it, query)
}
}
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.itsaky.androidide.adapters.RunTasksCategoryAdapter.VH
import com.itsaky.androidide.databinding.LayoutRunTasksCategoryBinding
import com.itsaky.androidide.models.Checkable
import com.itsaky.androidide.models.RunTasksCategory
import com.itsaky.androidide.tooling.api.model.GradleTask
/** @author Akash Yadav */
class RunTasksCategoryAdapter(
val items: List<RunTasksCategory>,
private val onCheckChanged: (Checkable<GradleTask>) -> Unit = {}
) : RecyclerView.Adapter<VH>() {
class VH(val binding: LayoutRunTasksCategoryBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
return VH(
LayoutRunTasksCategoryBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
}
override fun getItemCount(): Int {
return items.size
}
fun getItem(index: Int): RunTasksCategory {
return items[index]
}
override fun onBindViewHolder(holder: VH, position: Int) {
val binding = holder.binding
val category = getItem(position)
binding.header.setText(category.title)
binding.tasks.adapter = RunTasksListAdapter(category.tasks, onCheckChanged)
}
}
@@ -0,0 +1,66 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.itsaky.androidide.adapters.RunTasksListAdapter.VH
import com.itsaky.androidide.databinding.LayoutRunTaskItemBinding
import com.itsaky.androidide.models.Checkable
import com.itsaky.androidide.tooling.api.model.GradleTask
/**
* Adapter for showing tasks list in [RunTaskDialogFragment]
* [com.itsaky.androidide.fragments.RunTasksDialogFragment].
*
* @author Akash Yadav
*/
class RunTasksListAdapter
@JvmOverloads
constructor(
tasks: List<Checkable<GradleTask>>,
val onCheckChanged: (Checkable<GradleTask>) -> Unit = {}
) : FilterableRecyclerViewAdapter<VH, Checkable<GradleTask>>(tasks) {
data class VH(val binding: LayoutRunTaskItemBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
return VH(LayoutRunTaskItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
override fun onBindViewHolder(holder: VH, position: Int) {
val binding = holder.binding
val data = getItem(position)
val task = data.data
binding.check.isChecked = data.isChecked
binding.taskPath.text = task.path
binding.taskDesc.text = task.description
binding.root.setOnClickListener {
data.isChecked = !data.isChecked
binding.check.isChecked = data.isChecked
onCheckChanged(data)
}
}
override fun getQueryCandidate(item: Checkable<GradleTask>): String {
return item.data.path
}
}
@@ -0,0 +1,178 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.fragments
import android.os.Bundle
import android.text.Editable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.TransitionManager
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.transition.MaterialSharedAxis
import com.itsaky.androidide.R.string
import com.itsaky.androidide.adapters.RunTasksCategoryAdapter
import com.itsaky.androidide.adapters.RunTasksListAdapter
import com.itsaky.androidide.databinding.LayoutRunTaskBinding
import com.itsaky.androidide.databinding.LayoutRunTaskDialogBinding
import com.itsaky.androidide.lookup.Lookup
import com.itsaky.androidide.models.Checkable
import com.itsaky.androidide.models.RunTasksCategory
import com.itsaky.androidide.projects.ProjectManager
import com.itsaky.androidide.projects.builder.BuildService
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.tasks.executeAsync
import com.itsaky.androidide.tooling.api.model.GradleTask
import com.itsaky.androidide.utils.ILogger
import com.itsaky.androidide.utils.SingleTextWatcher
import com.itsaky.androidide.viewmodel.RunTasksViewModel
import com.itsaky.toaster.toastInfo
/**
* A bottom sheet dialog fragment to show UI which allows the users to select and execute Gradle
* tasks from the initialized project.
*
* @author Akash Yadav
*/
class RunTasksDialogFragment : BottomSheetDialogFragment() {
private lateinit var binding: LayoutRunTaskDialogBinding
private lateinit var run: LayoutRunTaskBinding
private val viewModel: RunTasksViewModel by viewModels()
private val log = ILogger.newInstance("RunTasksDialogFragment")
companion object {
private const val CHILD_LOADING = 0
private const val CHILD_TASKS = 1
private const val CHILD_CONFIRMATION = 2
private const val CHILD_PROJECT_NOT_INITIALIZED = 3
// The minimum amount of time (in milliseconds) the adapter should wait after the query is
// changed before starting any further filter request.
// A too less value here will result in UI lags
private const val SEARCH_DELAY = 500
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
this.binding = LayoutRunTaskDialogBinding.inflate(inflater, container, false)
this.run = this.binding.run
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.observeDisplayedChild(viewLifecycleOwner) {
val transition =
MaterialSharedAxis(MaterialSharedAxis.X, it > this.binding.flipper.displayedChild)
TransitionManager.beginDelayedTransition(this.binding.root, transition)
this.binding.flipper.displayedChild = it
}
viewModel.observeQuery(viewLifecycleOwner) {
val adapter = run.categories.adapter
if (adapter !is RunTasksCategoryAdapter) {
return@observeQuery
}
for (index in 0 until viewModel.categories.size) {
val layout =
run.categories.layoutManager
?.findViewByPosition(index)
?.findViewById<RecyclerView>(com.itsaky.androidide.R.id.tasks)
?: continue
val childAdapter = layout.adapter
if (childAdapter !is RunTasksListAdapter) {
continue
}
childAdapter.filter(it)
}
}
run.searchInput.editText?.addTextChangedListener(
object : SingleTextWatcher() {
override fun afterTextChanged(s: Editable?) {
viewModel.query = s?.toString() ?: ""
}
}
)
binding.exec.setOnClickListener {
if (viewModel.selected.isEmpty()) {
toastInfo(getString(string.msg_err_select_tasks))
return@setOnClickListener
}
if (viewModel.displayedChild == CHILD_TASKS) {
binding.confirm.msg.text =
getString(R.string.msg_tasks_to_run, viewModel.getSelectedTaskPaths())
viewModel.displayedChild = CHILD_CONFIRMATION
return@setOnClickListener
}
if (viewModel.displayedChild == CHILD_CONFIRMATION) {
val buildService =
Lookup.DEFAULT.lookup(BuildService.KEY_BUILD_SERVICE)
?: run {
log.error("Cannot find build service")
return@setOnClickListener
}
val toRun = viewModel.selected.toTypedArray()
buildService.executeTasks(*toRun)
dismiss()
}
}
binding.confirm.cancel.setOnClickListener { viewModel.displayedChild = CHILD_TASKS }
viewModel.displayedChild = CHILD_LOADING
executeAsync({
val rootProject =
ProjectManager.rootProject ?: return@executeAsync emptyList<Checkable<GradleTask>>()
val tasks = rootProject.tasks.map { Checkable(false, it) }.toMutableList()
tasks.addAll(rootProject.subModules.flatMap { it.tasks }.map { Checkable(false, it) })
return@executeAsync tasks
}) { tasks ->
viewModel.tasks = tasks ?: emptyList()
viewModel.displayedChild =
if (viewModel.tasks.isNotEmpty()) CHILD_TASKS else CHILD_PROJECT_NOT_INITIALIZED
val onCheckChanged: (Checkable<GradleTask>) -> Unit = { item ->
if (item.isChecked) {
viewModel.select(item.data.path)
} else {
viewModel.deselect(item.data.path)
}
}
viewModel.categories =
listOf(
RunTasksCategory(R.string.title_common, viewModel.commonTasks),
RunTasksCategory(R.string.title_all_tasks, viewModel.tasks)
)
run.categories.adapter = RunTasksCategoryAdapter(viewModel.categories, onCheckChanged)
}
}
}
@@ -0,0 +1,25 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.models
/**
* Holds data that can be checked/unchecked.
*
* @author Akash Yadav
*/
data class Checkable<T>(var isChecked: Boolean, val data: T)
@@ -1,39 +1,24 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.actions.lint
import android.content.Context
import androidx.core.content.ContextCompat
import com.itsaky.androidide.resources.R
import com.itsaky.androidide.actions.ActionData
import com.itsaky.androidide.actions.BaseBuildAction
/** @author Akash Yadav */
class LintAction() : BaseBuildAction() {
constructor(context: Context) : this() {
label = context.getString(R.string.lint)
icon = ContextCompat.getDrawable(context, R.drawable.ic_lint)
}
override val id: String = "editor_lint"
override fun execAction(data: ActionData): Boolean {
execTasks(data = data, resultHandler = {},"lint")
return true
}
}
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.models
import androidx.annotation.StringRes
import com.itsaky.androidide.tooling.api.model.GradleTask
/** @author Akash Yadav */
data class RunTasksCategory(@StringRes val title: Int, val tasks: List<Checkable<GradleTask>>)
@@ -22,7 +22,7 @@ import com.itsaky.androidide.actions.ActionsRegistry
import com.itsaky.androidide.actions.build.CancelBuildAction
import com.itsaky.androidide.actions.build.ProjectSyncAction
import com.itsaky.androidide.actions.build.QuickRunAction
import com.itsaky.androidide.actions.build.RunActionMenu
import com.itsaky.androidide.actions.build.RunTasksAction
import com.itsaky.androidide.actions.editor.CopyAction
import com.itsaky.androidide.actions.editor.CutAction
import com.itsaky.androidide.actions.editor.ExpandSelectionAction
@@ -52,7 +52,7 @@ class EditorActivityActions {
registry.registerAction(UndoAction(context))
registry.registerAction(RedoAction(context))
registry.registerAction(QuickRunAction(context))
registry.registerAction(RunActionMenu(context))
registry.registerAction(RunTasksAction(context))
registry.registerAction(SaveFileAction(context))
registry.registerAction(PreviewLayoutAction(context))
registry.registerAction(FindActionMenu(context))
@@ -0,0 +1,101 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.viewmodel
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import com.itsaky.androidide.models.Checkable
import com.itsaky.androidide.models.RunTasksCategory
import com.itsaky.androidide.tooling.api.model.GradleTask
/** @author Akash Yadav */
class RunTasksViewModel : ViewModel() {
// These tasks should be easily accessible to user
private val _commonTaskNames =
setOf(
"assembleDebug",
"assembleRelease",
"clean",
"build",
"bundle",
"lint",
"lintDebug",
"lintRelease"
)
private val _categories = MutableLiveData(listOf<RunTasksCategory>())
private val _tasks = MutableLiveData(listOf<Checkable<GradleTask>>())
private val _commonTasks = MutableLiveData(listOf<Checkable<GradleTask>>())
private val _selected = MutableLiveData(mutableSetOf<String>())
private val _displayedChild = MutableLiveData(0)
private val _query = MutableLiveData("")
var categories: List<RunTasksCategory>
get() = _categories.value!!
set(value) {
_categories.value = value
}
var tasks: List<Checkable<GradleTask>>
get() = _tasks.value!!
set(value) {
_tasks.value = value
_commonTasks.value = value.filter { _commonTaskNames.contains(it.data.name) }
}
val commonTasks: List<Checkable<GradleTask>>
get() = _commonTasks.value!!
var displayedChild: Int
get() = this._displayedChild.value!!
set(value) {
this._displayedChild.value = value
}
var query: String
get() = _query.value!!
set(value) {
_query.value = value
}
val selected: Set<String>
get() = _selected.value!!
fun observeDisplayedChild(owner: LifecycleOwner, observer: Observer<Int>) {
_displayedChild.observe(owner, observer)
}
fun observeQuery(owner: LifecycleOwner, observer: Observer<String>) {
_query.observe(owner, observer)
}
fun select(item: String) {
this._selected.value!!.add(item)
}
fun deselect(item: String) {
this._selected.value!!.remove(item)
}
fun getSelectedTaskPaths(): String {
return selected.joinToString(separator = "\n")
}
}
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.4"
app:srcCompat="@drawable/ic_android"
app:tint="@color/green_500" />
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:maxLines="1"
android:text="@string/msg_project_not_initialized"
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/icon" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/search_input"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:hint="@string/hint_search_tasks"
android:theme="@style/AppTheme.TextInputLayout"
app:boxBackgroundColor="@color/content_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.google.android.material.textfield.TextInputLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/categories"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:descendantFocusability="blocksDescendants"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/search_input"
tools:itemCount="3"
tools:listitem="@layout/layout_run_tasks_category" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:nestedScrollingEnabled="true">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:gravity="center_vertical"
android:text="@string/title_run_tasks"
android:textAppearance="@style/TextAppearance.Material3.ActionBar.Title"
app:layout_constraintBottom_toBottomOf="@id/exec"
app:layout_constraintEnd_toStartOf="@id/exec"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/exec" />
<com.google.android.material.button.MaterialButton
android:id="@+id/exec"
style="@style/Widget.Material3.Button.IconButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
android:tooltipText="@string/run"
app:icon="@drawable/ic_run"
app:iconTint="@color/green_500"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/separator"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/primaryLightColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/exec" />
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/separator">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/loading_tasks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/msg_loading_tasks"
android:textAppearance="@style/TextAppearance.Material3.BodySmall" />
<include
android:id="@+id/run"
layout="@layout/layout_run_task" />
<include
android:id="@+id/confirm"
layout="@layout/layout_run_tasks_confirmation" />
<include
android:id="@+id/not_initialized"
layout="@layout/layout_project_not_initialized" />
</ViewFlipper>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:descendantFocusability="blocksDescendants"
android:focusable="true">
<com.google.android.material.checkbox.MaterialCheckBox
android:id="@+id/check"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:gravity="center_vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/task_path"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
app:layout_constraintBottom_toTopOf="@id/task_desc"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/check"
app:layout_constraintTop_toTopOf="@id/check"
tools:text=":app:assemble" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/task_desc"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:maxLines="1"
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
app:layout_constraintBottom_toBottomOf="@id/check"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/check"
app:layout_constraintTop_toBottomOf="@id/task_path"
tools:text="Assemble main outputs for all the variants." />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/separator"
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:background="@color/primaryLightColor"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/separator"
tools:text="@string/title_all_tasks" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/tasks"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/header"
tools:itemCount="3"
tools:listitem="@layout/layout_run_task_item" />
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/title_confirmation"
android:textAppearance="@style/TextAppearance.Material3.TitleMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/msg"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@string/msg_tasks_to_run"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<com.google.android.material.button.MaterialButton
android:id="@+id/cancel"
style="@style/Widget.Material3.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="@android:string/cancel"
android:textColor="@color/secondaryColor"
app:cornerRadius="8dp"
app:icon="@drawable/ic_close"
app:iconTint="@color/secondaryColor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/msg"
app:rippleColor="@color/primaryLightColor"
app:strokeColor="@color/secondaryColor"
app:strokeWidth="2dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
+1
View File
@@ -1,5 +1,6 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
android {
namespace "com.itsaky.androidide.projects"
@@ -31,4 +31,4 @@ open class GradleTask(
displayName: String?,
isPublic: Boolean?,
val projectPath: String?
) : IdeLaunchable(displayName, isPublic), Serializable {}
) : IdeLaunchable(displayName, isPublic), Serializable
@@ -0,0 +1,8 @@
<!-- drawable/window_maximize.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="@color/primaryIconColor" android:pathData="M8 3H16C18.76 3 21 5.24 21 8V16C21 18.76 18.76 21 16 21H8C5.24 21 3 18.76 3 16V8C3 5.24 5.24 3 8 3M8 5C6.34 5 5 6.34 5 8V16C5 17.66 6.34 19 8 19H16C17.66 19 19 17.66 19 16V8C19 6.34 17.66 5 16 5H8Z" />
</vector>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ This file is part of AndroidIDE.
~
~ AndroidIDE is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ AndroidIDE is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_rounded_square" />
<item
android:width="12dp"
android:height="12dp"
android:drawable="@drawable/ic_run"
android:start="5.5dp"
android:top="5.5dp"/>
</layer-list>
+1 -1
View File
@@ -281,7 +281,7 @@
<string name="msg_compiler_module_installed">কম্পাইলার মডিউল সফলভাবে ইনস্টল করা হয়েছে!</string>
<string name="action_expand_selection">নির্বাচন প্রসারিত করুন</string>
<string name="idepref_java_matchLower_title">ছোট হাতের অক্ষর এও কমপ্লিশন করুন</string>
<string name="idepref_editor_category_common">সাধারণ</string>
<string name="title_common">সাধারণ</string>
<string name="idepref_editor_category_java">জাভা</string>
<string name="title_files_unsaved">অসংরক্ষিত ফাইল</string>
<string name="msg_files_unsaved">কিছু ফাইল সংরক্ষিত নেই৷ আপনি বন্ধ করার আগে তাদের সংরক্ষণ করতে চান? অসংরক্ষিত ফাইলগুলি হল: \n%s</string>
+1 -1
View File
@@ -263,7 +263,7 @@
<string name="idepref_editor_autoSave_title">Dateien vor dem schließen speichern</string>
<string name="idepref_java_matchLower_summary">Wenn diese Option aktiviert ist, werden durch die Eingabe von Klein- oder Großbuchstaben Klassennamen sowie Bereichsmitglieder vorgeschlagen.</string>
<string name="msg_files_unsaved">Einige Dateien wurden noch nicht gespeichert. Möchtest du diese nun speichern? Nicht gespeicherte Dateien: %s</string>
<string name="idepref_editor_category_common">Common</string>
<string name="title_common">Common</string>
<string name="action_expand_selection">Auswahl erweitern</string>
<string name="idepref_java_matchLower_title">Vervollständigungen in Kleinbuchstaben nutzen</string>
<string name="msg_compiler_module_install">Kompilierer Modul wird installiert, bitte warten&#8230;</string>
+1 -1
View File
@@ -267,7 +267,7 @@
<string name="msg_compiler_module_installed">Modules du compileur installés avec succès !</string>
<string name="action_expand_selection">Sélection expansion</string>
<string name="idepref_java_matchLower_title">Faire correspondre les complétions en minuscules</string>
<string name="idepref_editor_category_common">Common</string>
<string name="title_common">Common</string>
<string name="idepref_editor_category_java">Java</string>
<string name="title_files_unsaved">Fichiers non sauvegardés</string>
<string name="msg_files_unsaved">Certains fichiers n\'ont pas été sauvegardés, voulez vous les sauvegarder avant de les fermer ? Fichiers non sauvegardés: \n%s</string>
+1 -1
View File
@@ -277,7 +277,7 @@
<string name="msg_compiler_module_installed">कंपाइलर मॉड्यूल सफलतापूर्वक स्थापित किया गया!</string>
<string name="action_expand_selection">चयन का विस्तार करें</string>
<string name="idepref_java_matchLower_title">कम्पलेशन्स लोअर केस में मिलाये</string>
<string name="idepref_editor_category_common">सामान्य</string>
<string name="title_common">सामान्य</string>
<string name="idepref_editor_category_java">जावा</string>
<string name="title_files_unsaved">फ़ाइल्स सेव नहीं की गयी है</string>
<string name="msg_files_unsaved">कुछ फ़ाइलें सेव नहीं की गई हैं। क्या आप बंद करने से पहले उन्हें सेव करना चाहेंगे? सेव न की गयी फ़ाइल्स : %s</string>
+1 -1
View File
@@ -265,7 +265,7 @@
<string name="msg_compiler_module_installed">Modul compiler sukses terpasang!</string>
<string name="action_expand_selection">Perluas seleksi</string>
<string name="idepref_java_matchLower_title">Samakan penyelesaian dalam huruf kecil</string>
<string name="idepref_editor_category_common">Umum</string>
<string name="title_common">Umum</string>
<string name="idepref_editor_category_java">Java</string>
<string name="title_files_unsaved">File tidak tersimpan</string>
<string name="msg_files_unsaved">Beberapa file belum disimpan. Apakah anda ingin menyimpan sebelum menutup file tersebut? File yang belum tersimpan: \n%s</string>
@@ -281,7 +281,7 @@
<string name="msg_compiler_module_installed">Módulo do compilador instalado com sucesso!</string>
<string name="action_expand_selection">Expandir seleção</string>
<string name="idepref_java_matchLower_title">Combinar o autocomplete em letras minúsculas</string>
<string name="idepref_editor_category_common">Comum</string>
<string name="title_common">Comum</string>
<string name="idepref_editor_category_java">Java</string>
<string name="title_files_unsaved">Arquivos não salvos</string>
<string name="msg_files_unsaved">Alguns arquivos não são salvos. Gostaria de salvá-los antes de fechar? Os arquivos não salvos são: \n%s</string>
+1 -1
View File
@@ -297,7 +297,7 @@
<string name="msg_compiler_module_installed">Модуль компилятора успешно установлен!</string>
<string name="action_expand_selection">Расширить выделение</string>
<string name="idepref_java_matchLower_title">Искать совпадения в строчном регистре</string>
<string name="idepref_editor_category_common">Общее</string>
<string name="title_common">Общее</string>
<string name="idepref_editor_category_java">Java</string>
<string name="title_files_unsaved">Несохраненные файлы</string>
<string name="msg_files_unsaved">Некоторые файлы не сохранены. Хотите сохранить их перед закрытием? Список несохраненных файлов: \n%s</string>
+1 -1
View File
@@ -281,7 +281,7 @@
<string name="msg_compiler_module_installed">编译器模块已成功安装!</string>
<string name="action_expand_selection">扩选</string>
<string name="idepref_java_matchLower_title">代码补全匹配小写字母</string>
<string name="idepref_editor_category_common">通用</string>
<string name="title_common">通用</string>
<string name="idepref_editor_category_java">Java</string>
<string name="title_files_unsaved">未保存文件</string>
<string name="msg_files_unsaved">部分文件并未保存,是否在关闭项目之前保存?未保存的文件:\n%s</string>
+1 -1
View File
@@ -26,8 +26,8 @@
<color name="diagnostic_warning">@color/log_warning</color>
<color name="content_background">#212121</color>
<color name="bg_widget_selected">#212121</color>
<color name="green_500">#4caf50</color>
<color name="color_toast_background">#90424242</color>
<color name="color_picker_default_color">#f44336</color>
</resources>
+10 -1
View File
@@ -281,7 +281,8 @@
<string name="msg_compiler_module_installed">Compiler module installed successfully!</string>
<string name="action_expand_selection">Expand selection</string>
<string name="idepref_java_matchLower_title">Match completions in lower case</string>
<string name="idepref_editor_category_common">Common</string>
<string name="title_common">Common</string>
<string name="idepref_editor_category_common" translatable="false">@string/title_common</string>
<string name="idepref_editor_category_java">Java</string>
<string name="title_files_unsaved">Unsaved files</string>
<string name="msg_files_unsaved">Some files are not saved. Would you like to save them before closing? Unsaved files are: \n%s</string>
@@ -466,4 +467,12 @@
<string name="replace">Replace</string>
<string name="replaceAll">Replace all</string>
<string name="title_run_tasks">Run tasks</string>
<string name="hint_search_tasks">Search tasks…</string>
<string name="title_selected_tasks">Selected tasks</string>
<string name="msg_err_select_tasks">Please select tasks to run</string>
<string name="title_confirmation">Confirmation</string>
<string name="msg_tasks_to_run">The following tasks will be run, in order. Click the \'Run\' button again to confirm.\n\n%1$s</string>
<string name="msg_loading_tasks">Loading tasks...</string>
<string name="title_all_tasks">All tasks</string>
</resources>
@@ -23,7 +23,7 @@ import java.util.WeakHashMap
/**
* @author Akash Yadav
*/
class ProgressManager {
class ProgressManager private constructor(){
private val threads = WeakHashMap<Thread, ICancelChecker>()
Binary file not shown.