/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.smart.dataui; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Insets; import java.awt.Point; import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DnDConstants; import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFileChooser; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.ScrollPaneConstants; import javax.swing.TransferHandler; import javax.swing.text.Document; import com.servoy.base.util.ITagResolver; import com.servoy.j2db.IApplication; import com.servoy.j2db.IModeManager; import com.servoy.j2db.IScriptExecuter; import com.servoy.j2db.IServiceProvider; import com.servoy.j2db.ISmartClientApplication; import com.servoy.j2db.component.ISupportAsyncLoading; import com.servoy.j2db.dataprocessing.DataAdapterList; import com.servoy.j2db.dataprocessing.IDisplayData; import com.servoy.j2db.dataprocessing.IEditListener; import com.servoy.j2db.ui.IDataRenderer; import com.servoy.j2db.ui.IEventExecutor; import com.servoy.j2db.ui.IFieldComponent; import com.servoy.j2db.ui.ILabel; import com.servoy.j2db.ui.IMediaFieldConstants; import com.servoy.j2db.ui.IScrollPane; import com.servoy.j2db.ui.ISupportCachedLocationAndSize; import com.servoy.j2db.ui.ISupportOnRender; import com.servoy.j2db.ui.scripting.RuntimeMediaField; import com.servoy.j2db.util.Debug; import com.servoy.j2db.util.EnableScrollPanel; import com.servoy.j2db.util.FileChooserUtils; import com.servoy.j2db.util.HtmlUtils; import com.servoy.j2db.util.ImageLoader; import com.servoy.j2db.util.MimeTypes; import com.servoy.j2db.util.Text; import com.servoy.j2db.util.Utils; import com.servoy.j2db.util.gui.FileNameSuggestionFileChooser; import com.servoy.j2db.util.gui.MyImageIcon; import com.servoy.j2db.util.gui.SnapShot; /** * Field for serving blobs (mainly images) * * @author jblok */ @SuppressWarnings("nls") public class DataImgMediaField extends EnableScrollPanel implements IDisplayData, IFieldComponent, IScrollPane, DropTargetListener, ISupportAsyncLoading, ISupportCachedLocationAndSize, ISupportOnRender { private final static Icon NOT_EMPTY_IMAGE; static { byte[] notEmptyImage = new byte[0]; try { InputStream is = IApplication.class.getResourceAsStream("images/notemptymedia.gif"); notEmptyImage = new byte[is.available()]; is.read(notEmptyImage); is.close(); } catch (IOException ex) { Debug.error(ex); } NOT_EMPTY_IMAGE = ImageLoader.getIcon(notEmptyImage, -1, -1, true); } private final AbstractScriptLabel enclosedComponent; private String dataProviderID; private volatile Object value; private final IApplication application; private final EventExecutor eventExecutor; private MouseAdapter rightclickMouseAdapter = null; private final RuntimeMediaField scriptable; public DataImgMediaField(IApplication app, RuntimeMediaField scriptable) { application = app; eventExecutor = new EventExecutor(this);//not setting the enclosed comp, not needed here getViewport().setView(new AbstractScriptLabel(app, null /* no scriptable */) { @Override public String toString() // uses scriptable { return "Enclosed component for " + DataImgMediaField.this.toString(); } }); enclosedComponent = (AbstractScriptLabel)getViewport().getView(); enclosedComponent.setOpaque(true); // setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); enclosedComponent.setMediaOption(1); MouseAdapter mouseListener = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (e.isPopupTrigger() && popup != null) { popup.show(DataImgMediaField.this, e.getX() - DataImgMediaField.this.getHorizontalScrollBar().getValue(), e.getY() - DataImgMediaField.this.getVerticalScrollBar().getValue()); } } @Override public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) { if (popup != null) { // the popup invoker should be displayed in order to show popup; otherwise error is thrown // it is for readonly listview where action should work and popup shouldn't if (isDisplayable()) popup.show(DataImgMediaField.this, e.getX() - DataImgMediaField.this.getHorizontalScrollBar().getValue(), e.getY() - DataImgMediaField.this.getVerticalScrollBar().getValue()); } } else if ((popup == null || !popup.isVisible()) && isEnabled()) { eventExecutor.fireActionCommand(false, DataImgMediaField.this, e.getModifiers(), e.getPoint()); } } // public void mouseClicked(MouseEvent e) // { // if (popup == null || !popup.isVisible()) // { // eventExecutor.fireActionCommand(false, DataImgMediaField.this); // } // } }; addMouseListener(mouseListener); enclosedComponent.addMouseListener(mouseListener); enclosedComponent.addKeyListener(eventExecutor); try { if (!GraphicsEnvironment.isHeadless()) { DropTarget dt = getDropTarget(); if (dt == null) { dt = new DropTarget(this, this); } dt.addDropTargetListener(editProvider); } } catch (Exception e) { Debug.error(e); } this.scriptable = scriptable; scriptable.setjComponent(enclosedComponent); } public final RuntimeMediaField getScriptObject() { return scriptable; } @Override public void setHorizontalScrollBarPolicy(int policy) { setMediaOptions(getVerticalScrollBarPolicy(), policy); super.setHorizontalScrollBarPolicy(policy); } @Override public void setVerticalScrollBarPolicy(int policy) { setMediaOptions(policy, getHorizontalScrollBarPolicy()); super.setVerticalScrollBarPolicy(policy); } private void setMediaOptions(int vertical, int horizontal) { if (enclosedComponent != null) { if (horizontal == ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER || vertical == ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER) { enclosedComponent.setMediaOption(10); } else { enclosedComponent.setMediaOption(1); } } } public Object getValueObject() { return value; } public Document getDocument() { return null; } public boolean needEditListener() { return true; } private EditProvider editProvider = null; public void addEditListener(IEditListener l) { if (editProvider == null) { editProvider = new EditProvider(this); editProvider.addEditListener(l); } } public IEventExecutor getEventExecutor() { return eventExecutor; } public boolean needEntireState() { return true; // always true so that we get have a tagresolver to use when loading/saving for use with dataprovider_filename and _mimetype TODO refactor this so as not to use tag resolver for this } private boolean needsToProcessTags; public void setNeedEntireState(boolean b) { needsToProcessTags = b; } @Override public String toString() { return scriptable.toString(); } private boolean useAsync = true; public void setAsyncLoadingEnabled(boolean useAsync) { this.useAsync = useAsync; } private boolean isAsyncLoading() { return useAsync && !Utils.getAsBoolean(application.getRuntimeProperties().get("isPrinting")); } protected ITagResolver resolver; public void setTagResolver(ITagResolver resolver) { this.resolver = resolver; } private Object previousValue; public void setValueObject(Object obj) { if ("".equals(obj)) obj = null; try { if (editProvider != null) editProvider.setAdjusting(true); if (needsToProcessTags) { if (resolver != null) { if (tooltip != null) { String txt = Text.processTags(tooltip, resolver); setToolTipTextImpl(txt); } } else { if (tooltip != null) { setToolTipTextImpl(null); } } } if (previousValue != null && previousValue.equals(obj)) return; previousValue = obj; value = obj; if (obj instanceof byte[] || (obj instanceof String && !editState)) { if (isAsyncLoading() && application.getModeManager().getMode() == IModeManager.EDIT_MODE) { enclosedComponent.setIconDirect((Icon)null, enclosedComponent.getNextSeq());//clear previous image enclosedComponent.setText(application.getI18NMessage("servoy.imageMedia.loadingImage"));//show loading text } final Object tmp = obj; final int seq = enclosedComponent.getNextSeq(); Runnable action = new Runnable() { public void run() { byte[] array = getByteArrayContents(tmp); Icon icon = ImageLoader.getIcon(array, -1, -1, true); if (icon == null) { if (array != null && array.length > 0) { icon = NOT_EMPTY_IMAGE; } else if (application.getI18NMessage("servoy.imageMedia.loadingImage").equals(enclosedComponent.getText())) { enclosedComponent.setText(null); } } if (!isAsyncLoading() || (application.getModeManager().getMode() != IModeManager.EDIT_MODE) || Utils.equalObjects(tmp, getValueObject())) { enclosedComponent.setIconDirect(icon, seq); } else if (application.getI18NMessage("servoy.imageMedia.loadingImage").equals(enclosedComponent.getText())) { enclosedComponent.setText(null); } } }; if (isAsyncLoading() && application.getModeManager().getMode() == IModeManager.EDIT_MODE) { application.getScheduledExecutor().execute(action); } else { action.run(); } } else { setIcon(null); if (application.getI18NMessage("servoy.imageMedia.loadingImage").equals(enclosedComponent.getText())) { enclosedComponent.setText(null); } } } finally { if (editProvider != null) editProvider.setAdjusting(false); } fireOnRender(false); } public void fireOnRender(boolean force) { if (scriptable != null) { if (force) scriptable.getRenderEventExecutor().setRenderStateChanged(); scriptable.getRenderEventExecutor().fireOnRender(hasFocus()); } } private byte[] getByteArrayContents(Object tmp) { byte[] array = null; if (tmp instanceof String) { array = Utils.getURLContent((String)tmp, application); if (array == null) { Debug.error("Cannot get media for field with dataprovider '" + getDataProviderID() + "' on form " + (application.getFormManager().getCurrentForm() == null ? null : application.getFormManager().getCurrentForm().getName())); } } else if (tmp instanceof byte[]) { array = (byte[])tmp; } return array; } public String getDataProviderID() { return dataProviderID; } public void setDataProviderID(String id) { dataProviderID = id; } /* * _____________________________________________________________ Methods for event handling */ public void addScriptExecuter(IScriptExecuter el) { eventExecutor.setScriptExecuter(el); } public void setEnterCmds(String[] ids, Object[][] args) { eventExecutor.setEnterCmds(ids, args); } public void setLeaveCmds(String[] ids, Object[][] args) { eventExecutor.setLeaveCmds(ids, args); } public boolean isValueValid() { return isValueValid; } private boolean isValueValid = true; private Object previousValidValue; public void setValueValid(boolean valid, Object oldVal) { application.getRuntimeProperties().put(IServiceProvider.RT_LASTFIELDVALIDATIONFAILED_FLAG, Boolean.valueOf(!valid)); isValueValid = valid; if (!isValueValid) { previousValidValue = oldVal; application.invokeLater(new Runnable() { public void run() { requestFocus(); } }); } else { previousValidValue = null; } } public void notifyLastNewValueWasChange(Object oldVal, Object newVal) { if (previousValidValue != null) { oldVal = previousValidValue; } previousValue = newVal; eventExecutor.fireChangeCommand(oldVal, newVal, false, this); // if change cmd is not succeeded also don't call action cmd? if (isValueValid) { eventExecutor.fireActionCommand(false, this); } } public void setChangeCmd(String id, Object[] args) { eventExecutor.setChangeCmd(id, args); } public void setActionCmd(String id, Object[] args) { eventExecutor.setActionCmd(id, args); } public void setRightClickCommand(String rightClickCmd, Object[] args) { eventExecutor.setRightClickCmd(rightClickCmd, args); if (rightClickCmd != null && rightclickMouseAdapter == null) { rightclickMouseAdapter = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (e.isPopupTrigger()) handle(e); } @Override public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) handle(e); } private void handle(MouseEvent e) { if (isEnabled()) { eventExecutor.fireRightclickCommand(true, DataImgMediaField.this, e.getModifiers(), e.getPoint()); } } }; enclosedComponent.addMouseListener(rightclickMouseAdapter); } } public void setValidationEnabled(boolean b) { eventExecutor.setValidationEnabled(b); } public void setSelectOnEnter(boolean b) { eventExecutor.setSelectOnEnter(b); } //_____________________________________________________________ public boolean stopUIEditing(boolean looseFocus) { if (editProvider != null) editProvider.commitData(); if (!isValueValid) { application.invokeLater(new Runnable() { public void run() { requestFocus(); } }); return false; } return true; } private JPopupMenu popup; public void setEditable(boolean b) { editState = b; if (b) { ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if (cmd.equals("load")) { loadFromFile(); } else if (cmd.equals("save")) { saveToFile(); } else if (cmd.equals("copy")) { copyToClipboard(); } else if (cmd.equals("paste")) { pasteFromClipboard(); } else if (cmd.equals("remove")) { removeImage(); } } }; popup = new JPopupMenu(); JMenuItem loadMenuItem = new JMenuItem(application.getI18NMessage("servoy.imageMedia.popup.menuitem.load")); loadMenuItem.setActionCommand("load"); loadMenuItem.addActionListener(listener); popup.add(loadMenuItem); JMenuItem saveMenuItem = new JMenuItem(application.getI18NMessage("servoy.imageMedia.popup.menuitem.save")); saveMenuItem.setActionCommand("save"); saveMenuItem.addActionListener(listener); popup.add(saveMenuItem); JMenuItem copyMenuItem = new JMenuItem(application.getI18NMessage("servoy.imageMedia.popup.menuitem.copy")); copyMenuItem.setActionCommand("copy"); copyMenuItem.addActionListener(listener); popup.add(copyMenuItem); JMenuItem pasteMenuItem = new JMenuItem(application.getI18NMessage("servoy.imageMedia.popup.menuitem.paste")); pasteMenuItem.setActionCommand("paste"); pasteMenuItem.addActionListener(listener); popup.add(pasteMenuItem); JMenuItem removeMenuItem = new JMenuItem(application.getI18NMessage("servoy.imageMedia.popup.menuitem.remove")); removeMenuItem.setActionCommand("remove"); removeMenuItem.addActionListener(listener); popup.add(removeMenuItem); } else { popup = null; } } private static DataFlavor getByteArrayDataFlavor() { return new DataFlavor(byte[].class, "Byte Array"); } private static DataFlavor getStringArrayDataFlavor() { return new DataFlavor(String[].class, "String Array"); } protected void copyToClipboard() { try { // we copy to clipboard as byte array and filename/mimetype array used when pasting into another media field and as image icon for external pastes or if byte array is not available (and for external types) final Icon icon = enclosedComponent.getIcon(); final byte[] bytes = getByteArrayContents(value); final String[] fileNameAndMime = new String[2]; if (resolver instanceof DataAdapterList) { DataAdapterList dal = ((DataAdapterList)resolver); Object tmp = dal.getValueObject(dal.getState(), dataProviderID + IMediaFieldConstants.FILENAME); fileNameAndMime[0] = (tmp instanceof String) ? (String)tmp : null; tmp = dal.getValueObject(dal.getState(), dataProviderID + IMediaFieldConstants.MIMETYPE); fileNameAndMime[1] = (tmp instanceof String) ? (String)tmp : null; } if (icon instanceof ImageIcon || icon instanceof MyImageIcon) { Transferable tr = new Transferable() { public DataFlavor[] getTransferDataFlavors() { List<DataFlavor> list = new ArrayList<DataFlavor>(3); if (bytes != null) list.add(getByteArrayDataFlavor()); list.add(DataFlavor.imageFlavor); if (fileNameAndMime[0] != null || fileNameAndMime[1] != null) { list.add(getStringArrayDataFlavor()); list.add(DataFlavor.stringFlavor); } return list.toArray(new DataFlavor[list.size()]); } public boolean isDataFlavorSupported(DataFlavor flavor) { return DataFlavor.imageFlavor.equals(flavor) || (bytes != null && getByteArrayDataFlavor().equals(flavor)) || ((fileNameAndMime[0] != null || fileNameAndMime[1] != null) && (getStringArrayDataFlavor().equals(flavor) || DataFlavor.stringFlavor.equals(flavor))); } public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException { if (!isDataFlavorSupported(flavor)) { throw new UnsupportedFlavorException(flavor); } if (DataFlavor.imageFlavor.equals(flavor)) { if (icon instanceof ImageIcon) { return ((ImageIcon)icon).getImage(); } else if (icon instanceof MyImageIcon) { return ((MyImageIcon)icon).getOriginal().getImage(); } } else if (getByteArrayDataFlavor().equals(flavor)) { return bytes; } else if (getStringArrayDataFlavor().equals(flavor)) { return fileNameAndMime; } else if (DataFlavor.stringFlavor.equals(flavor)) { return (fileNameAndMime[0] != null ? "Filename: '" + fileNameAndMime[0] + "' " : "") + (fileNameAndMime[1] != null ? "Type: '" + fileNameAndMime[1] + "'" : ""); } return null; } }; Toolkit.getDefaultToolkit().getSystemClipboard().setContents(tr, null); } } catch (Exception e) { Debug.error(e); } } protected void pasteFromClipboard() { try { Transferable tr = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null); byte[] data; if (tr.isDataFlavorSupported(getByteArrayDataFlavor())) { data = (byte[])tr.getTransferData(getByteArrayDataFlavor()); } else { Image img = (Image)tr.getTransferData(DataFlavor.imageFlavor); data = SnapShot.createJPGImage(((ISmartClientApplication)application).getMainApplicationFrame(), img, -1, -1); } String[] fileNameAndMimeType; if (tr.isDataFlavorSupported(getStringArrayDataFlavor())) { fileNameAndMimeType = (String[])tr.getTransferData(getStringArrayDataFlavor()); if (fileNameAndMimeType == null || fileNameAndMimeType.length != 2) fileNameAndMimeType = new String[2]; // use null values as this is unknown clipboard data } else { fileNameAndMimeType = new String[2]; // null values } if (data != null && data.length != 0) { if (editProvider != null) editProvider.startEdit(); setValueObject(data); if (editProvider != null) editProvider.commitData(); // dataprovider_filename and dataprovider_mimetype fields will be set like in the web TODO maybe refactor to avoid cast below and existence of method setValueObject in DataAdapterList if (resolver instanceof DataAdapterList) { ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.FILENAME, fileNameAndMimeType[0]); ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.MIMETYPE, fileNameAndMimeType[1]); } } } catch (Exception e) { Debug.error(e); } } protected void removeImage() { try { if (editProvider != null) editProvider.startEdit(); setValueObject(null); if (editProvider != null) editProvider.commitData(); // dataprovider_filename and dataprovider_mimetype fields will be set like in the web TODO maybe refactor to avoid cast below and existence of method setValueObject in DataAdapterList if (resolver instanceof DataAdapterList) { ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.FILENAME, null); ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.MIMETYPE, null); } } catch (Exception e) { Debug.error(e); } } void loadFromFile() { JFileChooser fc = new JFileChooser(); int returnVal = fc.showOpenDialog(((ISmartClientApplication)application).getMainApplicationFrame()); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File f = fc.getSelectedFile(); if (editProvider != null) editProvider.startEdit(); byte[] content = null; if (application.isEventDispatchThread()) { setValueObject(content = FileChooserUtils.paintingReadFile(application.getScheduledExecutor(), application, f)); } else { setValueObject(content = FileChooserUtils.readFile(f)); } if (editProvider != null) editProvider.commitData(); // dataprovider_filename and dataprovider_mimetype fields will be set like in the web TODO maybe refactor to avoid cast below and existence of method setValueObject in DataAdapterList if (resolver instanceof DataAdapterList) { ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.FILENAME, f.getName()); ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.MIMETYPE, MimeTypes.getContentType(content, f.getName())); } } catch (Exception e) { if (application instanceof ISmartClientApplication) { ((ISmartClientApplication)application).reportError(this, application.getI18NMessage("servoy.imageMedia.error.loading"), e); } else { application.reportError(application.getI18NMessage("servoy.imageMedia.error.loading"), e); } } } } void saveToFile() { if (value instanceof byte[]) { byte[] array = (byte[])value; FileNameSuggestionFileChooser fc = new FileNameSuggestionFileChooser(); String fileName = null; // dataprovider_filename and dataprovider_mimetype fields will be used like in the web TODO maybe refactor to avoid cast below if (resolver instanceof DataAdapterList) { Object val = ((DataAdapterList)resolver).getValueObject(((DataAdapterList)resolver).getState(), dataProviderID + IMediaFieldConstants.FILENAME); fileName = (val instanceof String) ? (String)val : null; } if (fileName != null) { fc.suggestFileName(fileName); } else if (array.length > 3 && array[0] == -1 && array[1] == -40 && array[2] == -1)//jpeg { fc.suggestFileName("image.jpg"); } else if (array.length > 3 && array[0] == 0x47 && array[1] == 0x49 && array[2] == 0x46)//gif { fc.suggestFileName("image.gif"); } else { fc.suggestFileName("filename.unknown"); } int returnVal = fc.showSaveDialog(((ISmartClientApplication)application).getMainApplicationFrame()); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File f = fc.getSelectedFile(); OutputStream os = new FileOutputStream(f); BufferedOutputStream bos = new BufferedOutputStream(os); bos.write(array); bos.close(); } catch (Exception e) { if (application instanceof ISmartClientApplication) { ((ISmartClientApplication)application).reportError(this, application.getI18NMessage("servoy.imageMedia.error.loading"), e); } else { application.reportError(application.getI18NMessage("servoy.imageMedia.error.loading"), e); } } } } } public void setMaxLength(int i) { //ignore } public void setHorizontalAlignment(int a) { enclosedComponent.setHorizontalAlignment(a); } public void setMargin(Insets i) { // TODO why no call to enclosedComponent (disappeared in version 1.46) } public Insets getMargin() { return null; } public void requestFocusToComponent() { } public List<ILabel> getLabelsFor() { return labels; } /** * processed on background thread */ public void setIcon(Icon icon) { enclosedComponent.setIcon(icon); } public synchronized void drop(DropTargetDropEvent dropTargetDropEvent) { try { Transferable tr = dropTargetDropEvent.getTransferable(); if (popup != null && tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { dropTargetDropEvent.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); List fileList = (List)tr.getTransferData(DataFlavor.javaFileListFlavor); Iterator iterator = fileList.iterator(); if (iterator.hasNext()) { try { File file = (File)iterator.next(); if (editProvider != null) editProvider.startEdit(); byte content[] = FileChooserUtils.paintingReadFile(application.getScheduledExecutor(), application, file); setValueObject(content); if (editProvider != null) editProvider.commitData(); // dataprovider_filename and dataprovider_mimetype fields will be set like in the web TODO maybe refactor to avoid cast below and existence of method setValueObject in DataAdapterList if (resolver instanceof DataAdapterList) { ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.FILENAME, file.getName()); ((DataAdapterList)resolver).setValueObject(dataProviderID + IMediaFieldConstants.MIMETYPE, MimeTypes.getContentType(content, file.getName())); } } catch (Exception e) { if (application instanceof ISmartClientApplication) { ((ISmartClientApplication)application).reportError(this, application.getI18NMessage("servoy.imageMedia.error.loading"), e); } else { application.reportError(application.getI18NMessage("servoy.imageMedia.error.loading"), e); } } } dropTargetDropEvent.getDropTargetContext().dropComplete(true); } else { Debug.trace("Rejected"); dropTargetDropEvent.rejectDrop(); } } catch (Exception io) { Debug.error(io); dropTargetDropEvent.rejectDrop(); } } public void dragEnter(DropTargetDragEvent dropTargetDragEvent) { if (isEnabled() && popup != null) { dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } else { dropTargetDragEvent.rejectDrag(); } } public void dragExit(DropTargetEvent dropTargetEvent) { } public void dragOver(DropTargetDragEvent dropTargetDragEvent) { } public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { } /* * bgcolor--------------------------------------------------- */ @Override public void setBackground(Color bg) { if (enclosedComponent != null) enclosedComponent.setBackground(bg); super.setBackground(bg); } @Override public Color getBackground() { if (enclosedComponent != null) { return enclosedComponent.getBackground(); } return super.getBackground(); } /* * fgcolor--------------------------------------------------- */ @Override public Color getForeground() { if (enclosedComponent != null) { return enclosedComponent.getForeground(); } return super.getForeground(); } @Override public void setForeground(Color fg) { if (enclosedComponent != null) enclosedComponent.setForeground(fg); super.setForeground(fg); } private Point cachedLocation; public Point getCachedLocation() { return cachedLocation; } private Dimension cachedSize; public Dimension getCachedSize() { return cachedSize; } public void setCachedLocation(Point location) { this.cachedLocation = location; } public void setCachedSize(Dimension size) { this.cachedSize = size; } public int getAbsoluteFormLocationY() { Container parent = getParent(); while ((parent != null) && !(parent instanceof IDataRenderer)) { parent = parent.getParent(); } if (parent != null) { return ((IDataRenderer)parent).getYOffset() + getLocation().y; } return getLocation().y; } /* * titleText--------------------------------------------------- */ private String titleText = null; public void setTitleText(String title) { this.titleText = title; } public String getTitleText() { return Text.processTags(titleText, resolver); } private String tooltip; @Override public void setToolTipText(String tip) { if (tip != null && tip.indexOf("%%") != -1) { tooltip = tip; } else if (!Utils.stringIsEmpty(tip)) { if (!Utils.stringContainsIgnoreCase(tip, "<html") || HtmlUtils.hasUsefulHtmlContent(tip)) { setToolTipTextImpl(tip); } } else { setToolTipTextImpl(null); } } /** * @param tip */ private void setToolTipTextImpl(String tip) { enclosedComponent.setToolTipText(tip); getViewport().setToolTipText(tip); super.setToolTipText(tip); } private boolean editState; public void setReadOnly(boolean b) { if (b && popup == null) return; if (b) { setEditable(false); editState = true; } else { setEditable(editState); } } public boolean isReadOnly() { return popup == null; } public boolean isEditable() { return !isReadOnly(); } public void setComponentEnabled(final boolean b) { if (accessible || !b) { super.setEnabled(b); if (labels != null) { for (int i = 0; i < labels.size(); i++) { ILabel label = labels.get(i); label.setComponentEnabled(b); } } } } private boolean accessible = true; private ArrayList<ILabel> labels; public void setAccessible(boolean b) { if (!b) setComponentEnabled(b); accessible = b; } private boolean viewable = true; public void setViewable(boolean b) { if (!b) setComponentVisible(b); this.viewable = b; } public boolean isViewable() { return viewable; } @Override public void setOpaque(boolean b) { if (enclosedComponent != null) enclosedComponent.setOpaque(b); getViewport().setOpaque(b); super.setOpaque(b); } public void setComponentVisible(boolean b_visible) { if (viewable || !b_visible) { setVisible(b_visible); } } @Override public void setVisible(boolean flag) { super.setVisible(flag); if (labels != null) { for (int i = 0; i < labels.size(); i++) { ILabel label = labels.get(i); label.setComponentVisible(flag); } } } public void addLabelFor(ILabel label) { if (labels == null) labels = new ArrayList(3); labels.add(label); } public String getId() { return (String)getClientProperty("Id"); } @Override public void setTransferHandler(TransferHandler newHandler) { super.setTransferHandler(newHandler); if (newHandler == null) setDropTarget(null); } }