Skip to content

Commit

Permalink
Merge branch 'graphic-wizard'
Browse files Browse the repository at this point in the history
  • Loading branch information
PHPirates committed Jan 8, 2021
2 parents f50aa8f + c7e5b1d commit 868ed22
Show file tree
Hide file tree
Showing 33 changed files with 855 additions and 112 deletions.
15 changes: 11 additions & 4 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,21 @@
<!-- MPS doesn't have the EditSmartGroup group, so we register directly in the Edit menu. -->
<add-to-group group-id="EditMenu" anchor="last"/>

<!-- Table Creation Wizard-->
<action class="nl.hannahsten.texifyidea.action.tablewizard.LatexTableWizardAction" id="texify.TableCreationWizzard" text="_Table Creation Wizard"
description="Shows popup to create and insert a table."/>

<!-- Toggle Star -->
<action class="nl.hannahsten.texifyidea.action.LatexToggleStarAction" id="texify.ToggleStar" text="Toggle _Star"
description="Adds/removes a star from a LaTeX command.">
<keyboard-shortcut first-keystroke="alt shift 8" keymap="$default" />
</action>

<separator></separator>

<!-- Table Creation Wizard-->
<action class="nl.hannahsten.texifyidea.action.wizard.table.LatexTableWizardAction" id="texify.TableCreationWizard" text="Insert _Table..."
description="Shows a popup to create and insert a table."/>

<!-- Graphic Wizard-->
<action class="nl.hannahsten.texifyidea.action.wizard.graphic.InsertGraphicWizardAction" id="texify.GraphicInsertWizard" text="Insert _Graphic..."
description="Shows a popup to insert a graphic."/>
</group>

<!-- LaTeX Analyze commands -->
Expand Down Expand Up @@ -467,6 +473,7 @@
<backspaceHandlerDelegate implementation="nl.hannahsten.texifyidea.editor.InlineMathBackspaceHandler" />
<extendWordSelectionHandler implementation="nl.hannahsten.texifyidea.editor.LatexCommandSelectioner"/>
<basicWordSelectionFilter implementation="nl.hannahsten.texifyidea.editor.CommandSelectionFilter"/>
<customFileDropHandler implementation="nl.hannahsten.texifyidea.editor.GraphicsDragAndDropHandler"/>

<!-- References and refactoring -->
<lang.findUsagesProvider language="Latex" implementationClass="nl.hannahsten.texifyidea.reference.LatexUsagesProvider"/>
Expand Down
5 changes: 2 additions & 3 deletions src/nl/hannahsten/texifyidea/action/EditorAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import nl.hannahsten.texifyidea.file.LatexFile

import javax.swing.*
import java.util.Arrays
import java.util.*
import javax.swing.Icon

