package com.qksnap.www.snap.gui; import java.awt.AWTException; import java.awt.Color; import java.awt.Dimension; import java.awt.DisplayMode; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.MenuItem; import java.awt.Point; import java.awt.PopupMenu; import java.awt.Rectangle; import java.awt.Robot; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.ClipboardOwner; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Iterator; import java.util.List; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.event.IIOReadProgressListener; import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.MemoryCacheImageOutputStream; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import javax.swing.WindowConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.qksnap.www.snap.gui.tabpane.AboutPane; import com.qksnap.www.snap.gui.tabpane.Links; import com.qksnap.www.snap.gui.tabpane.MainPane; import com.qksnap.www.snap.gui.tabpane.Settings; import com.qksnap.www.snap.gui.tabpane.Uploader; import com.qksnap.www.snap.gui.tabpane.data.ImageLink; import com.qksnap.www.snap.gui.tabpane.ui.TabUI; import com.qksnap.www.snap.hotkeys.common.HotKey; import com.qksnap.www.snap.hotkeys.common.HotKeyListener; import com.qksnap.www.snap.hotkeys.common.Provider; import com.qksnap.www.snap.io.SocketEngine; import com.qksnap.www.snap.settings.UserSettings; import com.qksnap.www.snap.util.Config; public class MainFrame extends JFrame implements ClipboardOwner { /** TODO: Need to really clean this up **/ /** global Hotkey provider **/ private Provider provider = Provider.getCurrentProvider(true); /** Instance to this class **/ private MainFrame instance; /** Links instance **/ private Links links; /** Settings instance **/ private Settings settings; /** Screenshot Image **/ private byte[] img; private Uploader upload; /** Main Tabbed pane instance **/ private MainPane mainPane; /** Our tab pane **/ private JTabbedPane pane; /** Area used to capture selected screenshots **/ private Rectangle SS; /** Parent Frame **/ private JFrame frame; /** Our Tray icon **/ private TrayIcon trayIcon; private boolean isDrawingAlready; /** our Hotkey Listener **/ private HotKeyListener[] listener = new HotKeyListener[3]; /** Our Socket Engine **/ private SocketEngine se; private Dimension screenSize; private Rectangle screenRectangle; private Robot robot; /** * Create the System Tray Icon and menu */ public void createTray() { if (!SystemTray.isSupported()) { System.out.println("SystemTray is not supported"); return; } try { final PopupMenu pop = new PopupMenu(); java.net.URL imageURL = getClass().getResource("/icon.png"); trayIcon = new TrayIcon(new ImageIcon(imageURL).getImage(), "QwikSnap"); final SystemTray tray = SystemTray.getSystemTray(); tray.add(trayIcon); /** Click Tray Icon **/ trayIcon.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { setVisible(true); setExtendedState(NORMAL); repaint(); } }); /** Frame Listener **/ addWindowListener(new WindowAdapter() { @Override public void windowDeiconified(WindowEvent e) { setVisible(true); validate(); repaint(); } @Override public void windowIconified(WindowEvent e) { setVisible(false); try { // tray.add(trayIcon); repaint(); } catch (Exception ed) { // TODO Auto-generated catch block ed.printStackTrace(); } } @Override public void windowClosing(WindowEvent e) { provider.reset(); provider.stop(); System.exit(0); } }); // Create a pop-up menu components MenuItem aboutItem = new MenuItem("Open QwikSnap"); aboutItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setVisible(true); setExtendedState(NORMAL); } }); pop.add(aboutItem); MenuItem exitItem = new MenuItem("Exit QwikSnap"); exitItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(2); } }); pop.add(exitItem); trayIcon.setPopupMenu(pop); } catch (Exception e) { e.printStackTrace(); } } /** * Create and initalize our tabbed pane */ private void createTabPane() { pane = new JTabbedPane(JTabbedPane.TOP); mainPane = new MainPane(); links = new Links(); upload = new Uploader(); settings = new Settings(); pane.setUI(new TabUI()); pane.setForeground(Color.white); pane.setFont(new Font("verdana", Font.CENTER_BASELINE, 12)); pane.addTab("Main", null, mainPane, "Main Panel"); pane.setMnemonicAt(0, KeyEvent.VK_1); pane.addTab("Upload", null, upload, "Offline Upload"); pane.setMnemonicAt(1, KeyEvent.VK_2); pane.addTab("Saved Image", null, links, "View Saved Links"); pane.setMnemonicAt(2, KeyEvent.VK_3); pane.addTab("Settings", null, settings, "Settings"); pane.setMnemonicAt(3, KeyEvent.VK_4); pane.addTab("About", null, new AboutPane(), "About Qwik Snap"); pane.setMnemonicAt(4, KeyEvent.VK_5); pane.addChangeListener(new ChangeListener() { // This method is called whenever the selected tab changes public void stateChanged(ChangeEvent evt) { JTabbedPane pane = (JTabbedPane) evt.getSource(); Object[] options = { "Save", "Reset Hotkeys" }; // Get current tab int sel = pane.getSelectedIndex(); if (sel != 2) upload.reset(); if (sel != 4 && settings.isHKPressed()) { int n = JOptionPane .showOptionDialog( frame, "You did not save your hot key changes! Would you like to save now?", "Error 10", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]); switch (n) { case 0: getProvider().reset(); getProvider().register( KeyStroke.getKeyStroke(settings.getSsHotkey() .getText()), hkListener()); getProvider().register( KeyStroke.getKeyStroke(settings.getSsRectkey() .getText()), hkListener2()); getProvider().register( KeyStroke.getKeyStroke(settings.getSsCutkey() .getText()), hkListener3()); SplashScreen.getSingleton().getUserSettings().update( settings.getSsRectkey().getText(), settings.getSsHotkey().getText(), settings.getSsCutkey().getText(), 1); getMainPane().updateLbl(); getMainPane().repaint(); getTrayIcon().displayMessage("QwikSnap", "Your settings have been saved.", TrayIcon.MessageType.INFO); settings.setHKPressed(false); break; default: getProvider().reset(); provider.register(KeyStroke .getKeyStroke(SplashScreen.getSingleton().getUserSettings().getSnapHK()), listener[0]); provider.register(KeyStroke .getKeyStroke(SplashScreen.getSingleton().getUserSettings().getSelHK()), listener[1]); provider.register( KeyStroke.getKeyStroke(SplashScreen.getSingleton().getUserSettings() .getSelsnapHK()), listener[2]); settings.updateSettings(); getMainPane().updateLbl(); getMainPane().repaint(); settings.setHKPressed(false); getTrayIcon().displayMessage("QwikSnap", "Your hotkey settings were reset to default..", TrayIcon.MessageType.INFO); } } } }); pane.validate(); } public void createGui() throws AWTException { frame = new JFrame("QwikSnap"); final Point point = new Point(); int width = 0; int height = 0; /** Duel Monitor Support **/ GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice[] gs = ge.getScreenDevices(); for (GraphicsDevice curGs : gs) { DisplayMode mode = curGs.getDisplayMode(); width += mode.getWidth(); height = mode.getHeight(); } screenSize = new Dimension(width,height); screenRectangle = new Rectangle(screenSize); robot = new Robot(); setSize(564, 240); setFont(new Font("verdana", Font.PLAIN, '9')); setResizable(false); setLayout(null); setUndecorated(true); setLocationRelativeTo(null); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { point.x = e.getX(); point.y = e.getY(); } }); addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { Point p = getLocation(); setLocation(p.x + e.getX() - point.x, p.y + e.getY() - point.y); } }); repaint(); } public MainFrame() throws IOException { setSize(564, 240); setLayout(null); try { createGui(); } catch (AWTException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } createTray(); createTabPane(); // pane.setBorder(BorderFactory.createLineBorder(Color.black)); setBackground(new Color(53, 53, 53)); // pane.setBackground(new Color(53,53,53)); pane.setForeground(Color.black); pane.setBounds(0, 57, 564, 180); JButton min = new JButton(new ImageIcon(getClass().getResource( "/min.png"))); min.setContentAreaFilled(false); min.setBorderPainted(false); min.setFocusPainted(false); JButton exit = new JButton(new ImageIcon(getClass().getResource( "/exit.png"))); exit.setContentAreaFilled(false); exit.setContentAreaFilled(false); exit.setBorderPainted(false); exit.setFocusPainted(false); exit.setBounds(540, 3, 16, 16); exit.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { System.exit(1); } }); min.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { setState(ICONIFIED); } }); min.setContentAreaFilled(false); min.setBounds(520, 3, 16, 16); add(min); add(pane); add(exit); JLabel bg = new JLabel(new ImageIcon(getClass().getResource("/bg.png"))); bg.setBounds(0, 0, 564, 240); add(bg); bg = null; // predefined area screenshot listener[0] = new HotKeyListener() { public void onHotKey(final HotKey hotKey) { if (!isDrawingAlready()) screenshot(); } }; // clip then snap listener[1] = new HotKeyListener() { public void onHotKey(final HotKey hotKey) { if (!isDrawingAlready()) { GlassFrame.getInstance().setUpWindow(false); GlassFrame.getInstance().setVisible(true); setIsDrawingAlready(true); } } }; // snap then freeze listener[2] = new HotKeyListener() { public void onHotKey(final HotKey hotKey) { if (!isDrawingAlready()) { snapscreenshot(); setIsDrawingAlready(true); } } }; provider.reset(); provider.register(KeyStroke.getKeyStroke(SplashScreen.getSingleton().getUserSettings().getSnapHK()), listener[0]); provider.register(KeyStroke.getKeyStroke(SplashScreen.getSingleton().getUserSettings().getSelHK()), listener[1]); provider.register(KeyStroke.getKeyStroke(SplashScreen.getSingleton().getUserSettings().getSelsnapHK()), listener[2]); validate(); } public void snapscreenshot(){ setImg(convertImg(robot.createScreenCapture(screenRectangle))); GlassFrame.getInstance().setUpWindow(true); GlassFrame.getInstance().setVisible(true); } public void screenshot() { try { robot = new Robot(); if (SS == null) { getTrayIcon().displayMessage( "QwikSnap", "You must select screen coordinates first!\nPress (" + SplashScreen.getSingleton().getUserSettings().getSelHK() + ") to select a region", TrayIcon.MessageType.ERROR); return; } setImg(convertImg(robot.createScreenCapture(SS))); getSE().start(); } catch (AWTException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void sendRectScreen(Rectangle s){ setImg(convertImg(crop(s))); getSE().start(); } public SocketEngine getSE() { if (se == null) se = new SocketEngine(); return se; } public byte[] getImg(){ return this.img; } public void setImg(byte[] in){ this.img = in; } public byte[] convertImg(BufferedImage in){ ByteArrayOutputStream baos=new ByteArrayOutputStream(); try { ImageIO.write(in, "png", baos ); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } byte[] imageInByte=baos.toByteArray(); return imageInByte; } public BufferedImage crop(Rectangle rect){ BufferedImage sml = new BufferedImage((int) rect.getWidth(), (int) rect.getHeight(), BufferedImage.TYPE_INT_RGB); Graphics2D g2d = (Graphics2D) sml.getGraphics(); try { g2d.drawImage(ImageIO.read((InputStream)new ByteArrayInputStream(getImg())), 0, 0, (int) rect.getWidth(), (int) rect.getHeight(), (int) rect.getX(), (int) rect.getY(), (int) (rect.getX() + rect.getWidth()), (int) (rect.getY() + rect.getHeight()), null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } g2d.dispose(); return Config.toCompatibleImage(sml); } @Override public void lostOwnership(Clipboard clipboard, Transferable contents) { // TODO Auto-generated method stub } public Links getLinks() { return links; } protected ImageIcon createImageIcon(String path, String description) { java.net.URL imgURL = getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL, description); } else { System.err.println("Couldn't find file: " + path); return null; } } public HotKeyListener hkListener() { return listener[0]; } public HotKeyListener hkListener2() { return listener[1]; } public HotKeyListener hkListener3() { return listener[2]; } public JFrame getFrame() { return frame; } public void setRect(Rectangle ss) { this.SS = ss; } public boolean isDrawingAlready() { return this.isDrawingAlready; } public void setIsDrawingAlready(boolean s) { this.isDrawingAlready = s; } public Provider getProvider() { return provider; } public MainPane getMainPane() { return mainPane; } public TrayIcon getTrayIcon() { return trayIcon; } public Settings getSettings() { // TODO Auto-generated method stub return settings; } }