/*
* Copyright (c) 2010-2016, Sikuli.org, sikulix.com
* Released under the MIT License.
*
*/
package org.sikuli.ide;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import org.sikuli.script.Location;
import org.sikuli.script.ScreenImage;
import org.sikuli.script.ScreenUnion;
import org.sikuli.basics.Debug;
import org.sikuli.basics.FileManager;
public class PatternWindow extends JFrame {
private static final String me = "PatternWindow: ";
private EditorPatternButton _imgBtn;
private PatternPaneScreenshot _screenshot;
private PatternPaneTargetOffset _tarOffsetPane;
private PatternPaneNaming paneNaming;
private JTabbedPane tabPane;
private JPanel paneTarget, panePreview;
private JLabel[] msgApplied;
private int tabSequence = 0;
private static final int tabMax = 3;
private ScreenImage _simg;
private boolean dirty;
private EditorPane currentPane;
boolean isFileOverwritten = false;
String fileRenameOld;
String fileRenameNew;
Dimension pDim;
static String _I(String key, Object... args) {
return SikuliIDEI18N._I(key, args);
}
public PatternWindow(EditorPatternButton imgBtn, boolean exact,
float similarity, int numMatches) {
init(imgBtn, exact, similarity, numMatches);
}
private void init(EditorPatternButton imgBtn, boolean exact, float similarity, int numMatches) {
setTitle(_I("winPatternSettings"));
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
_imgBtn = imgBtn;
takeScreenshot();
Container c = getContentPane();
c.setLayout(new BorderLayout());
GraphicsConfiguration gc = getGraphicsConfiguration();
int pOff = 50;
Point pLoc = new Point(pOff, pOff);
if (gc == null) {
pDim = new Dimension(900, 700);
} else {
pDim = getGraphicsConfiguration().getBounds().getSize();
pDim.width = (int) ((pDim.width - 2 * pOff) * 0.95);
pDim.height = (int) ((pDim.height - 2 * pOff) * 0.95);
pLoc = getGraphicsConfiguration().getBounds().getLocation();
pLoc.translate(pOff, pOff);
}
setPreferredSize(pDim);
tabPane = new JTabbedPane();
msgApplied = new JLabel[tabMax];
tabSequence = 0;
JLabel aMsg = msgApplied[tabSequence] = new JLabel();
setMessageApplied(tabSequence, false);
paneNaming = new PatternPaneNaming(_imgBtn, aMsg);
tabPane.addTab(_I("tabNaming"), paneNaming);
tabSequence++;
msgApplied[tabSequence] = new JLabel();
setMessageApplied(tabSequence, false);
panePreview = createPreviewPanel();
tabPane.addTab(_I("tabMatchingPreview"), panePreview);
tabSequence++;
msgApplied[tabSequence] = new JLabel();
setMessageApplied(tabSequence, false);
paneTarget = createTargetPanel();
tabPane.addTab(_I("tabTargetOffset"), paneTarget);
c.add(tabPane, BorderLayout.CENTER);
c.add(createButtons(), BorderLayout.SOUTH);
c.doLayout();
pack();
try {
_screenshot.setParameters(_imgBtn.getFilename(),
exact, similarity, numMatches);
} catch (Exception e) {
Debug.error(me + "Problem while setting up pattern pane\n%s", e.getMessage());
}
setDirty(false);
currentPane = SikuliIDE.getInstance().getCurrentCodePane();
setLocation(pLoc);
setVisible(true);
}
void takeScreenshot() {
SikuliIDE ide = SikuliIDE.getInstance();
ide.setVisible(false);
try {
Thread.sleep(500);
} catch (Exception e) {
}
_simg = (new ScreenUnion()).getScreen().capture();
ide.setVisible(true);
}
private JPanel createPreviewPanel() {
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
_screenshot = new PatternPaneScreenshot(_simg, pDim, msgApplied[tabSequence]);
createMarginBox(p, _screenshot);
p.add(Box.createVerticalStrut(5));
p.add(_screenshot.createControls());
// p.add(Box.createVerticalStrut(5));
// p.add(msgApplied[tabSequence]);
p.doLayout();
return p;
}
private JPanel createTargetPanel() {
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
_tarOffsetPane = new PatternPaneTargetOffset(
_simg, _imgBtn.getFilename(), _imgBtn.getTargetOffset(), pDim, msgApplied[tabSequence]);
createMarginBox(p, _tarOffsetPane);
p.add(Box.createVerticalStrut(5));
p.add(_tarOffsetPane.createControls());
p.doLayout();
return p;
}
private JComponent createButtons() {
JPanel pane = new JPanel(new GridBagLayout());
JButton btnOK = new JButton(_I("ok"));
btnOK.addActionListener(new ActionOK(this));
JButton btnApply = new JButton(_I("apply"));
btnApply.addActionListener(new ActionApply(this));
final JButton btnCancel = new JButton(_I("cancel"));
btnCancel.addActionListener(new ActionCancel(this));
GridBagConstraints c = new GridBagConstraints();
c.gridy = 3;
c.gridx = 0;
c.insets = new Insets(5, 0, 10, 0);
c.anchor = GridBagConstraints.LAST_LINE_END;
pane.add(btnOK, c);
c.gridx = 1;
pane.add(btnApply, c);
c.gridx = 2;
pane.add(btnCancel, c);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
btnCancel.doClick();
}
});
KeyStroke escapeKeyStroke =
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
this.getRootPane().
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).
put(escapeKeyStroke, "ESCAPE");
this.getRootPane().getActionMap().put("ESCAPE",
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
btnCancel.doClick();
}
});
return pane;
}
private void createMarginBox(Container c, Component comp) {
c.add(Box.createVerticalStrut(10));
Box lrMargins = Box.createHorizontalBox();
lrMargins.add(Box.createHorizontalStrut(10));
lrMargins.add(comp);
lrMargins.add(Box.createHorizontalStrut(10));
c.add(lrMargins);
c.add(Box.createVerticalStrut(10));
}
public void setMessageApplied(int i, boolean flag) {
if (flag) {
for (JLabel m : msgApplied) {
m.setText(" (changed)");
}
} else {
msgApplied[i].setText(" ( )");
}
}
public void close() {
_simg = null;
_imgBtn.resetWindow();
}
public JTabbedPane getTabbedPane() {
return tabPane;
}
public void setTargetOffset(Location offset) {
if (offset != null) {
_tarOffsetPane.setTarget(offset.x, offset.y);
}
}
private void actionPerformedUpdates(Window _parent) {
boolean tempDirty = isDirty();
if (paneNaming.isDirty()) {
String filename = paneNaming.getAbsolutePath();
if (filename.contains("%")) {
Debug.error("%s\n%% in filename replaced with _", filename);
filename = filename.replace("%", "_");
}
String oldFilename = _imgBtn.getFilename();
if (FileManager.exists(filename)) {
String name = FileManager.getName(filename);
int ret = JOptionPane.showConfirmDialog(
_parent,
SikuliIDEI18N._I("msgFileExists", name),
SikuliIDEI18N._I("dlgFileExists"),
JOptionPane.WARNING_MESSAGE,
JOptionPane.YES_NO_OPTION);
if (ret != JOptionPane.YES_OPTION) {
return;
}
if (isFileOverwritten) {
if (!revertImageRename()) {
return;
}
}
isFileOverwritten = true;
}
try {
FileManager.xcopy(oldFilename, filename);
_imgBtn.setFilename(filename);
fileRenameOld = oldFilename;
fileRenameNew = filename;
} catch (IOException ioe) {
Debug.error("renaming failed: old: %s \nnew: %s\n%s",
oldFilename, filename, ioe.getMessage());
isFileOverwritten = false;
return;
}
paneNaming.updateFilename();
addDirty(true);
}
addDirty(_imgBtn.setParameters(
_screenshot.isExact(), _screenshot.getSimilarity(),
_screenshot.getNumMatches()));
addDirty(_imgBtn.setTargetOffset(_tarOffsetPane.getTargetOffset()));
if (isDirty() || tempDirty) {
Debug.log(3, "Preview: update: " + _imgBtn.toString());
int i = _imgBtn.getWindow().getTabbedPane().getSelectedIndex();
_imgBtn.getWindow().setMessageApplied(i, true);
_imgBtn.repaint();
}
}
private boolean revertImageRename() {
try {
FileManager.xcopy(fileRenameNew, fileRenameOld);
_imgBtn.setFilename(fileRenameOld);
} catch (IOException ioe) {
Debug.error("revert renaming failed: new: %s \nold: %s\n%s",
fileRenameNew, fileRenameOld, ioe.getMessage());
return false;
}
return true;
}
class ActionOK implements ActionListener {
private Window _parent;
public ActionOK(JFrame parent) {
_parent = parent;
}
@Override
public void actionPerformed(ActionEvent e) {
actionPerformedUpdates(_parent);
if (fileRenameOld != null) {
currentPane.reparse(fileRenameOld, fileRenameNew, isFileOverwritten);
}
_imgBtn.getWindow().close();
_parent.dispose();
currentPane.setDirty(setDirty(false));
}
}
class ActionApply implements ActionListener {
private Window _parent;
public ActionApply(Window parent) {
_parent = parent;
}
@Override
public void actionPerformed(ActionEvent e) {
actionPerformedUpdates(_parent);
_imgBtn.getWindow().getTabbedPane().getSelectedComponent().transferFocus();
}
}
class ActionCancel implements ActionListener {
private Window _parent;
public ActionCancel(Window parent) {
_parent = parent;
}
@Override
public void actionPerformed(ActionEvent e) {
if (isDirty()) {
_imgBtn.resetParameters();
if (isFileOverwritten) {
revertImageRename();
}
}
_imgBtn.getWindow().close();
_parent.dispose();
}
}
protected boolean isDirty() {
return dirty;
}
private boolean setDirty(boolean flag) {
boolean xDirty = dirty;
dirty = flag;
return xDirty;
}
protected void addDirty(boolean flag) {
dirty |= flag;
}
}