/**
* Action that fetches the required information beforehand.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package nl.hannahsten.texifyidea.action.wizard.graphic

import nl.hannahsten.texifyidea.lang.graphic.CaptionLocation
import nl.hannahsten.texifyidea.lang.graphic.FigureLocation

/**
* @author Hannah Schellekens
*/
data class InsertGraphicData(
val filePath: String,
val relativePath: Boolean,
val options: String,
val center: Boolean,
val placeInFigure: Boolean,
/** `null` when [placeInFigure] is `false`, not `null` otherwise */
val captionLocation: CaptionLocation? = null,
/** `null` when [placeInFigure] is `false`, not `null` otherwise */
val caption: String? = null,
/** `null` when [placeInFigure] is `false`, not `null` otherwise */
val shortCaption: String? = null,
/** `null` when [placeInFigure] is `false`, not `null` otherwise */
val label: String? = null,
/** `null` when [placeInFigure] is `false`, not `null` otherwise */
val positions: List<FigureLocation>? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package nl.hannahsten.texifyidea.action.wizard.graphic

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import nl.hannahsten.texifyidea.lang.LatexPackage
import nl.hannahsten.texifyidea.lang.graphic.CaptionLocation
import nl.hannahsten.texifyidea.util.*
import nl.hannahsten.texifyidea.util.files.*
import java.io.File
import java.util.*

/**
* Action that shows a dialog with a graphic insertion wizard, and inserts the graphic as latex at the location of the
* cursor.
*
* @author Hannah Schellekens
*/
class InsertGraphicWizardAction(val initialFile: File? = null) : AnAction() {

/**
* Opens and handles the graphic insertion wizard.
*/
fun executeAction(file: VirtualFile, project: Project) {
val editor = project.currentTextEditor() ?: return
val document = editor.editor.document

// Get the indentation from the current line.
val indent = document.lineIndentationByOffset(editor.editor.caretOffset())

// Create the dialog.
val dialogWrapper = InsertGraphicWizardDialogWrapper(initialFilePath = initialFile?.absolutePath ?: "")

// If the user pressed OK, do stuff.
if (!dialogWrapper.showAndGet()) return

// Handle result.
val graphicData = dialogWrapper.extractData()
file.psiFile(project)?.let { graphicData.importPackages(it) }
editor.editor.insertGraphic(project, graphicData, indent)
}

override fun actionPerformed(e: AnActionEvent) {
val file = e.getData(PlatformDataKeys.VIRTUAL_FILE) ?: return
val project = e.getData(PlatformDataKeys.PROJECT) ?: return
executeAction(file, project)
}

private fun Editor.insertGraphic(project: Project, data: InsertGraphicData, indent: String, tab: String = " ") {
// Only the graphics (non-centered).
val toInsert = if (data.center.not() && data.placeInFigure.not()) {
data.includeCommand(project)
}
// Centered graphics, but not in a figure.
else if (data.center && data.placeInFigure.not()) {
buildString {
append("\\begin{center}\n")
append(indent).append(tab).append(data.includeCommand(project)).newline()
append(indent).append("\\end{center}")
}
}
// Insert figure.
else data.figure(project, indent, tab)

insertAtCaretAndMove(toInsert)
}

private fun InsertGraphicData.figure(project: Project, indent: String, tab: String) = buildString {
append("\\begin{figure}")
if (positions?.isNotEmpty() == true) {
append(positionOptions())
}
newline()

if (center) {
append(indent).append(tab).append("\\centering").newline()
}

if (captionLocation == CaptionLocation.ABOVE_GRAPHIC) {
addCaptionAndLabel(this@figure, indent, tab)
}

append(indent).append(tab).append(includeCommand(project)).newline()

if (captionLocation == CaptionLocation.BELOW_GRAPHIC) {
addCaptionAndLabel(this@figure, indent, tab)
}

append(indent).append("\\end{figure}")
}

private fun StringBuilder.addCaptionAndLabel(data: InsertGraphicData, indent: String, tab: String) {
append(indent).append(tab).append(data.captionCommand()).newline()
append(indent).append(tab).append("\\label{").append(data.label ?: "").append("}").newline()
}

private fun InsertGraphicData.includeCommand(project: Project) = buildString {
append("\\includegraphics")
if (options.isNotBlank()) {
append("[").append(options).append("]")
}
append("{").append(convertFilePath(project, filePath)).append("}")
}

private fun InsertGraphicData.convertFilePath(project: Project, absoluteFilePath: String): String {
val rootManager = ProjectRootManager.getInstance(project)

val filePath = if (relativePath) {
rootManager.relativizePath(absoluteFilePath) ?: absoluteFilePath
}
else absoluteFilePath

return filePath.removeFileExtension()
}

private fun InsertGraphicData.captionCommand() = buildString {
append("\\caption")
if (shortCaption?.isNotBlank() == true) {
append("[").append(shortCaption).append("]")
}
append("{").append(caption ?: "").append("}")
}

private fun InsertGraphicData.importPackages(file: PsiFile) {
WriteCommandAction.runWriteCommandAction(file.project) {
file.insertUsepackage(LatexPackage.GRAPHICX)
positions?.forEach { location ->
location.requiredPackage?.let {
file.insertUsepackage(it)
}
}
}
}

private fun InsertGraphicData.positionOptions() = buildString {
append("[")
append(positions?.joinToString("") { it.symbol })
append("]")
}
}
Loading

0 comments on commit 868ed22

Please sign in to comment.