Added repeat and repeatCount options for text transform operation. This lets us fix those & repeated encoding problems easily.
git-svn-id: http://google-refine.googlecode.com/svn/trunk@179 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
b4d2cef526
commit
2fe8f98e4e
@ -17,11 +17,22 @@ public class DoTextTransformCommand extends EngineDependentCommand {
|
|||||||
String columnName = request.getParameter("columnName");
|
String columnName = request.getParameter("columnName");
|
||||||
String expression = request.getParameter("expression");
|
String expression = request.getParameter("expression");
|
||||||
String onError = request.getParameter("onError");
|
String onError = request.getParameter("onError");
|
||||||
|
boolean repeat = "true".equals(request.getParameter("repeat"));
|
||||||
|
|
||||||
|
int repeatCount = 10;
|
||||||
|
String repeatCountString = request.getParameter("repeatCount");
|
||||||
|
try {
|
||||||
|
repeatCount = Math.max(Math.min(Integer.parseInt(repeatCountString), 10), 0);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
return new TextTransformOperation(
|
return new TextTransformOperation(
|
||||||
engineConfig,
|
engineConfig,
|
||||||
columnName,
|
columnName,
|
||||||
expression,
|
expression,
|
||||||
TextTransformOperation.stringToOnError(onError));
|
TextTransformOperation.stringToOnError(onError),
|
||||||
|
repeat,
|
||||||
|
repeatCount
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,10 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
|
|||||||
StoreError
|
StoreError
|
||||||
}
|
}
|
||||||
|
|
||||||
final protected String _expression;
|
final protected String _expression;
|
||||||
final protected OnError _onError;
|
final protected OnError _onError;
|
||||||
|
final protected boolean _repeat;
|
||||||
|
final protected int _repeatCount;
|
||||||
|
|
||||||
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
|
static public AbstractOperation reconstruct(Project project, JSONObject obj) throws Exception {
|
||||||
JSONObject engineConfig = obj.getJSONObject("engineConfig");
|
JSONObject engineConfig = obj.getJSONObject("engineConfig");
|
||||||
@ -37,7 +39,9 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
|
|||||||
engineConfig,
|
engineConfig,
|
||||||
obj.getString("columnName"),
|
obj.getString("columnName"),
|
||||||
obj.getString("expression"),
|
obj.getString("expression"),
|
||||||
stringToOnError(obj.getString("onError"))
|
stringToOnError(obj.getString("onError")),
|
||||||
|
obj.getBoolean("repeat"),
|
||||||
|
obj.getInt("repeatCount")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,10 +64,19 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextTransformOperation(JSONObject engineConfig, String columnName, String expression, OnError onError) {
|
public TextTransformOperation(
|
||||||
|
JSONObject engineConfig,
|
||||||
|
String columnName,
|
||||||
|
String expression,
|
||||||
|
OnError onError,
|
||||||
|
boolean repeat,
|
||||||
|
int repeatCount
|
||||||
|
) {
|
||||||
super(engineConfig, columnName, true);
|
super(engineConfig, columnName, true);
|
||||||
_expression = expression;
|
_expression = expression;
|
||||||
_onError = onError;
|
_onError = onError;
|
||||||
|
_repeat = repeat;
|
||||||
|
_repeatCount = repeatCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(JSONWriter writer, Properties options)
|
public void write(JSONWriter writer, Properties options)
|
||||||
@ -76,6 +89,8 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
|
|||||||
writer.key("columnName"); writer.value(_columnName);
|
writer.key("columnName"); writer.value(_columnName);
|
||||||
writer.key("expression"); writer.value(_expression);
|
writer.key("expression"); writer.value(_expression);
|
||||||
writer.key("onError"); writer.value(onErrorToString(_onError));
|
writer.key("onError"); writer.value(onErrorToString(_onError));
|
||||||
|
writer.key("repeat"); writer.value(_repeat);
|
||||||
|
writer.key("repeatCount"); writer.value(_repeatCount);
|
||||||
writer.endObject();
|
writer.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,6 +142,21 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
|
|||||||
|
|
||||||
if (!ExpressionUtils.sameValue(oldValue, newValue)) {
|
if (!ExpressionUtils.sameValue(oldValue, newValue)) {
|
||||||
Cell newCell = new Cell(newValue, (cell != null) ? cell.recon : null);
|
Cell newCell = new Cell(newValue, (cell != null) ? cell.recon : null);
|
||||||
|
|
||||||
|
if (_repeat) {
|
||||||
|
for (int i = 0; i < _repeatCount; i++) {
|
||||||
|
ExpressionUtils.bind(bindings, row, rowIndex, newCell);
|
||||||
|
|
||||||
|
newValue = eval.evaluate(bindings);
|
||||||
|
if (ExpressionUtils.isError(newValue)) {
|
||||||
|
break;
|
||||||
|
} else if (ExpressionUtils.sameValue(newCell.value, newValue)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
newCell = new Cell(newValue, newCell.recon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CellChange cellChange = new CellChange(rowIndex, cellIndex, cell, newCell);
|
CellChange cellChange = new CellChange(rowIndex, cellIndex, cell, newCell);
|
||||||
cellChanges.add(cellChange);
|
cellChanges.add(cellChange);
|
||||||
|
@ -32,7 +32,7 @@ function ExpressionPreviewDialog(title, cellIndex, rowIndices, values, expressio
|
|||||||
};
|
};
|
||||||
|
|
||||||
ExpressionPreviewDialog.generateWidgetHtml = function() {
|
ExpressionPreviewDialog.generateWidgetHtml = function() {
|
||||||
return '<table class="expression-preview-layout">' +
|
return '<table class="expression-preview-layout" rows="4" cols="2">' +
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td>Expression</td>' +
|
'<td>Expression</td>' +
|
||||||
'<td>Language</td>' +
|
'<td>Language</td>' +
|
||||||
@ -48,7 +48,7 @@ ExpressionPreviewDialog.generateWidgetHtml = function() {
|
|||||||
'</td>' +
|
'</td>' +
|
||||||
'</tr>' +
|
'</tr>' +
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td class="expression-preview-error-container" bind="expressionPreviewErrorContainer" width="150"></td>' +
|
'<td class="expression-preview-error-container" bind="expressionPreviewErrorContainer" width="150" style="vertical-align: top;"></td>' +
|
||||||
'</tr>' +
|
'</tr>' +
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td colspan="2">' +
|
'<td colspan="2">' +
|
||||||
@ -61,7 +61,7 @@ ExpressionPreviewDialog.generateWidgetHtml = function() {
|
|||||||
'<div id="expression-preview-tabs-preview">' +
|
'<div id="expression-preview-tabs-preview">' +
|
||||||
'<div class="expression-preview-container" bind="expressionPreviewPreviewContainer"></div>' +
|
'<div class="expression-preview-container" bind="expressionPreviewPreviewContainer"></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="expression-preview-tabs-history">' +
|
'<div id="expression-preview-tabs-history" style="display: none;">' +
|
||||||
'<div class="expression-preview-container" bind="expressionPreviewHistoryContainer"></div>' +
|
'<div class="expression-preview-container" bind="expressionPreviewHistoryContainer"></div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div id="expression-preview-tabs-help" style="display: none;">' +
|
'<div id="expression-preview-tabs-help" style="display: none;">' +
|
||||||
@ -90,7 +90,7 @@ ExpressionPreviewDialog.Widget = function(
|
|||||||
this._timerID = null;
|
this._timerID = null;
|
||||||
|
|
||||||
$("#expression-preview-tabs").tabs();
|
$("#expression-preview-tabs").tabs();
|
||||||
$("#expression-preview-tabs-preview").css("display", "");
|
$("#expression-preview-tabs-history").css("display", "");
|
||||||
$("#expression-preview-tabs-help").css("display", "");
|
$("#expression-preview-tabs-help").css("display", "");
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
@ -59,15 +59,15 @@ DataTableColumnHeaderUI.prototype._createMenuForColumnHeader = function(elmt) {
|
|||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: "To Titlecase",
|
label: "To Titlecase",
|
||||||
click: function() { self._doTextTransform("toTitlecase(value)", "store-blank"); }
|
click: function() { self._doTextTransform("toTitlecase(value)", "store-blank", false, ""); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "To Uppercase",
|
label: "To Uppercase",
|
||||||
click: function() { self._doTextTransform("toUppercase(value)", "store-blank"); }
|
click: function() { self._doTextTransform("toUppercase(value)", "store-blank", false, ""); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "To Lowercase",
|
label: "To Lowercase",
|
||||||
click: function() { self._doTextTransform("toLowercase(value)", "store-blank"); }
|
click: function() { self._doTextTransform("toLowercase(value)", "store-blank", false, ""); }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Custom Transform ...",
|
label: "Custom Transform ...",
|
||||||
@ -399,10 +399,16 @@ DataTableColumnHeaderUI.prototype._doFilterByExpressionPrompt = function(express
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
DataTableColumnHeaderUI.prototype._doTextTransform = function(expression, onError) {
|
DataTableColumnHeaderUI.prototype._doTextTransform = function(expression, onError, repeat, repeatCount) {
|
||||||
Gridworks.postProcess(
|
Gridworks.postProcess(
|
||||||
"do-text-transform",
|
"do-text-transform",
|
||||||
{ columnName: this._column.headerLabel, expression: expression, onError: onError },
|
{
|
||||||
|
columnName: this._column.headerLabel,
|
||||||
|
expression: expression,
|
||||||
|
onError: onError,
|
||||||
|
repeat: repeat,
|
||||||
|
repeatCount: repeatCount
|
||||||
|
},
|
||||||
null,
|
null,
|
||||||
{ cellsChanged: true }
|
{ cellsChanged: true }
|
||||||
);
|
);
|
||||||
@ -417,24 +423,36 @@ DataTableColumnHeaderUI.prototype._doTextTransformPrompt = function() {
|
|||||||
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
|
var body = $('<div></div>').addClass("dialog-body").appendTo(frame);
|
||||||
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
|
var footer = $('<div></div>').addClass("dialog-footer").appendTo(frame);
|
||||||
|
|
||||||
body.html(ExpressionPreviewDialog.generateWidgetHtml());
|
body.html(
|
||||||
|
'<table class="expression-preview-layout">' +
|
||||||
|
'<tr>' +
|
||||||
|
'<td colspan="4">' + ExpressionPreviewDialog.generateWidgetHtml() + '</td>' +
|
||||||
|
'</tr>' +
|
||||||
|
'<tr style="white-space: pre;">' +
|
||||||
|
'<td width="1%">' +
|
||||||
|
'On error' +
|
||||||
|
'</td>' +
|
||||||
|
'<td>' +
|
||||||
|
'<input type="radio" name="text-transform-dialog-onerror-choice" value="set-to-blank" checked /> set to blank<br/>' +
|
||||||
|
'<input type="radio" name="text-transform-dialog-onerror-choice" value="store-error" /> store error<br/>' +
|
||||||
|
'<input type="radio" name="text-transform-dialog-onerror-choice" value="keep-original" /> keep original' +
|
||||||
|
'</td>' +
|
||||||
|
'<td width="1%">' +
|
||||||
|
'<input type="checkbox" bind="repeatCheckbox" />' +
|
||||||
|
'</td>' +
|
||||||
|
'<td>' +
|
||||||
|
'Re-transform until no change<br/>' +
|
||||||
|
'up to <input bind="repeatCountInput" value="10" size="3" /> times' +
|
||||||
|
'</td>' +
|
||||||
|
'</tr>' +
|
||||||
|
'</table>'
|
||||||
|
);
|
||||||
var bodyElmts = DOM.bind(body);
|
var bodyElmts = DOM.bind(body);
|
||||||
|
|
||||||
footer.html(
|
footer.html(
|
||||||
'<table class="expression-preview-layout">' +
|
'<button bind="okButton"> OK </button>' +
|
||||||
'<tr>' +
|
'<button bind="cancelButton">Cancel</button>'
|
||||||
'<td align="left">' +
|
);
|
||||||
'On error ' +
|
|
||||||
'<input type="radio" name="text-transform-dialog-onerror-choice" value="set-to-blank" checked /> set to blank ' +
|
|
||||||
'<input type="radio" name="text-transform-dialog-onerror-choice" value="store-error" /> store error ' +
|
|
||||||
'<input type="radio" name="text-transform-dialog-onerror-choice" value="keep-original" /> keep original' +
|
|
||||||
'</td>' +
|
|
||||||
'<td align="right">' +
|
|
||||||
'<button bind="okButton"> OK </button>' +
|
|
||||||
'<button bind="cancelButton">Cancel</button>' +
|
|
||||||
'</td>' +
|
|
||||||
'</tr>' +
|
|
||||||
'</table>');
|
|
||||||
var footerElmts = DOM.bind(footer);
|
var footerElmts = DOM.bind(footer);
|
||||||
|
|
||||||
var level = DialogSystem.showDialog(frame);
|
var level = DialogSystem.showDialog(frame);
|
||||||
@ -445,7 +463,9 @@ DataTableColumnHeaderUI.prototype._doTextTransformPrompt = function() {
|
|||||||
footerElmts.okButton.click(function() {
|
footerElmts.okButton.click(function() {
|
||||||
self._doTextTransform(
|
self._doTextTransform(
|
||||||
previewWidget.getExpression(true),
|
previewWidget.getExpression(true),
|
||||||
$('input[name="text-transform-dialog-onerror-choice"]:checked')[0].value
|
$('input[name="text-transform-dialog-onerror-choice"]:checked')[0].value,
|
||||||
|
bodyElmts.repeatCheckbox[0].checked,
|
||||||
|
bodyElmts.repeatCountInput[0].value
|
||||||
);
|
);
|
||||||
dismiss();
|
dismiss();
|
||||||
})
|
})
|
||||||
|
@ -14,7 +14,11 @@ table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tr, td {
|
tr, td {
|
||||||
vertical-align: top;
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header {
|
#header {
|
||||||
|
Loading…
Reference in New Issue
Block a user