/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.mantle.client.solutionbrowser.filelist;
import com.google.gwt.event.dom.client.HasAllMouseHandlers;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import org.pentaho.gwt.widgets.client.filechooser.RepositoryFile;
import org.pentaho.gwt.widgets.client.utils.ElementUtils;
import org.pentaho.mantle.client.images.ImageUtil;
import org.pentaho.mantle.client.solutionbrowser.FileTypeEnabledOptions;
import org.pentaho.mantle.client.solutionbrowser.IFileSummary;
import org.pentaho.mantle.client.solutionbrowser.MantlePopupPanel;
import org.pentaho.mantle.client.solutionbrowser.SolutionBrowserPanel;
import org.pentaho.mantle.client.solutionbrowser.filelist.FileCommand.COMMAND;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
public class FileItem extends FlexTable implements HasAllMouseHandlers, IFileSummary {
public static final String ANALYSIS_VIEW_SUFFIX = ".analysisview.xaction"; //$NON-NLS-1$
public static final String XACTION_SUFFIX = ".xaction"; //$NON-NLS-1$
public static final String URL_SUFFIX = ".url"; //$NON-NLS-1$
// by creating a single popupMenu, we're reducing total # of widgets used
// and we can be sure to hide any existing ones by calling hide
static PopupPanel popupMenu = new MantlePopupPanel( true );
private Label fileLabel = new Label();
private FilesListPanel filesListPanel;
private RepositoryFile repositoryFile;
private ArrayList<IFileItemListener> listeners = new ArrayList<IFileItemListener>();
private FileTypeEnabledOptions options;
private String url;
private String iconStr;
private Image dropIndicator = ImageUtil.getThemeableImage( "icon-small", "icon-drop-invalid" );
private boolean canDrop = false;
public FileItem( RepositoryFile repositoryFile, FilesListPanel filesListPanel, FileTypeEnabledOptions options,
boolean supportsACLs, String fileIconStr ) {
this.filesListPanel = filesListPanel;
this.iconStr = fileIconStr;
sinkEvents( Event.ONCLICK | Event.ONDBLCLICK | Event.ONMOUSEUP );
DOM.setElementAttribute( getElement(), "oncontextmenu", "return false;" ); //$NON-NLS-1$ //$NON-NLS-2$
DOM.setElementAttribute( popupMenu.getElement(), "oncontextmenu", "return false;" ); //$NON-NLS-1$ //$NON-NLS-2$
fileLabel.setWordWrap( false );
fileLabel.setText( repositoryFile.getTitle() );
String description = repositoryFile.getDescription();
if ( description == null ) {
description = repositoryFile.getTitle();
}
fileLabel.setTitle( description );
if ( repositoryFile.isHidden() ) {
setStyleName( "hiddenFileLabel" ); //$NON-NLS-1$
} else {
setStyleName( "fileLabel" ); //$NON-NLS-1$
}
setCellPadding( 0 );
setCellSpacing( 0 );
ElementUtils.preventTextSelection( fileLabel.getElement() );
String name = repositoryFile.getName();
Image fileIcon = new Image();
if ( fileIconStr != null ) {
fileIcon.setUrl( fileIconStr );
} else if ( name.endsWith( ANALYSIS_VIEW_SUFFIX ) ) {
fileIcon = ImageUtil.getThemeableImage( "icon-small", "icon-analysis" );
} else if ( name.endsWith( XACTION_SUFFIX ) ) {
fileIcon = ImageUtil.getThemeableImage( "icon-small", "icon-xaction" );
} else if ( name.endsWith( URL_SUFFIX ) ) {
fileIcon = ImageUtil.getThemeableImage( "icon-small", "icon-url" );
} else {
fileIcon = ImageUtil.getThemeableImage( "icon-small", "icon-file" );
}
fileIcon.setWidth( "16px" ); //$NON-NLS-1$
fileLabel.setWidth( "100%" ); //$NON-NLS-1$
setWidget( 0, 0, fileIcon );
getCellFormatter().setWidth( 0, 0, "16px" ); //$NON-NLS-1$
setWidget( 0, 1, fileLabel );
getCellFormatter().setWidth( 0, 1, "100%" ); //$NON-NLS-1$
this.options = options;
this.repositoryFile = repositoryFile;
}
public void select() {
if ( filesListPanel.getSelectedFileItems().contains( this ) ) {
return;
} else {
if ( this.getStyleName().equalsIgnoreCase( "fileLabelCut" ) ) {
this.setStyleName( "fileLabelCutSelected" );
} else {
if ( repositoryFile.isHidden() ) {
this.setStyleName( "hiddenFileLabelSelected" ); //$NON-NLS-1$
} else {
this.setStyleName( "fileLabelSelected" ); //$NON-NLS-1$
}
}
filesListPanel.getSelectedFileItems().add( this ); // and add it to the list of selected files.
}
}
public void deselect() {
if ( !filesListPanel.getSelectedFileItems().contains( this ) ) {
return;
} else {
if ( this.getStyleName().equalsIgnoreCase( "fileLabelCutSelected" ) ) {
this.setStyleName( "fileLabelCut" );
} else {
if ( repositoryFile.isHidden() ) {
this.setStyleName( "hiddenFileLabel" ); //$NON-NLS-1$
} else {
this.setStyleName( "fileLabel" ); //$NON-NLS-1$
}
}
filesListPanel.getSelectedFileItems().remove( this ); // Remove it from the selected list
}
}
public void toggleSelect( Boolean addSelection, Boolean extendSelection ) {
if ( extendSelection ) {
extendSelection();
return;
}
if ( addSelection ) {
Boolean isSelected = filesListPanel.getSelectedFileItems().contains( this );
if ( isSelected ) { // then toggle it to not selected
deselect();
} else {
select();
}
} else {
for ( FileItem fileItem : filesListPanel.getAllFileItems() ) { // Set all the file Items to a unselected
// style
fileItem.deselect();
}
filesListPanel.getSelectedFileItems().clear(); // Remove all the files from the selected list
select();
}
}
private void extendSelection() {
if ( filesListPanel.getSelectedFileItems() == null
|| filesListPanel.getSelectedFileItems().size() < 1 ) { // nothing is selected so do a simple select
toggleSelect( false, false );
} else {
int currentItemIndex = filesListPanel.getFileItemIndex( this );
int maxSelectedIndex = -1;
int minSelectedIndex = filesListPanel.getFileCount() - 1;
for ( int i = 0; i < filesListPanel.getSelectedFileItems().size(); i++ ) {
FileItem testItem = filesListPanel.getSelectedFileItems().get( i );
int textIdx = filesListPanel.getFileItemIndex( testItem );
maxSelectedIndex = Math.max( maxSelectedIndex, textIdx );
minSelectedIndex = Math.min( minSelectedIndex, textIdx );
}
boolean forwardSelect = currentItemIndex > maxSelectedIndex;
int startIdx;
int endIdx;
if ( forwardSelect ) {
startIdx = maxSelectedIndex + 1;
endIdx = currentItemIndex;
} else {
startIdx = currentItemIndex;
endIdx = minSelectedIndex - 1;
}
for ( int i = startIdx; i <= endIdx; i++ ) {
filesListPanel.getFileItem( i ).toggleSelect( true, false );
}
}
}
public void onBrowserEvent( Event event ) {
Boolean metaKeyDown = DOM.eventGetMetaKey( event ) || DOM.eventGetCtrlKey( event );
Boolean shiftKeyDown = DOM.eventGetShiftKey( event );
if ( ( DOM.eventGetType( event ) & Event.ONDBLCLICK ) == Event.ONDBLCLICK ) {
toggleSelect( false, false );
FileItem selectedFileItem = filesListPanel.getSelectedFileItems().get( 0 );
if ( !selectedFileItem.isInTrash() ) {
SolutionBrowserPanel.getInstance().openFile(
filesListPanel.getSelectedFileItems().get( 0 ).getRepositoryFile(), COMMAND.RUN );
}
} else if ( ( DOM.eventGetType( event ) & Event.ONCLICK ) == Event.ONCLICK ) {
toggleSelect( metaKeyDown, shiftKeyDown );
fireFileSelectionEvent();
}
super.onBrowserEvent( event );
}
public boolean isCommandEnabled( COMMAND command, HashMap<String, String> metadataPerms ) {
return options != null && options.isCommandEnabled( command, metadataPerms );
}
public String getName() {
return this.repositoryFile.getName();
}
public void setName( String name ) {
this.repositoryFile.setName( name );
}
public Date getLastModifiedDate() {
return this.repositoryFile.getLastModifiedDate();
}
public void setLastModifiedDate( Date lastModifiedDate ) {
this.repositoryFile.setLastModifiedDate( lastModifiedDate );
}
// TODO LocalizedName and NonLocalizedName is the same. Do we need this extra method in there
public String getLocalizedName() {
return repositoryFile.getTitle();
}
public void setLocalizedName( String localizedName ) {
this.repositoryFile.setTitle( localizedName );
}
public RepositoryFile getRepositoryFile() {
return repositoryFile;
}
public void setRepositoryFile( RepositoryFile repositoryFile ) {
this.repositoryFile = repositoryFile;
}
public void fireFileSelectionEvent() {
for ( IFileItemListener listener : listeners ) {
listener.itemSelected( this );
}
}
public void addFileSelectionChangedListener( IFileItemListener listener ) {
listeners.add( listener );
}
public void removeFileSelectionChangedListener( IFileItemListener listener ) {
listeners.remove( listener );
}
public String getPath() {
return this.repositoryFile.getPath();
}
public String getURL() {
return url;
}
public void setURL( String url ) {
this.url = url;
}
public String getIcon() {
return this.iconStr;
}
/**
* DND required methods below
*/
public HandlerRegistration addMouseUpHandler( MouseUpHandler handler ) {
return addDomHandler( handler, MouseUpEvent.getType() );
}
public HandlerRegistration addMouseOutHandler( MouseOutHandler handler ) {
return addDomHandler( handler, MouseOutEvent.getType() );
}
public HandlerRegistration addMouseMoveHandler( MouseMoveHandler handler ) {
return addDomHandler( handler, MouseMoveEvent.getType() );
}
public HandlerRegistration addMouseWheelHandler( MouseWheelHandler handler ) {
return addDomHandler( handler, MouseWheelEvent.getType() );
}
public HandlerRegistration addMouseOverHandler( MouseOverHandler handler ) {
return addDomHandler( handler, MouseOverEvent.getType() );
}
public HandlerRegistration addMouseDownHandler( MouseDownHandler handler ) {
return addDomHandler( handler, MouseDownEvent.getType() );
}
public FileItem makeDragProxy() {
FileItem f = new FileItem( getRepositoryFile(), filesListPanel, options, false, getIcon() );
f.enableDrag();
return f;
}
public void enableDrag() {
setWidget( 0, 0, dropIndicator );
addStyleName( "fileItemDragProxy" ); //$NON-NLS-1$
setDroppable( false );
dropIndicator.removeStyleName( "icon-drop-valid" );
dropIndicator.addStyleName( "icon-drop-invalid" );
}
public void setDroppable( boolean canDrop ) {
if ( this.canDrop == canDrop ) {
return;
}
if ( canDrop ) {
dropIndicator.addStyleName( "icon-drop-valid" );
dropIndicator.removeStyleName( "icon-drop-invalid" );
addStyleName( "validDrop" ); //$NON-NLS-1$
} else {
dropIndicator.removeStyleName( "icon-drop-valid" );
dropIndicator.addStyleName( "icon-drop-invalid" );
removeStyleName( "validDrop" ); //$NON-NLS-1$
}
this.canDrop = canDrop;
}
public boolean isInTrash() {
return repositoryFile.getPath().contains( "/.trash/pho:" );
}
}