diff --git a/src/main/java/com/ardublock/translator/block/code/CommentProgramBlock.java b/src/main/java/com/ardublock/translator/block/code/CommentProgramBlock.java index 90e415c177e4f997504f41f0e4c3c8ea06e55a33..fc6a703f8ced6fd4909178ce017b2e3a8614509d 100644 --- a/src/main/java/com/ardublock/translator/block/code/CommentProgramBlock.java +++ b/src/main/java/com/ardublock/translator/block/code/CommentProgramBlock.java @@ -25,7 +25,7 @@ public class CommentProgramBlock extends TranslatorBlock String programVersion =""; String ret = "/**\n"; - + TranslatorBlock tb_programName = this.getRequiredTranslatorBlockAtSocket(0); programName = tb_programName.toCode().replaceAll("\"", ""); ret += "* file:\t" + programName +"\n"; @@ -59,6 +59,7 @@ public class CommentProgramBlock extends TranslatorBlock ret += "* version:\t" + programVersion +"\n*/\n"; translator.addDefinitionCommand(ret); + return ""; } diff --git a/src/main/java/com/ardublock/ui/OpenblocksFrame.java b/src/main/java/com/ardublock/ui/OpenblocksFrame.java index 71ef11579359eb20b95fd83f56046bdc5bc4fe7a..15947d7404a1c00a9a276bc449dcfba8d24bba1a 100644 --- a/src/main/java/com/ardublock/ui/OpenblocksFrame.java +++ b/src/main/java/com/ardublock/ui/OpenblocksFrame.java @@ -1,23 +1,24 @@ package com.ardublock.ui; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Cursor; import java.awt.Desktop; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.PrintWriter; import java.io.UnsupportedEncodingException; -import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.util.ResourceBundle; +import javax.imageio.ImageIO; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JComponent; @@ -31,6 +32,8 @@ import javax.swing.ToolTipManager; import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileNameExtensionFilter; +import org.apache.commons.io.FilenameUtils; + import com.ardublock.core.Context; import com.ardublock.ui.listener.ArdublockWorkspaceListener; import com.ardublock.ui.listener.GenerateCodeButtonListener; @@ -220,7 +223,7 @@ public class OpenblocksFrame extends JFrame //***************************************** JPanel bottomPanel = new JPanel(); JButton saveImageButton = new JButton(uiMessageBundle.getString("ardublock.ui.saveImage")); - ActionListener saveImageButtonListener = new SaveImageButtonListener(workspace); + ActionListener saveImageButtonListener = new SaveImageButtonListener(this); saveImageButton.addActionListener(saveImageButtonListener); KeyStroke ctrlpKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK); saveImageButton.registerKeyboardAction(saveImageButtonListener, ctrlpKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); @@ -478,17 +481,17 @@ public class OpenblocksFrame extends JFrame JButton copyButton = new JButton(uiMessageBundle.getString("ardublock.ui.copy")); ActionListener copyButtonListener = new CopyButtonListener(context); copyButton.addActionListener(copyButtonListener); - KeyStroke ctrlcKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK); - copyButton.registerKeyboardAction(copyButtonListener, ctrlcKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); - copyButton.setToolTipText(uiMessageBundle.getString("ardublock.ui.copy.tooltip")); + //KeyStroke ctrlcKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK); + //copyButton.registerKeyboardAction(copyButtonListener, ctrlcKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); + //copyButton.setToolTipText(uiMessageBundle.getString("ardublock.ui.copy.tooltip")); JButton pasteButton = new JButton(uiMessageBundle.getString("ardublock.ui.paste")); ActionListener pasteButtonListener = new PasteButtonListener(this, context, uiMessageBundle, workspaceModeState); pasteButton.addActionListener(pasteButtonListener); - KeyStroke ctrlvKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK); - pasteButton.registerKeyboardAction(pasteButtonListener, ctrlvKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); - pasteButton.setToolTipText(uiMessageBundle.getString("ardublock.ui.paste.tooltip")); + //KeyStroke ctrlvKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK); + //pasteButton.registerKeyboardAction(pasteButtonListener, ctrlvKeyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW); + //pasteButton.setToolTipText(uiMessageBundle.getString("ardublock.ui.paste.tooltip")); //***************************************** //WEBSITE BUTTON @@ -581,7 +584,13 @@ public class OpenblocksFrame extends JFrame File savedFile = fileChooser.getSelectedFile(); if (!savedFile.exists()) { - JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.file_not_found"), uiMessageBundle.getString("message.title.error"), JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE, null, null, JOptionPane.OK_OPTION); + //JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.file_not_found"), uiMessageBundle.getString("message.title.error"), JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, JOptionPane.OK_OPTION); + int optionValue = JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.file_not_found_new_file"), uiMessageBundle.getString("message.title.error"), JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null, null, JOptionPane.OK_OPTION); + if(optionValue == JOptionPane.YES_OPTION) { + context.resetWorkspace(); + context.setWorkspaceChanged(false); + chooseFileAndSave(getArduBlockString()); + } return ; } @@ -593,7 +602,7 @@ public class OpenblocksFrame extends JFrame } catch (IOException e) { - JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.file_not_found"), uiMessageBundle.getString("message.title.error"), JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE, null, null, JOptionPane.OK_OPTION); + JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.file_not_found"), uiMessageBundle.getString("message.title.error"), JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE, null, null, JOptionPane.OK_OPTION); //e.printStackTrace(); } finally @@ -673,12 +682,13 @@ public class OpenblocksFrame extends JFrame private void chooseFileAndSave(String ardublockString) { File saveFile = letUserChooseSaveFile(); - saveFile = checkFileSuffix(saveFile); if (saveFile == null) { return ; } + saveFile = checkFileSuffix(saveFile); + if (saveFile.exists() && !askUserOverwriteExistedFile()) { return ; @@ -725,12 +735,19 @@ public class OpenblocksFrame extends JFrame return (optionValue == JOptionPane.YES_OPTION); } + private boolean askUserOverwriteDefaultFile() { int optionValue = JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.content.overwriteDefault"), uiMessageBundle.getString("message.title.question"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, JOptionPane.YES_OPTION); return (optionValue == JOptionPane.YES_OPTION); } + private boolean askUserOverwriteExistedImage() + { + int optionValue = JOptionPane.showOptionDialog(this, uiMessageBundle.getString("message.content.overwriteImage"), uiMessageBundle.getString("message.title.question"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, JOptionPane.YES_OPTION); + return (optionValue == JOptionPane.YES_OPTION); + } + private void saveArduBlockToFile(String ardublockString, File saveFile) throws IOException { context.saveArduBlockFile(saveFile, ardublockString); @@ -764,7 +781,6 @@ public class OpenblocksFrame extends JFrame try { if(workspaceModeState){ context.getWorkspaceController().loadProject(getArduBlockString(), null , "custom"); - } } catch (Exception e1) { //e1.printStackTrace(); @@ -786,6 +802,82 @@ public class OpenblocksFrame extends JFrame return new File(filePath + ".abp"); } } + + + public void saveProgramAsImage() { + Workspace workspace = context.getWorkspace(); + Dimension size = workspace.getCanvasSize(); + Color transparent = new Color(0, 0, 0, 0); + + //System.out.println("size: " + size); + BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB); //letsgoING + + Graphics2D g = (Graphics2D)bi.createGraphics(); + g.setBackground(transparent); + //double theScaleFactor = (300d/72d); + //g.scale(theScaleFactor,theScaleFactor); + + workspace.getBlockCanvas().getPageAt(0).getJComponent().paint(g); + + //CHANGE BACKGROUND COLOR FOR PRINT + //***************************************** + int maxPixelX = 0; + int maxPixelY = 0; + + for( int x = 0; x < bi.getWidth(); x++ ) { // loop through the pixels + for( int y = 0; y < bi.getHeight(); y++ ) { + Color pixelColor = new Color(bi.getRGB(x, y)); + if( pixelColor.getRed() == 128 && pixelColor.getGreen() == 128 && pixelColor.getBlue() == 128 ) { + bi.setRGB(x, y,transparent.getRGB()); + } + else{ //GET SIZE OF BLOCKS ON IMAGE + maxPixelX = Math.max(x,maxPixelX); + maxPixelY = Math.max(y,maxPixelY); + } + } + } + + //System.out.println("Max X: " + maxPixelX +" Max Y: " + maxPixelY +"Image W: " + bi.getWidth() + "Image H: " +bi.getHeight()); + + BufferedImage ci = bi.getSubimage(0, 0, Math.min(maxPixelX+20, bi.getWidth()), Math.min(maxPixelY+20, bi.getHeight())); + //***************************************** + + try{ + final JFileChooser fc = new JFileChooser(); + String fileName = "ardublock.png"; + + FileNameExtensionFilter filterPNG = new FileNameExtensionFilter("png", "png"); + fc.setFileFilter(filterPNG); + + System.out.println("Name"+context.getSaveFileName()); + if(context.getSaveFileName().contains(".")) { + fileName = context.getSaveFileName().substring(0, context.getSaveFileName().lastIndexOf('.')); + } + /*else { + fileName = context.getSaveFileName(); + }*/ + + fc.setSelectedFile(new File(fileName));//get ABprogramFileName + int returnVal = fc.showSaveDialog(workspace.getBlockCanvas().getJComponent()); + + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + if(file.exists() && !askUserOverwriteExistedImage()) { + return; + } + else { + if(fc.getFileFilter().equals(filterPNG)) { + file = new File(file.getParentFile(), FilenameUtils.getBaseName(file.getName())+".png"); + ImageIO.write(ci,"png",file); + } + } + } + } catch (Exception e1) { + + } finally { + g.dispose(); + } + } @SuppressWarnings("unused") private void resetModeState(){ //letsgoING diff --git a/src/main/java/com/ardublock/ui/listener/GenerateCodeButtonListener.java b/src/main/java/com/ardublock/ui/listener/GenerateCodeButtonListener.java index 8857ae29de24b186bd3b60a5ad4a3517a4450694..51820b8af25ca43902653b5a6e38836665fe4f55 100644 --- a/src/main/java/com/ardublock/ui/listener/GenerateCodeButtonListener.java +++ b/src/main/java/com/ardublock/ui/listener/GenerateCodeButtonListener.java @@ -226,9 +226,11 @@ public class GenerateCodeButtonListener implements ActionListener } catch (SocketNullException e1) { - e1.printStackTrace(); + //e1.printStackTrace(); success = false; Long blockId = e1.getBlockId(); + String errorMessage = ""; + Iterable<RenderableBlock> blocks = workspace.getRenderableBlocks(); for (RenderableBlock renderableBlock2 : blocks) { @@ -236,14 +238,16 @@ public class GenerateCodeButtonListener implements ActionListener if (block2.getBlockID().equals(blockId)) { context.highlightBlock(renderableBlock2); + errorMessage = "\n\n"+uiMessageBundle.getString("ardublock.translator.exception.socketNull.consolePrint")+" "+block2.getBlockLabel(); break; } } - JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.socketNull"), "Error", JOptionPane.ERROR_MESSAGE); + + JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.socketNull") + errorMessage, "Error", JOptionPane.ERROR_MESSAGE); } catch (BlockException e2) { - e2.printStackTrace(); + //e2.printStackTrace(); success = false; Long blockId = e2.getBlockId(); Iterable<RenderableBlock> blocks = workspace.getRenderableBlocks(); @@ -260,9 +264,10 @@ public class GenerateCodeButtonListener implements ActionListener } catch (SubroutineNotDeclaredException e3) { - e3.printStackTrace(); + //e3.printStackTrace(); success = false; Long blockId = e3.getBlockId(); + String errorMessage = ""; Iterable<RenderableBlock> blocks = workspace.getRenderableBlocks(); for (RenderableBlock renderableBlock3 : blocks) { @@ -270,10 +275,11 @@ public class GenerateCodeButtonListener implements ActionListener if (block2.getBlockID().equals(blockId)) { context.highlightBlock(renderableBlock3); + errorMessage = "\n\n"+uiMessageBundle.getString("ardublock.translator.exception.subroutineNotDeclared.consolePrint")+" "+block2.getBlockLabel(); break; } } - JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.subroutineNotDeclared"), "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.subroutineNotDeclared") + errorMessage, "Error", JOptionPane.ERROR_MESSAGE); } diff --git a/src/main/java/com/ardublock/ui/listener/SaveImageButtonListener.java b/src/main/java/com/ardublock/ui/listener/SaveImageButtonListener.java index 2a4d08f6af3e346fb43be54b14b6ae04f5871600..4e4e439563525e9251e30c398641eeff5072fcba 100644 --- a/src/main/java/com/ardublock/ui/listener/SaveImageButtonListener.java +++ b/src/main/java/com/ardublock/ui/listener/SaveImageButtonListener.java @@ -1,77 +1,23 @@ package com.ardublock.ui.listener; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.image.BufferedImage; -import java.io.File; - -import javax.imageio.ImageIO; -import javax.swing.JFileChooser; +import com.ardublock.core.Context; +import com.ardublock.ui.OpenblocksFrame; import edu.mit.blocks.workspace.Workspace; public class SaveImageButtonListener implements ActionListener { - private Workspace workspace; + private OpenblocksFrame parentFrame; - public SaveImageButtonListener(Workspace workspace) + public SaveImageButtonListener(OpenblocksFrame frame) { - this.workspace = workspace; + parentFrame = frame; } public void actionPerformed(ActionEvent e) { - Dimension size = workspace.getCanvasSize(); - Color transparent = new Color(0, 0, 0, 0); - - //System.out.println("size: " + size); - BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB); //letsgoING - - Graphics2D g = (Graphics2D)bi.createGraphics(); - g.setBackground(transparent); - //double theScaleFactor = (300d/72d); - //g.scale(theScaleFactor,theScaleFactor); - - workspace.getBlockCanvas().getPageAt(0).getJComponent().paint(g); - - //CHANGE BACKGROUND COLOR FOR PRINT - //***************************************** - int maxPixelX = 0; - int maxPixelY = 0; - - for( int x = 0; x < bi.getWidth(); x++ ) { // loop through the pixels - for( int y = 0; y < bi.getHeight(); y++ ) { - Color pixelColor = new Color(bi.getRGB(x, y)); - if( pixelColor.getRed() == 128 && pixelColor.getGreen() == 128 && pixelColor.getBlue() == 128 ) { - bi.setRGB(x, y,transparent.getRGB()); - } - else{ //GET SIZE OF BLOCKS ON IMAGE - maxPixelX = Math.max(x,maxPixelX); - maxPixelY = Math.max(y,maxPixelY); - } - } - } - - //System.out.println("Max X: " + maxPixelX +" Max Y: " + maxPixelY +"Image W: " + bi.getWidth() + "Image H: " +bi.getHeight()); - - BufferedImage ci = bi.getSubimage(0, 0, Math.min(maxPixelX+20, bi.getWidth()), Math.min(maxPixelY+20, bi.getHeight())); - //***************************************** - - try{ - final JFileChooser fc = new JFileChooser(); - fc.setSelectedFile(new File("ardublock.png")); - int returnVal = fc.showSaveDialog(workspace.getBlockCanvas().getJComponent()); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); - ImageIO.write(ci,"png",file); ////// - } - } catch (Exception e1) { - - } finally { - g.dispose(); - } + parentFrame.saveProgramAsImage(); } } diff --git a/src/main/java/com/ardublock/ui/listener/SimulateCodeButtonListener.java b/src/main/java/com/ardublock/ui/listener/SimulateCodeButtonListener.java index 2a9e01063d13b461ed7c0039fb80b19fa1f21e20..8310e602da96de99d94ec4873a108ed551402b4d 100644 --- a/src/main/java/com/ardublock/ui/listener/SimulateCodeButtonListener.java +++ b/src/main/java/com/ardublock/ui/listener/SimulateCodeButtonListener.java @@ -241,9 +241,11 @@ public class SimulateCodeButtonListener implements ActionListener } catch (SocketNullException e1) { - e1.printStackTrace(); + //e1.printStackTrace(); success = false; Long blockId = e1.getBlockId(); + String errorMessage = ""; + Iterable<RenderableBlock> blocks = workspace.getRenderableBlocks(); for (RenderableBlock renderableBlock2 : blocks) { @@ -251,14 +253,15 @@ public class SimulateCodeButtonListener implements ActionListener if (block2.getBlockID().equals(blockId)) { context.highlightBlock(renderableBlock2); + errorMessage = "\n\n"+uiMessageBundle.getString("ardublock.translator.exception.socketNull.consolePrint")+" "+block2.getBlockLabel(); break; } } - JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.socketNull"), "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.socketNull") + errorMessage, "Error", JOptionPane.ERROR_MESSAGE); } catch (BlockException e2) { - e2.printStackTrace(); + //e2.printStackTrace(); success = false; Long blockId = e2.getBlockId(); Iterable<RenderableBlock> blocks = workspace.getRenderableBlocks(); @@ -275,9 +278,10 @@ public class SimulateCodeButtonListener implements ActionListener } catch (SubroutineNotDeclaredException e3) { - e3.printStackTrace(); + //e3.printStackTrace(); success = false; Long blockId = e3.getBlockId(); + String errorMessage = ""; Iterable<RenderableBlock> blocks = workspace.getRenderableBlocks(); for (RenderableBlock renderableBlock3 : blocks) { @@ -285,10 +289,11 @@ public class SimulateCodeButtonListener implements ActionListener if (block2.getBlockID().equals(blockId)) { context.highlightBlock(renderableBlock3); + errorMessage = "\n\n"+uiMessageBundle.getString("ardublock.translator.exception.subroutineNotDeclared.consolePrint")+" "+block2.getBlockLabel(); break; } } - JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.subroutineNotDeclared"), "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(parentFrame, uiMessageBundle.getString("ardublock.translator.exception.subroutineNotDeclared") + errorMessage, "Error", JOptionPane.ERROR_MESSAGE); } diff --git a/src/main/resources/com/ardublock/block/ardublock.properties b/src/main/resources/com/ardublock/block/ardublock.properties index 38417d1cd89bb96e04641c7b9bf6fc182d755a87..0fede5b20748dfdc88185b9ba80c2120ea0f4de2 100644 --- a/src/main/resources/com/ardublock/block/ardublock.properties +++ b/src/main/resources/com/ardublock/block/ardublock.properties @@ -109,7 +109,9 @@ ardublock.translator.exception.subroutineNameDuplicated=two or more subroutines ardublock.translator.exception.noLoopFound=No loop found! ardublock.translator.exception.multipleLoopFound=multiple loop block found! ardublock.translator.exception.socketNull=A required Value, Variable Name or 'Test' is missing.\nHint:: Look for an empty 'socket' in the highlighted block. +ardublock.translator.exception.socketNull.consolePrint=Name of the block: ardublock.translator.exception.subroutineNotDeclared=subroutine not declared +ardublock.translator.exception.subroutineNotDeclared.consolePrint=Name of the subroutine: #MESSAGE #**************************** @@ -118,7 +120,10 @@ message.title.question=Question message.content.open_unsaved=Ardublock program has changed, do you want to save? message.content.overwrite=Do you want to overwrite existing file? message.content.overwriteDefault=Do you want to overwrite default file? -message.file_not_found=File Not Found or Permission Denied +message.file_not_found=File not found or permission denied +message.file_not_found_new_file=File Not Found or permission denied.\nCreate new file? +message.content.overwriteImage=Do you want to overwrite existing image? + message.question.newfile_on_workspace_changed=The program has changed, do you want to create a new Ardublock file? ################## diff --git a/src/main/resources/com/ardublock/block/ardublock_de.properties b/src/main/resources/com/ardublock/block/ardublock_de.properties index f69a36720c3a4f2e12481eaa473b48647c0f43e8..1cda312ab8f0c62d240064c9eaee1ba811ecfa50 100644 --- a/src/main/resources/com/ardublock/block/ardublock_de.properties +++ b/src/main/resources/com/ardublock/block/ardublock_de.properties @@ -111,7 +111,9 @@ ardublock.translator.exception.subroutineNameDuplicated=Zwei oder mehr Unterprog ardublock.translator.exception.noLoopFound=Keine Hauptschleife gefunden\! ardublock.translator.exception.multipleLoopFound=Mehrere Hauptschleifen gefunden\! ardublock.translator.exception.socketNull=Ein benötigter Wert, Variablenname oder eine Bedingung fehlt!\nTIPP: Suche nach einem leeren Sockel an dem hervorgehobenen Block! +ardublock.translator.exception.socketNull.consolePrint=Der Name des Blocks: ardublock.translator.exception.subroutineNotDeclared=Unterprogramm nicht deklariert! +ardublock.translator.exception.subroutineNotDeclared.consolePrint=Der Name des Unterprogramms: #MESSAGE #**************************** @@ -121,7 +123,9 @@ message.content.open_unsaved=Das Ardublock-Programm hat sich ge message.content.overwrite=Soll das vorhandene Programm überschrieben werden? message.content.overwriteDefault=Soll die Programmvorlage überschrieben werden? message.file_not_found=Datei wurde nicht gefunden oder der Zugriff wurde verweigert. +message.file_not_found_new_file=Datei wurde nicht gefunden oder der Zugriff wurde verweigert.\nSoll eine neue Datei erstellt werden? message.question.newfile_on_workspace_changed=Das Programm hat sich geändert, soll eine neue Ardublock-Datei erstellt werden? +message.content.overwriteImage=Soll das vorhandene Bild überschrieben werden? ################## # BLOCK CONFIG #