/*!
* 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-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.designer.core.editor;
import org.pentaho.reporting.designer.core.ReportDesignerContext;
import org.pentaho.reporting.designer.core.ReportDesignerDocumentContext;
import org.pentaho.reporting.designer.core.ReportDesignerView;
import org.pentaho.reporting.designer.core.actions.global.PasteAction;
import org.pentaho.reporting.designer.core.actions.report.AddDataFactoryAction;
import org.pentaho.reporting.designer.core.editor.structuretree.ReportFunctionNode;
import org.pentaho.reporting.designer.core.editor.structuretree.ReportParametersNode;
import org.pentaho.reporting.designer.core.editor.structuretree.ReportQueryNode;
import org.pentaho.reporting.designer.core.editor.structuretree.SubReportParametersNode;
import org.pentaho.reporting.designer.core.settings.WorkspaceSettings;
import org.pentaho.reporting.engine.classic.core.Band;
import org.pentaho.reporting.engine.classic.core.CompoundDataFactory;
import org.pentaho.reporting.engine.classic.core.CrosstabCellBody;
import org.pentaho.reporting.engine.classic.core.CrosstabColumnGroup;
import org.pentaho.reporting.engine.classic.core.CrosstabElement;
import org.pentaho.reporting.engine.classic.core.CrosstabGroup;
import org.pentaho.reporting.engine.classic.core.CrosstabOtherGroup;
import org.pentaho.reporting.engine.classic.core.CrosstabRowGroup;
import org.pentaho.reporting.engine.classic.core.DataFactory;
import org.pentaho.reporting.engine.classic.core.Element;
import org.pentaho.reporting.engine.classic.core.Group;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.RelationalGroup;
import org.pentaho.reporting.engine.classic.core.RootLevelBand;
import org.pentaho.reporting.engine.classic.core.SubReport;
import org.pentaho.reporting.engine.classic.core.function.Expression;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryMetaData;
import org.pentaho.reporting.engine.classic.core.metadata.DataFactoryRegistry;
import org.pentaho.reporting.engine.classic.core.metadata.GroupedMetaDataComparator;
import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry;
import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.MenuElement;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
public class ContextMenuUtility {
private ContextMenuUtility() {
}
public static JPopupMenu getMenu( final ReportDesignerContext context, final Object selectedElement ) {
ReportDesignerView view = context.getView();
if ( selectedElement == null || selectedElement instanceof MasterReport ) { // This check assumes that we've click on a report band see JIRA
// PRD-1076
return view.getPopupMenu( "popup-ReportDefinition" ); // NON-NLS
}
final ReportDesignerDocumentContext activeContext = context.getActiveContext();
ReportRenderContext doc = null;
if ( activeContext instanceof ReportRenderContext ) {
doc = (ReportRenderContext) activeContext;
if ( selectedElement == doc.getReportDefinition() ) {
if ( selectedElement instanceof CrosstabElement ) {
return view.getPopupMenu( "popup-CrosstabElement" ); // NON-NLS
}
return view.getPopupMenu( "popup-ReportDefinition" ); // NON-NLS
}
}
if ( selectedElement instanceof SubReport ) {
return view.getPopupMenu( "popup-SubReport" ); // NON-NLS
}
if ( selectedElement instanceof CompoundDataFactory ) {
return createDataSourcePopup( context );
}
if ( selectedElement instanceof DataFactory ) {
return view.getPopupMenu( "popup-DataSource" ); // NON-NLS
}
if ( selectedElement instanceof ReportFunctionNode ) {
return view.getPopupMenu( "popup-Expressions" ); // NON-NLS
}
if ( selectedElement instanceof ReportQueryNode ) {
final ReportQueryNode rqn = (ReportQueryNode) selectedElement;
JPopupMenu popupMenu;
if ( rqn.isAllowEdit() ) {
popupMenu = view.getPopupMenu( "popup-Query" ); // NON-NLS
} else {
popupMenu = view.getPopupMenu( "popup-Inherited-Query" ); // NON-NLS
}
final MenuElement activationItem = popupMenu.getSubElements()[0];
toggleActivationItem( doc, rqn, activationItem );
return popupMenu;
}
if ( selectedElement instanceof Expression ) {
return view.getPopupMenu( "popup-Expression" ); // NON-NLS
}
if ( selectedElement instanceof RootLevelBand ) {
return view.getPopupMenu( "popup-RootLevelBand" ); // NON-NLS
}
if ( selectedElement instanceof RelationalGroup ) {
return view.getPopupMenu( "popup-RelationalGroup" ); // NON-NLS
}
if ( selectedElement instanceof CrosstabGroup ) {
return view.getPopupMenu( "popup-CrosstabGroup" ); // NON-NLS
}
if ( selectedElement instanceof CrosstabOtherGroup ) {
return view.getPopupMenu( "popup-CrosstabOtherGroup" ); // NON-NLS
}
if ( selectedElement instanceof CrosstabRowGroup ) {
return view.getPopupMenu( "popup-CrosstabRowGroup" ); // NON-NLS
}
if ( selectedElement instanceof CrosstabColumnGroup ) {
return view.getPopupMenu( "popup-CrosstabColumnGroup" ); // NON-NLS
}
if ( selectedElement instanceof CrosstabCellBody ) {
return view.getPopupMenu( "popup-CrosstabCellBody" ); // NON-NLS
}
if ( selectedElement instanceof Group ) {
return view.getPopupMenu( "popup-Group" ); // NON-NLS
}
if ( selectedElement instanceof Band ) {
return view.getPopupMenu( "popup-Band" ); // NON-NLS
}
if ( selectedElement instanceof Element ) {
final Element element = (Element) selectedElement;
final JPopupMenu popup = view.getPopupMenu( "popup-" + element.getElementTypeName() ); // NON-NLS
if ( popup != null ) {
return popup;
}
return view.getPopupMenu( "popup-Element" ); // NON-NLS
}
if ( selectedElement instanceof ReportParameterDefinition ) {
return view.getPopupMenu( "popup-Parameters" ); // NON-NLS
}
if ( selectedElement instanceof ParameterDefinitionEntry ) {
return view.getPopupMenu( "popup-Parameter" ); // NON-NLS
}
if ( selectedElement instanceof ReportParametersNode ) {
return view.getPopupMenu( "popup-Parameters" ); // NON-NLS
}
if ( selectedElement instanceof SubReportParametersNode ) {
return view.getPopupMenu( "popup-SubReportParameters" ); // NON-NLS
}
return null;
}
public static JPopupMenu createDataSourcePopup( final ReportDesignerContext designerContext ) {
final JPopupMenu insertDataSourcesMenu = new JPopupMenu();
final PasteAction action = new PasteAction();
action.setReportDesignerContext( designerContext );
insertDataSourcesMenu.add( action );
insertDataSourcesMenu.addSeparator();
createDataSourceMenu( designerContext, insertDataSourcesMenu );
return insertDataSourcesMenu;
}
public static void createDataSourceMenu( final ReportDesignerContext designerContext,
final JComponent insertDataSourcesMenu ) {
JMenu subMenu = null;
final Map<String, Boolean> groupingMap = new HashMap<>();
final DataFactoryMetaData[] datas = DataFactoryRegistry.getInstance().getAll();
for ( int i = 0; i < datas.length; i++ ) {
final DataFactoryMetaData data = datas[i];
if ( data.isHidden() ) {
continue;
}
if ( !WorkspaceSettings.getInstance().isVisible( data ) ) {
continue;
}
if ( data.isEditorAvailable() == false ) {
continue;
}
final String currentGrouping = data.getGrouping( Locale.getDefault() );
groupingMap.put( currentGrouping, groupingMap.containsKey( currentGrouping ) );
}
Arrays.sort( datas, new GroupedMetaDataComparator() );
Object grouping = null;
boolean firstElement = true;
for ( int i = 0; i < datas.length; i++ ) {
final DataFactoryMetaData data = datas[i];
if ( data.isHidden() ) {
continue;
}
if ( !WorkspaceSettings.getInstance().isVisible( data ) ) {
continue;
}
if ( data.isEditorAvailable() == false ) {
continue;
}
final String currentGrouping = data.getGrouping( Locale.getDefault() );
final boolean isMultiGrouping = groupingMap.get( currentGrouping );
if ( firstElement == false ) {
if ( ObjectUtilities.equal( currentGrouping, grouping ) == false ) {
grouping = currentGrouping;
if ( isMultiGrouping ) {
subMenu = new JMenu( currentGrouping );
insertDataSourcesMenu.add( subMenu );
}
}
} else {
firstElement = false;
grouping = currentGrouping;
if ( isMultiGrouping ) {
subMenu = new JMenu( currentGrouping );
insertDataSourcesMenu.add( subMenu );
}
}
final AddDataFactoryAction action = new AddDataFactoryAction( data );
action.setReportDesignerContext( designerContext );
if ( isMultiGrouping ) {
//noinspection ConstantConditions
subMenu.add( new JMenuItem( action ) );
} else {
insertDataSourcesMenu.add( new JMenuItem( action ) );
}
}
}
protected static void toggleActivationItem( final ReportRenderContext doc,
final ReportQueryNode rqn,
final MenuElement activationItem ) {
if ( activationItem instanceof JMenuItem && doc != null ) {
final DataFactory dataFactory = doc.getContextRoot().getDataFactory();
boolean disabled = false;
if ( dataFactory instanceof CompoundDataFactory ) {
final CompoundDataFactory compound = (CompoundDataFactory) dataFactory;
int count = countQueriesWithName( rqn.getQueryName(), compound );
disabled = count > 1;
}
if ( disabled ) {
( (JMenuItem) activationItem ).setEnabled( false );
} else {
( (JMenuItem) activationItem ).setEnabled( true );
}
}
}
private static int countQueriesWithName( final String queryName, final CompoundDataFactory compound ) {
int count = 0;
if ( compound.size() > 1 ) {
for ( int i = 0; i < compound.size(); i++ ) {
final DataFactory innerFactory = compound.get( i );
final String[] queryNames = innerFactory.getQueryNames();
for ( int j = 0; j < queryNames.length; j++ ) {
if ( ObjectUtilities.equal( queryName, queryNames[j] ) ) {
count++;
break;
}
}
}
}
return count;
}
}