Skip to content

Commit

Permalink
Add a menu action to insert images from filesystem (#500)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielVenturini committed Apr 2, 2020
1 parent 27a2745 commit d2035d0
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 25 deletions.
53 changes: 30 additions & 23 deletions ReText/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,48 +378,55 @@ def findNextImageName(self, filenames):
highestNumber = max(number, highestNumber)
return 'image%04d.png' % (highestNumber + 1)

def getImageFilenameAndLink(self):
def getImageFilename(self):
if self.tab.fileName:
saveDir = os.path.dirname(self.tab.fileName)
else:
saveDir = os.getcwd()

imageFileName = self.findNextImageName(os.listdir(saveDir))

chosenFileName = QFileDialog.getSaveFileName(self,
return QFileDialog.getSaveFileName(self,
self.tr('Save image'),
os.path.join(saveDir, imageFileName),
self.tr('Images (*.png *.jpg)'))[0]

if chosenFileName:
# Use relative links for named documents
if self.tab.fileName:
try:
link = os.path.relpath(chosenFileName, saveDir)
except ValueError: # different roots
link = chosenFileName
else:
link = chosenFileName
else:
link = None

return chosenFileName, link
def makeFileNameRelative(self, fileName):
"""Tries to make the given fileName relative. If the document is
not saved, or the fileName is on a different root, returns the
original fileName.
"""
if self.tab.fileName:
currentDir = os.path.dirname(self.tab.fileName)
try:
return os.path.relpath(fileName, currentDir)
except ValueError: # different roots
return fileName
return fileName

def getImageMarkup(self, fileName):
"""Returns markup for image in the current markup language.
This method is also accessed in ReTextWindow.insertImage.
"""
link = self.makeFileNameRelative(fileName)
markupClass = self.tab.getActiveMarkupClass()
if markupClass == MarkdownMarkup:
return '![%s](%s)' % (QFileInfo(link).baseName(), link)
elif markupClass == ReStructuredTextMarkup:
return '.. image:: %s' % link
elif markupClass == TextileMarkup:
return '!%s!' % link

def pasteImage(self):
mimeData = QApplication.instance().clipboard().mimeData()
fileName, link = self.getImageFilenameAndLink()
fileName = self.getImageFilename()
if not fileName or not mimeData.hasImage():
return
image = QImage(mimeData.imageData())
image.save(fileName)

markupClass = self.tab.getActiveMarkupClass()
if markupClass == MarkdownMarkup:
imageText = '![%s](%s)' % (QFileInfo(link).baseName(), link)
elif markupClass == ReStructuredTextMarkup:
imageText = '.. image:: %s' % link
elif markupClass == TextileMarkup:
imageText = '!%s!' % link
imageText = self.getImageMarkup(fileName)

self.textCursor().insertText(imageText)

Expand Down
20 changes: 20 additions & 0 deletions ReText/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ def __init__(self, parent=None):
self.actionTableMode = self.act(self.tr('Table editing mode'),
shct=Qt.CTRL+Qt.Key_T,
trigbool=lambda x: self.currentTab.editBox.enableTableMode(x))
self.actionInsertImages = self.act(self.tr('Insert images by file path'),
trig=lambda: self.insertImages())
if ReTextFakeVimHandler:
self.actionFakeVimMode = self.act(self.tr('FakeVim mode'),
shct=Qt.CTRL+Qt.ALT+Qt.Key_V, trigbool=self.enableFakeVimMode)
Expand Down Expand Up @@ -326,6 +328,7 @@ def __init__(self, parent=None):
menuEdit.addAction(self.actionPreview)
menuEdit.addAction(self.actionInsertTable)
menuEdit.addAction(self.actionTableMode)
menuEdit.addAction(self.actionInsertImages)
if ReTextFakeVimHandler:
menuEdit.addAction(self.actionFakeVimMode)
menuEdit.addSeparator()
Expand Down Expand Up @@ -1239,6 +1242,23 @@ def viewHtml(self):
htmlDlg.raise_()
htmlDlg.activateWindow()

def insertImages(self):
supportedExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp']
fileFilter = ' (%s);;' % ' '.join('*' + ext for ext in supportedExtensions)
fileNames, _selectedFilter = QFileDialog.getOpenFileNames(self,
self.tr("Select one or several images to open"), QDir.currentPath(),
self.tr("Supported files") + fileFilter + self.tr("All files (*)"))

cursor = self.currentTab.editBox.textCursor()

imagesMarkup = '\n'.join(
self.currentTab.editBox.getImageMarkup(fileName)
for fileName in fileNames)
cursor.insertText(imagesMarkup)

self.formattingBox.setCurrentIndex(0)
self.currentTab.editBox.setFocus(Qt.OtherFocusReason)

def openHelp(self):
QDesktopServices.openUrl(QUrl('https://github.com/retext-project/retext/wiki'))

Expand Down
6 changes: 4 additions & 2 deletions tests/test_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,24 +111,26 @@ def test_pasteText(self):
self.editor.insertFromMimeData(mimeData)
self.assertTrue('pasted text' in self.editor.toPlainText())

@patch.object(ReTextEdit, 'getImageFilenameAndLink', return_value=('/tmp/myimage.jpg', 'myimage.jpg'))
@patch.object(ReTextEdit, 'getImageFilename', return_value='/tmp/myimage.jpg')
@patch.object(QImage, 'save')
def test_pasteImage_Markdown(self, _mock_image, _mock_editor):
mimeData = QMimeData()
mimeData.setImageData(self._create_image())
app.clipboard().setMimeData(mimeData)
self.dummytab.markupClass = MarkdownMarkup
self.dummytab.fileName = '/tmp/foo.md'

self.editor.pasteImage()
self.assertTrue('![myimage](myimage.jpg)' in self.editor.toPlainText())

@patch.object(ReTextEdit, 'getImageFilenameAndLink', return_value=('/tmp/myimage.jpg', 'myimage.jpg'))
@patch.object(ReTextEdit, 'getImageFilename', return_value='/tmp/myimage.jpg')
@patch.object(QImage, 'save')
def test_pasteImage_RestructuredText(self, _mock_image, _mock_editor):
mimeData = QMimeData()
mimeData.setImageData(self._create_image())
app.clipboard().setMimeData(mimeData)
self.dummytab.markupClass = ReStructuredTextMarkup
self.dummytab.fileName = '/tmp/foo.rst'

self.editor.pasteImage()
self.assertTrue('.. image:: myimage.jpg' in self.editor.toPlainText())
Expand Down

0 comments on commit d2035d0

Please sign in to comment.