Skip to content

Commit

Permalink
Merge pull request #3770 from Hannah-Sten/paste-image
Browse files Browse the repository at this point in the history
Fix relative path conversion in graphics insertion wizard
  • Loading branch information
PHPirates authored Nov 27, 2024
2 parents 6512df5 + 91777ca commit f62840f
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 21 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
* Add setting to disable auto-import of bibtex entries from remote libraries

### Fixed
* Fix relative path conversion in graphics insertion wizard by resolving relative to the root file
* Fix exception #3763
* Fix 'missing import' false positive in subfiles
* Don't override the file icon for .txt files, by @Steve-Li-1998
* Fix exceptions #3754 and #3326
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.application.runInEdt
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.LocalFileSystem
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.isLatexFile
import nl.hannahsten.texifyidea.util.files.psiFile
import nl.hannahsten.texifyidea.util.files.relativizePath
import nl.hannahsten.texifyidea.util.files.removeFileExtension
import nl.hannahsten.texifyidea.util.files.*
import java.io.File

/**
Expand All @@ -32,8 +31,10 @@ class InsertGraphicWizardAction(private val initialFile: File? = null) : AnActio
*/
fun executeAction(file: VirtualFile, project: Project) {
val editor = project.currentTextEditor() ?: return
val text = showDialogAndGetText(editor, file, project) ?: return
editor.editor.insertAtCaretAndMove(text)
runInEdt {
val text = showDialogAndGetText(editor, file, project) ?: return@runInEdt
editor.editor.insertAtCaretAndMove(text)
}
}

/**
Expand All @@ -57,8 +58,10 @@ class InsertGraphicWizardAction(private val initialFile: File? = null) : AnActio

// Handle result.
val graphicData = dialogWrapper.extractData()
file.psiFile(project)?.let { graphicData.importPackages(it) }
return buildGraphicString(project, graphicData, indent)
val psiFile = file.psiFile(project)
psiFile?.let { graphicData.importPackages(it) }
val rootFile = psiFile?.findRootFile()
return buildGraphicString(project, graphicData, indent, rootFile)
}

override fun actionPerformed(e: AnActionEvent) {
Expand All @@ -81,27 +84,28 @@ class InsertGraphicWizardAction(private val initialFile: File? = null) : AnActio
project: Project,
data: InsertGraphicData,
indent: String,
tab: String = " "
rootFile: PsiFile?,
tab: String = " ",
): String {
// Only the graphics (non-centered).
val toInsert = if (data.center.not() && data.placeInFigure.not()) {
data.includeCommand(project)
data.includeCommand(project, rootFile)
}
// 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(tab).append(data.includeCommand(project, rootFile)).newline()
append(indent).append("\\end{center}")
}
}
// Insert figure.
else data.figure(project, indent, tab)
else data.figure(project, indent, tab, rootFile)

return toInsert
}

private fun InsertGraphicData.figure(project: Project, indent: String, tab: String) = buildString {
private fun InsertGraphicData.figure(project: Project, indent: String, tab: String, rootFile: PsiFile?) = buildString {
append("\\begin{figure}")
if (positions?.isNotEmpty() == true) {
append(positionOptions())
Expand All @@ -116,7 +120,7 @@ class InsertGraphicWizardAction(private val initialFile: File? = null) : AnActio
addCaptionAndLabel(this@figure, indent, tab)
}

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

if (captionLocation == CaptionLocation.BELOW_GRAPHIC) {
addCaptionAndLabel(this@figure, indent, tab)
Expand All @@ -130,19 +134,28 @@ class InsertGraphicWizardAction(private val initialFile: File? = null) : AnActio
append(indent).append(tab).append("\\label{").append(data.label ?: "").append("}").newline()
}

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

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

val filePath = if (relativePath) {
rootManager.relativizePath(absoluteFilePath) ?: absoluteFilePath
// We need to match the path given by the user (from e.g. the file chooser dialog) to the root file
val imageFile = LocalFileSystem.getInstance().findFileByPath(absoluteFilePath)

val default = rootManager.relativizePath(absoluteFilePath) ?: absoluteFilePath
if (rootFile != null && imageFile != null) {
FileUtil.pathRelativeTo(rootFile.virtualFile.parent.path + "/", imageFile.path) ?: default
}
else {
default
}
}
else absoluteFilePath

Expand Down
3 changes: 2 additions & 1 deletion src/nl/hannahsten/texifyidea/util/Documents.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nl.hannahsten.texifyidea.util

import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.CaretModel
import com.intellij.openapi.editor.Document
Expand Down Expand Up @@ -106,4 +107,4 @@ fun Editor.insertAtCaretAndMove(string: String) {
/**
* @see [CaretModel.getOffset]
*/
fun Editor.caretOffset() = caretModel.offset
fun Editor.caretOffset() = runReadAction { caretModel.offset }
3 changes: 2 additions & 1 deletion src/nl/hannahsten/texifyidea/util/files/Files.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nl.hannahsten.texifyidea.util.files

import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.module.Module
Expand Down Expand Up @@ -103,7 +104,7 @@ fun Module.createExcludedDir(path: String) {
* The project scope to retrieve the psi file for.
* @return The PSI file matching the document, or `null` when the PSI file could not be found.
*/
fun Document.psiFile(project: Project): PsiFile? = PsiDocumentManager.getInstance(project).getPsiFile(this)
fun Document.psiFile(project: Project): PsiFile? = runReadAction { PsiDocumentManager.getInstance(project).getPsiFile(this) }

/**
* Creates a new file with a given name and given content.
Expand Down
6 changes: 5 additions & 1 deletion src/nl/hannahsten/texifyidea/util/files/RootFile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ fun PsiFile.findRootFilesWithoutCache(fileset: Set<PsiFile>): Set<PsiFile> {
* Note: LaTeX Files can have more than one * root file, so using [findRootFiles] and explicitly handling the cases of
* multiple root files is preferred over using [findRootFile].
*/
fun PsiFile.findRootFile(): PsiFile = findRootFiles().firstOrNull() ?: this
fun PsiFile.findRootFile(): PsiFile {
val allRoots = findRootFiles()
// If there are multiple root files, prefer the current one
return if (this in allRoots) this else allRoots.firstOrNull() ?: this
}

/**
* Gets the set of files that are the root files of `this` file.
Expand Down

0 comments on commit f62840f

Please sign in to comment.