/*
* 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) 2006 - 2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.openformula.ui.util;
import org.pentaho.openformula.ui.ParameterUpdateEvent;
import org.pentaho.openformula.ui.model2.FormulaSemicolonElement;
import org.pentaho.openformula.ui.model2.FunctionInformation;
import org.pentaho.reporting.libraries.base.util.StringUtils;
public class FunctionParameterEditHelper {
public static class EditResult {
public final String text;
public final int caretPositionAfterEdit;
private EditResult( final String text, final int caretPositionAfterEdit ) {
this.text = text;
this.caretPositionAfterEdit = caretPositionAfterEdit;
}
}
public static EditResult buildFormulaText( final ParameterUpdateEvent event,
final FunctionInformation fn,
final String formula ) {
// The parameter index corresponds to the individual parameter text-fields
final int globalParameterIndex = event.getParameter();
// special case: Replace the complete formula
if ( globalParameterIndex == -1 ) {
return performGlobalReplace( fn, formula, event );
}
// Special case 2: If the event adds a parameter beyond the defined parameter count, then we insert empty
// parameter values as needed to fit the gap.
if ( globalParameterIndex >= fn.getParameterCount() ) {
return performAppendParameter( fn, formula, event );
}
// The text entered in a parameter field
final String parameterText = event.getText();
// insert an parameter somewhere in the middle.
if ( event.isCatchAllParameter() == false ) {
final int start = fn.getParamStart( globalParameterIndex );
final int end = fn.getParamEnd( globalParameterIndex );
final StringBuilder formulaText = new StringBuilder( formula );
formulaText.delete( start, end );
formulaText.insert( start, parameterText );
return new EditResult( formulaText.toString(), start + parameterText.length() );
}
final int start = fn.getParamStart( globalParameterIndex );
boolean canClearEmpty = true;
int paramIdx = globalParameterIndex + 1;
while ( paramIdx < fn.getParameterCount() ) {
final String paramText = fn.getParameterText( paramIdx );
if ( StringUtils.isEmpty( paramText, true ) == false ) {
canClearEmpty = false;
}
paramIdx += 1;
}
final int end;
if ( canClearEmpty ) {
end = fn.getParamEnd( paramIdx - 1 );
} else {
end = fn.getParamEnd( globalParameterIndex );
}
final StringBuilder formulaText = new StringBuilder( formula );
formulaText.delete( start, end );
formulaText.insert( start, parameterText );
return new EditResult( formulaText.toString(), start + parameterText.length() );
}
private static EditResult performAppendParameter( final FunctionInformation fn,
final String formula,
final ParameterUpdateEvent event ) {
// The parameter index corresponds to the individual parameter text-fields
final int globalParameterIndex = event.getParameter();
// The text entered in a parameter field
final String parameterText = event.getText();
// In case the parameter is empty, we do NOT generate dummy values. This produces cleaner
// formulas with infinite parameters.
if ( StringUtils.isEmpty( parameterText ) ) {
return new EditResult( formula, fn.getParamEnd( fn.getParameterCount() - 1 ) );
}
final int functionParameterCount = fn.getParameterCount();
// Build the formula text. Remove the old text and inject the new text in it's place
final StringBuilder formulaText = new StringBuilder( formula );
int start = fn.getParamEnd( functionParameterCount - 1 );
for ( int i = functionParameterCount; i <= globalParameterIndex; i += 1 ) {
formulaText.insert( start, FormulaSemicolonElement.ELEMENT );
start += 1;
}
formulaText.insert( start, parameterText );
return new EditResult( formulaText.toString(), start + parameterText.length() );
}
private static EditResult performGlobalReplace( final FunctionInformation fn,
final String formula,
final ParameterUpdateEvent event ) {
final String parameterText = event.getText();
final int start = fn.getFunctionOffset();
final int end = fn.getFunctionParameterEnd();
// Build the formula text. Remove the old text and inject the new text in it's place
final StringBuilder formulaText = new StringBuilder( formula );
formulaText.delete( start, end );
formulaText.insert( start, parameterText );
return new EditResult( formulaText.toString(), start + parameterText.length() );
}
}