/* * Copyright (c) 2010-2016, Sikuli.org, sikulix.com * Released under the MIT License. * */ package org.sikuli.ide; import org.sikuli.android.ADBScreen; import org.sikuli.basics.PreferencesUser; import java.awt.*; import java.awt.event.*; import java.io.File; import java.net.*; import javax.swing.*; import javax.swing.text.*; import org.sikuli.basics.Debug; import org.sikuli.basics.FileManager; import org.sikuli.script.*; import org.sikuli.script.Sikulix; import org.sikuli.util.OverlayCapturePrompt; import org.sikuli.basics.Settings; import org.sikuli.util.EventObserver; import org.sikuli.util.EventSubject; import static org.sikuli.script.Sikulix.popup; class ButtonCapture extends ButtonOnToolbar implements ActionListener, Cloneable, EventObserver { private static final String me = "ButtonCapture: "; protected Element _line; protected EditorPane _codePane; private boolean captureCancelled = false; private EditorPatternLabel _lbl = null; private String givenName = ""; public static boolean debugTrace = true; public ButtonCapture() { super(); URL imageURL = SikuliIDE.class.getResource("/icons/camera-icon.png"); setIcon(new ImageIcon(imageURL)); PreferencesUser pref = PreferencesUser.getInstance(); String strHotkey = Key.convertKeyToText( pref.getCaptureHotkey(), pref.getCaptureHotkeyModifiers()); setToolTipText(SikuliIDE._I("btnCaptureHint", strHotkey)); setText(SikuliIDE._I("btnCaptureLabel")); //setBorderPainted(false); //setMaximumSize(new Dimension(26,26)); addActionListener(this); _line = null; } public ButtonCapture(EditorPane codePane, Element elmLine) { this(); _line = elmLine; _codePane = codePane; setUI(UIManager.getUI(this)); setBorderPainted(true); setCursor(new Cursor(Cursor.HAND_CURSOR)); setText(null); URL imageURL = SikuliIDE.class.getResource("/icons/capture-small.png"); setIcon(new ImageIcon(imageURL)); } public ButtonCapture(EditorPatternLabel lbl) { // for internal use with the image label __CLICK-TO-CAPTURE__ super(); _line = null; _codePane = null; _lbl = lbl; } @Override public void actionPerformed(ActionEvent e) { Debug.log(3, "ButtonCapture: capture!"); captureWithAutoDelay(); } public void captureWithAutoDelay() { PreferencesUser pref = PreferencesUser.getInstance(); int delay = (int) (pref.getCaptureDelay() * 1000.0) + 1; capture(delay); } IScreen defaultScreen = null; ScreenImage sImgNonLocal = null; public void capture(final int delay) { String line = ""; SikuliIDE ide = SikuliIDE.getInstance(); ide.setVisible(false); EditorPane codePane = ide.getCurrentCodePane(); line = codePane.getLineTextAtCaret(); givenName = codePane.parseLineText("#" + line.trim()); Debug.log(3, "ButtonCapture: doPrompt for %s", givenName); RunTime.pause(((float) delay)/1000); defaultScreen = SikuliIDE.getDefaultScreen(); if (defaultScreen == null) { Screen.doPrompt("Select an image", this); } else { Sikulix.popup("Android capture"); Thread adbCapture = new Thread() { @Override public void run() { ADBScreen aScr = (ADBScreen) defaultScreen; aScr.wakeUp(2); sImgNonLocal = aScr.userCapture(""); ButtonCapture.this.update((EventSubject) null); } }; adbCapture.start(); } } @Override public void update(EventSubject es) { Debug.log(3, "ButtonCapture: update"); ScreenImage simg = null; OverlayCapturePrompt ocp = null; if (null == es) { simg = sImgNonLocal; } else { ocp = (OverlayCapturePrompt) es; simg = ocp.getSelection(); Screen.closePrompt(); } String filename = null; String fullpath = null; EditorPane pane = SikuliIDE.getInstance().getCurrentCodePane(); boolean saveOverwrite = Settings.OverwriteImages; if (simg != null) { if (!givenName.isEmpty()) { filename = givenName + ".png"; Settings.OverwriteImages = true; } else { int naming = PreferencesUser.getInstance().getAutoNamingMethod(); if (naming == PreferencesUser.AUTO_NAMING_TIMESTAMP) { filename = Settings.getTimestamp(); } else if (naming == PreferencesUser.AUTO_NAMING_OCR) { filename = PatternPaneNaming.getFilenameFromImage(simg.getImage()); if (filename == null || filename.length() == 0) { filename = Settings.getTimestamp(); } } else { String nameOCR = ""; try { nameOCR = PatternPaneNaming.getFilenameFromImage(simg.getImage()); } catch (Exception e) { } filename = getFilenameFromUser(nameOCR); } } if (filename != null) { fullpath = FileManager.saveImage(simg.getImage(), filename, pane.getSrcBundle()); if (fullpath != null) { fullpath = FileManager.slashify(fullpath, false); } } } Settings.OverwriteImages = saveOverwrite; captureCompleted(fullpath); if (ocp != null) { Screen.resetPrompt(ocp); } SikuliIDE.showAgain(); } public void captureCompleted(String imgFullPath) { Element src = getSrcElement(); if (imgFullPath != null) { Debug.log(3, "captureCompleted: " + imgFullPath); if (src == null) { if (_codePane == null) { if (_lbl == null) { insertAtCursor(SikuliIDE.getInstance().getCurrentCodePane(), imgFullPath); } else { _lbl.setFile(imgFullPath); } } else { insertAtCursor(_codePane, imgFullPath); } } else { replaceButton(src, imgFullPath); } } else { Debug.log(3, "ButtonCapture: Capture cancelled"); if (src != null) { captureCancelled = true; replaceButton(src, ""); captureCancelled = false; } } } //<editor-fold defaultstate="collapsed" desc="RaiMan not used"> /*public boolean hasNext() { * return false; * }*/ /*public CaptureButton getNextDiffButton() { * return null; * }*/ /*public void setParentPane(SikuliPane parent) { * _codePane = parent; * }*/ /*public void setDiffMode(boolean flag) { * }*/ /*public void setSrcElement(Element elmLine) { * _line = elmLine; * }*/ //</editor-fold> private String getFilenameFromUser(String hint) { return (String) JOptionPane.showInputDialog( _codePane, SikuliIDEI18N._I("msgEnterScreenshotFilename"), SikuliIDEI18N._I("dlgEnterScreenshotFilename"), JOptionPane.PLAIN_MESSAGE, null, null, hint); } private Element getSrcElement() { return _line; } private boolean replaceButton(Element src, String imgFullPath) { if (captureCancelled) { if (_codePane.showThumbs && PreferencesUser.getInstance().getPrefMoreImageThumbs() || !_codePane.showThumbs) { return true; } } int start = src.getStartOffset(); int end = src.getEndOffset(); int old_sel_start = _codePane.getSelectionStart(), old_sel_end = _codePane.getSelectionEnd(); try { StyledDocument doc = (StyledDocument) src.getDocument(); String text = doc.getText(start, end - start); Debug.log(3, text); for (int i = start; i < end; i++) { Element elm = doc.getCharacterElement(i); if (elm.getName().equals(StyleConstants.ComponentElementName)) { AttributeSet attr = elm.getAttributes(); Component com = StyleConstants.getComponent(attr); boolean isButton = com instanceof ButtonCapture; boolean isLabel = com instanceof EditorPatternLabel; if (isButton || isLabel && ((EditorPatternLabel) com).isCaptureButton()) { Debug.log(5, "button is at " + i); int oldCaretPos = _codePane.getCaretPosition(); _codePane.select(i, i + 1); if (!_codePane.showThumbs) { _codePane.insertString((new EditorPatternLabel(_codePane, imgFullPath, true)).toString()); } else { if (PreferencesUser.getInstance().getPrefMoreImageThumbs()) { com = new EditorPatternButton(_codePane, imgFullPath); } else { if (captureCancelled) { com = new EditorPatternLabel(_codePane, ""); } else { com = new EditorPatternLabel(_codePane, imgFullPath, true); } } _codePane.insertComponent(com); } _codePane.setCaretPosition(oldCaretPos); break; } } } } catch (BadLocationException ble) { Debug.error(me + "Problem inserting Button!\n%s", ble.getMessage()); } _codePane.select(old_sel_start, old_sel_end); _codePane.requestFocus(); return true; } protected void insertAtCursor(EditorPane pane, String imgFilename) { String img = "\"" + (new File(imgFilename)).getName() + "\""; if (!pane.showThumbs) { pane.insertString(img); } else { if (PreferencesUser.getInstance().getPrefMoreImageThumbs()) { EditorPatternButton comp = EditorPatternButton.createFromFilename(pane, imgFilename, null); if (comp != null) { pane.insertComponent(comp); } } else { pane.insertComponent(new EditorPatternLabel(pane, imgFilename, true)); } } //TODO set Caret pane.requestFocus(); } @Override public String toString() { return "\"__CLICK-TO-CAPTURE__\""; } }