Merge remote-tracking branch 'origin/GP-4162_dev747368_fix_viewstringstable_custom_constraints'

This commit is contained in:
Ryan Kurtz 2023-12-27 07:51:52 -05:00
commit a806848b31
8 changed files with 167 additions and 214 deletions

View file

@ -15,7 +15,7 @@
*/ */
package ghidra.app.plugin.core.string.translate; package ghidra.app.plugin.core.string.translate;
import java.util.*; import java.util.List;
import docking.ActionContext; import docking.ActionContext;
import docking.action.DockingAction; import docking.action.DockingAction;
@ -63,13 +63,11 @@ public abstract class AbstractTranslateAction extends DockingAction {
@Override @Override
public void actionPerformed(ActionContext context) { public void actionPerformed(ActionContext context) {
if (context instanceof DataLocationListContext) { if (context instanceof DataLocationListContext dllc) {
DataLocationListContext dataContext = (DataLocationListContext) context; actionPerformed(dllc.getProgram(), getStringLocations(dllc));
actionPerformed(dataContext.getProgram(), getStringLocations(dataContext));
} }
else if (context instanceof CodeViewerActionContext) { else if (context instanceof CodeViewerActionContext cvac) {
CodeViewerActionContext codeContext = (CodeViewerActionContext) context; actionPerformed(cvac.getProgram(), getStringLocations(cvac));
actionPerformed(codeContext.getProgram(), getStringLocations(codeContext));
} }
else { else {
throw new AssertException("This can't happen!"); throw new AssertException("This can't happen!");
@ -91,9 +89,9 @@ public abstract class AbstractTranslateAction extends DockingAction {
protected List<ProgramLocation> getStringLocations(CodeViewerActionContext context) { protected List<ProgramLocation> getStringLocations(CodeViewerActionContext context) {
Data data = DataUtilities.getDataAtLocation(context.getLocation()); Data data = DataUtilities.getDataAtLocation(context.getLocation());
if (data == null || !StringDataInstance.isString(data)) { if (data == null || !StringDataInstance.isString(data)) {
return Collections.emptyList(); return List.of();
} }
return Arrays.asList(context.getLocation()); return List.of(context.getLocation());
} }
protected List<ProgramLocation> getStringLocations(DataLocationListContext context) { protected List<ProgramLocation> getStringLocations(DataLocationListContext context) {

View file

@ -15,7 +15,7 @@
*/ */
package ghidra.app.plugin.core.string.translate; package ghidra.app.plugin.core.string.translate;
import static ghidra.program.model.data.TranslationSettingsDefinition.TRANSLATION; import static ghidra.program.model.data.TranslationSettingsDefinition.*;
import java.util.List; import java.util.List;
@ -64,6 +64,7 @@ public class ClearTranslationAction extends AbstractTranslateAction {
monitor.initialize(dataLocations.size()); monitor.initialize(dataLocations.size());
for (ProgramLocation progLoc : dataLocations) { for (ProgramLocation progLoc : dataLocations) {
Data data = DataUtilities.getDataAtLocation(progLoc); Data data = DataUtilities.getDataAtLocation(progLoc);
TRANSLATION.setTranslatedValue(data, null);
TRANSLATION.clear(data); TRANSLATION.clear(data);
} }
} }

View file

@ -1,29 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.strings;
import docking.widgets.table.constraint.ColumnTypeMapper;
import ghidra.program.model.data.StringDataInstance;
public class StringDataInstanceColumnTypeMapper
extends ColumnTypeMapper<StringDataInstance, String> {
@Override
public String convert(StringDataInstance value) {
return value.getStringValue();
}
}

View file

@ -15,32 +15,36 @@
*/ */
package ghidra.app.plugin.core.strings; package ghidra.app.plugin.core.strings;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Predicate; import java.util.function.Predicate;
import docking.DefaultActionContext; import docking.DefaultActionContext;
import ghidra.app.context.DataLocationListContext; import ghidra.app.context.DataLocationListContext;
import ghidra.program.model.data.DataUtilities;
import ghidra.program.model.listing.Data; import ghidra.program.model.listing.Data;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import ghidra.program.util.ProgramLocation; import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection;
import ghidra.util.table.GhidraTable; import ghidra.util.table.GhidraTable;
public class ViewStringsContext extends DefaultActionContext implements DataLocationListContext { public class ViewStringsContext extends DefaultActionContext implements DataLocationListContext {
private ViewStringsProvider viewStringsProvider; private final ViewStringsProvider viewStringsProvider;
private final GhidraTable table;
private final ViewStringsTableModel tableModel;
ViewStringsContext(ViewStringsProvider provider, GhidraTable stringsTable) { ViewStringsContext(ViewStringsProvider provider, GhidraTable table,
super(provider, stringsTable); ViewStringsTableModel tableModel) {
viewStringsProvider = provider; super(provider, table);
} this.viewStringsProvider = provider;
this.table = table;
GhidraTable getStringsTable() { this.tableModel = tableModel;
return (GhidraTable) getContextObject();
} }
@Override @Override
public int getCount() { public int getCount() {
return viewStringsProvider.getSelectedRowCount(); return table.getSelectedRowCount();
} }
@Override @Override
@ -50,11 +54,48 @@ public class ViewStringsContext extends DefaultActionContext implements DataLoca
@Override @Override
public List<ProgramLocation> getDataLocationList() { public List<ProgramLocation> getDataLocationList() {
return viewStringsProvider.getSelectedDataLocationList(null); return getDataLocationList(null);
} }
@Override @Override
public List<ProgramLocation> getDataLocationList(Predicate<Data> filter) { public List<ProgramLocation> getDataLocationList(Predicate<Data> filter) {
return viewStringsProvider.getSelectedDataLocationList(filter); List<ProgramLocation> result = new ArrayList<>();
int[] selectedRows = table.getSelectedRows();
for (int row : selectedRows) {
ProgramLocation location = tableModel.getRowObject(row);
Data data = DataUtilities.getDataAtLocation(location);
if (passesFilter(data, filter)) {
result.add(location);
} }
}
return result;
}
private boolean passesFilter(Data data, Predicate<Data> filter) {
if (data == null) {
return false;
}
if (filter == null) {
return true;
}
return filter.test(data);
}
ProgramSelection getProgramSelection() {
return table.getProgramSelection();
}
public int getSelectedRowCount() {
return table.getSelectedRowCount();
}
public Data getSelectedData() {
int selectedRow = table.getSelectedRow();
if (selectedRow < 0) {
return null;
}
ProgramLocation location = tableModel.getRowObject(selectedRow);
return DataUtilities.getDataAtLocation(location);
}
} }

View file

@ -17,8 +17,8 @@ package ghidra.app.plugin.core.strings;
import javax.swing.Icon; import javax.swing.Icon;
import docking.ActionContext; import docking.action.DockingAction;
import docking.action.*; import docking.action.builder.ActionBuilder;
import ghidra.app.CorePluginPackage; import ghidra.app.CorePluginPackage;
import ghidra.app.plugin.PluginCategoryNames; import ghidra.app.plugin.PluginCategoryNames;
import ghidra.app.plugin.ProgramPlugin; import ghidra.app.plugin.ProgramPlugin;
@ -86,40 +86,35 @@ public class ViewStringsPlugin extends ProgramPlugin implements DomainObjectList
} }
private void createActions() { private void createActions() {
refreshAction = new DockingAction("Refresh Strings", getName()) { refreshAction = new ActionBuilder("Refresh Strings", getName())
.toolBarIcon(REFRESH_NOT_NEEDED_ICON)
@Override .description("<html>Push at any time to refresh the current table of strings.<br>" +
public boolean isEnabledForContext(ActionContext context) { "This button is highlighted when the data <i>may</i> be stale.<br>")
return getCurrentProgram() != null; .enabledWhen(ac -> getCurrentProgram() != null)
} .onAction(ac -> {
refreshAction.getToolBarData().setIcon(REFRESH_NOT_NEEDED_ICON);
@Override
public void actionPerformed(ActionContext context) {
getToolBarData().setIcon(REFRESH_NOT_NEEDED_ICON);
reload(); reload();
} })
}; .helpLocation(new HelpLocation("ViewStringsPlugin", "Refresh"))
refreshAction.setToolBarData(new ToolBarData(REFRESH_NOT_NEEDED_ICON)); .buildAndInstallLocal(provider);
refreshAction.setDescription(
"<html>Push at any time to refresh the current table of strings.<br>" +
"This button is highlighted when the data <i>may</i> be stale.<br>");
refreshAction.setHelpLocation(new HelpLocation("ViewStringsPlugin", "Refresh"));
tool.addLocalAction(provider, refreshAction);
tool.addLocalAction(provider, new MakeProgramSelectionAction(this, provider.getTable())); tool.addLocalAction(provider, new MakeProgramSelectionAction(this, provider.getTable()));
linkNavigationAction = new SelectionNavigationAction(this, provider.getTable()); linkNavigationAction = new SelectionNavigationAction(this, provider.getTable());
tool.addLocalAction(provider, linkNavigationAction); tool.addLocalAction(provider, linkNavigationAction);
DockingAction editDataSettingsAction = new ActionBuilder("Data Settings", getName()) // create pop-up menu item "Settings..."
new DockingAction("Data Settings", getName(), KeyBindingType.SHARED) { .withContext(ViewStringsContext.class)
@Override .popupMenuPath("Settings...")
public void actionPerformed(ActionContext context) { .popupMenuGroup("R")
.helpLocation(new HelpLocation("DataPlugin", "Data_Settings"))
.sharedKeyBinding()
.enabledWhen(vsac -> vsac.getCount() > 0)
.onAction(vsac -> {
try { try {
DataSettingsDialog dialog = provider.getSelectedRowCount() == 1 DataSettingsDialog dialog = vsac.getCount() == 1
? new DataSettingsDialog(provider.getSelectedData()) ? new DataSettingsDialog(vsac.getSelectedData())
: new DataSettingsDialog(currentProgram, : new DataSettingsDialog(vsac.getProgram(), vsac.getProgramSelection());
provider.getProgramSelection());
tool.showDialog(dialog); tool.showDialog(dialog);
dialog.dispose(); dialog.dispose();
@ -127,51 +122,34 @@ public class ViewStringsPlugin extends ProgramPlugin implements DomainObjectList
catch (CancelledException e) { catch (CancelledException e) {
// do nothing // do nothing
} }
})
.buildAndInstallLocal(provider);
new ActionBuilder("Default Settings", getName()) // create pop-up menu item "Default Settings..."
.withContext(ViewStringsContext.class)
.popupMenuPath("Default Settings...")
.popupMenuGroup("R")
.helpLocation(new HelpLocation("DataPlugin", "Default_Settings"))
.sharedKeyBinding()
.enabledWhen(vsac -> {
if (vsac.getCount() != 1) {
return false;
} }
Data data = vsac.getSelectedData();
}; return data != null && data.getDataType().getSettingsDefinitions().length != 0;
editDataSettingsAction.setPopupMenuData(new MenuData(new String[] { "Settings..." }, "R")); })
editDataSettingsAction.setHelpLocation(new HelpLocation("DataPlugin", "Data_Settings")); .onAction(vsac -> {
Data data = vsac.getSelectedData();
DockingAction editDefaultSettingsAction = if (data == null) {
new DockingAction("Default Settings", getName(), KeyBindingType.SHARED) {
@Override
public void actionPerformed(ActionContext context) {
DataType dt = getSelectedDataType();
if (dt == null) {
return; return;
} }
DataTypeSettingsDialog dataSettingsDialog = DataType dt = data.getDataType();
DataTypeSettingsDialog dialog =
new DataTypeSettingsDialog(dt, dt.getSettingsDefinitions()); new DataTypeSettingsDialog(dt, dt.getSettingsDefinitions());
tool.showDialog(dataSettingsDialog); tool.showDialog(dialog);
dataSettingsDialog.dispose(); dialog.dispose();
} })
.buildAndInstallLocal(provider);
@Override
public boolean isEnabledForContext(ActionContext context) {
if (provider.getSelectedRowCount() != 1) {
return false;
}
DataType dt = getSelectedDataType();
if (dt == null) {
return false;
}
return dt.getSettingsDefinitions().length != 0;
}
private DataType getSelectedDataType() {
Data data = provider.getSelectedData();
return data != null ? data.getDataType() : null;
}
};
editDefaultSettingsAction.setPopupMenuData(
new MenuData(new String[] { "Default Settings..." }, "R"));
editDefaultSettingsAction.setHelpLocation(
new HelpLocation("DataPlugin", "Default_Settings"));
tool.addLocalAction(provider, editDataSettingsAction);
tool.addLocalAction(provider, editDefaultSettingsAction);
} }
@Override @Override

View file

@ -17,15 +17,11 @@ package ghidra.app.plugin.core.strings;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import javax.swing.*; import javax.swing.*;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import docking.ActionContext;
import docking.widgets.table.GTableTextCellEditor; import docking.widgets.table.GTableTextCellEditor;
import docking.widgets.table.threaded.ThreadedTableModelListener; import docking.widgets.table.threaded.ThreadedTableModelListener;
import generic.theme.GIcon; import generic.theme.GIcon;
@ -39,7 +35,6 @@ import ghidra.program.util.ProgramLocation;
import ghidra.program.util.ProgramSelection; import ghidra.program.util.ProgramSelection;
import ghidra.util.HelpLocation; import ghidra.util.HelpLocation;
import ghidra.util.table.*; import ghidra.util.table.*;
import ghidra.util.task.TaskMonitor;
/** /**
* Provider for the defined strings table. * Provider for the defined strings table.
@ -76,8 +71,8 @@ public class ViewStringsProvider extends ComponentProviderAdapter {
} }
@Override @Override
public ActionContext getActionContext(MouseEvent event) { public ViewStringsContext getActionContext(MouseEvent event) {
return new ViewStringsContext(this, table); return new ViewStringsContext(this, table, stringModel);
} }
@Override @Override
@ -125,8 +120,8 @@ public class ViewStringsProvider extends ComponentProviderAdapter {
int rowCount = stringModel.getRowCount(); int rowCount = stringModel.getRowCount();
int unfilteredCount = stringModel.getUnfilteredRowCount(); int unfilteredCount = stringModel.getUnfilteredRowCount();
setSubTitle("" + rowCount + " items" + setSubTitle("%d items%s".formatted(rowCount,
(rowCount != unfilteredCount ? " (of " + unfilteredCount + ")" : "")); rowCount != unfilteredCount ? " (of " + unfilteredCount + ")" : ""));
}); });
stringModel.addThreadedTableModelListener(new ThreadedTableModelListener() { stringModel.addThreadedTableModelListener(new ThreadedTableModelListener() {
@ -181,7 +176,7 @@ public class ViewStringsProvider extends ComponentProviderAdapter {
void add(Data data) { void add(Data data) {
if (isVisible()) { if (isVisible()) {
stringModel.addDataInstance(currentProgram, data, TaskMonitor.DUMMY); stringModel.addDataInstance(currentProgram, data);
} }
} }
@ -242,54 +237,6 @@ public class ViewStringsProvider extends ComponentProviderAdapter {
} }
} }
public int getSelectedRowCount() {
return table.getSelectedRowCount();
}
public Data getSelectedData() {
int selectedRow = table.getSelectedRow();
if (selectedRow < 0) {
return null;
}
ProgramLocation location = stringModel.getRowObject(selectedRow);
return DataUtilities.getDataAtLocation(location);
}
public List<Data> getSelectedDataList(Predicate<Data> filter) {
List<Data> list = new ArrayList<>();
int[] selectedRows = table.getSelectedRows();
for (int row : selectedRows) {
ProgramLocation location = stringModel.getRowObject(row);
Data data = DataUtilities.getDataAtLocation(location);
if (passesFilter(data, filter)) {
list.add(data);
}
}
return list;
}
public List<ProgramLocation> getSelectedDataLocationList(Predicate<Data> filter) {
List<ProgramLocation> result = new ArrayList<>();
int[] selectedRows = table.getSelectedRows();
for (int row : selectedRows) {
ProgramLocation location = stringModel.getRowObject(row);
Data data = DataUtilities.getDataAtLocation(location);
if (passesFilter(data, filter)) {
result.add(location);
}
}
return result;
}
private boolean passesFilter(Data data, Predicate<Data> filter) {
if (data == null) {
return false;
}
if (filter == null) {
return true;
}
return filter.test(data);
}
public Program getProgram() { public Program getProgram() {
return currentProgram; return currentProgram;
@ -322,10 +269,11 @@ public class ViewStringsProvider extends ComponentProviderAdapter {
@Override @Override
public Component getTableCellEditorComponent(JTable jTable, Object value, public Component getTableCellEditorComponent(JTable jTable, Object value,
boolean isSelected, int row, int column) { boolean isSelected, int rowIndex, int columnIndex) {
if (value instanceof StringDataInstance) { Data data = DataUtilities.getDataAtLocation(stringModel.getRowObject(rowIndex));
if (data != null) {
textField.setEditable(true); textField.setEditable(true);
StringDataInstance sdi = (StringDataInstance) value; StringDataInstance sdi = StringDataInstance.getStringDataInstance(data);
if (sdi.isShowTranslation() && sdi.getTranslatedValue() != null) { if (sdi.isShowTranslation() && sdi.getTranslatedValue() != null) {
textField.setText(sdi.getTranslatedValue()); textField.setText(sdi.getTranslatedValue());
} }
@ -334,8 +282,8 @@ public class ViewStringsProvider extends ComponentProviderAdapter {
} }
} }
else { else {
textField.setText("");
textField.setEditable(false); textField.setEditable(false);
textField.setText("unsupported");
} }
return textField; return textField;
} }

View file

@ -62,7 +62,8 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
IS_ASCII_COL, IS_ASCII_COL,
CHARSET_COL, CHARSET_COL,
HAS_ENCODING_ERROR, HAS_ENCODING_ERROR,
UNICODE_SCRIPT UNICODE_SCRIPT,
TRANSLATED_VALUE
} }
ViewStringsTableModel(PluginTool tool) { ViewStringsTableModel(PluginTool tool) {
@ -81,7 +82,10 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
DynamicTableColumn<ProgramLocation, ?, ?> column = getColumn(columnIndex); DynamicTableColumn<ProgramLocation, ?, ?> column = getColumn(columnIndex);
if (column instanceof StringRepColumn) { if (column instanceof StringRepColumn) {
ProgramLocation progLoc = getRowObject(rowIndex); ProgramLocation progLoc = getRowObject(rowIndex);
ManualStringTranslationService.setTranslatedValue(program, progLoc, aValue.toString()); if (progLoc != null) {
ManualStringTranslationService.setTranslatedValue(program, progLoc,
aValue.toString());
}
} }
} }
@ -92,12 +96,13 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
// These columns need to match the COLUMNS enum indexes // These columns need to match the COLUMNS enum indexes
descriptor.addVisibleColumn(new DataLocationColumn(), 1, true); descriptor.addVisibleColumn(new DataLocationColumn(), 1, true);
descriptor.addVisibleColumn(new DataValueColumn()); descriptor.addVisibleColumn(new DataValueColumn());
descriptor.addVisibleColumn(new StringRepColumn()); descriptor.addVisibleColumn(new StringRepColumn()); // see StringRepCellEditor in ViewStringsProvider
descriptor.addVisibleColumn(new DataTypeColumn()); descriptor.addVisibleColumn(new DataTypeColumn());
descriptor.addHiddenColumn(new IsAsciiColumn()); descriptor.addHiddenColumn(new IsAsciiColumn());
descriptor.addHiddenColumn(new CharsetColumn()); descriptor.addHiddenColumn(new CharsetColumn());
descriptor.addHiddenColumn(new HasEncodingErrorColumn()); descriptor.addHiddenColumn(new HasEncodingErrorColumn());
descriptor.addHiddenColumn(new UnicodeScriptColumn()); descriptor.addHiddenColumn(new UnicodeScriptColumn());
descriptor.addHiddenColumn(new TranslatedValueColumn());
return descriptor; return descriptor;
} }
@ -119,8 +124,7 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
Swing.allowSwingToProcessEvents(); Swing.allowSwingToProcessEvents();
for (Data stringInstance : DefinedDataIterator.definedStrings(localProgram)) { for (Data stringInstance : DefinedDataIterator.definedStrings(localProgram)) {
accumulator.add(createIndexedStringInstanceLocation(localProgram, stringInstance)); accumulator.add(createIndexedStringInstanceLocation(localProgram, stringInstance));
monitor.checkCancelled(); monitor.increment();
monitor.incrementProgress(1);
} }
} }
@ -143,7 +147,7 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
return (pl != null) ? rowsIndexedByAddress.get(pl.getAddress()) : null; return (pl != null) ? rowsIndexedByAddress.get(pl.getAddress()) : null;
} }
public void addDataInstance(Program localProgram, Data data, TaskMonitor monitor) { public void addDataInstance(Program localProgram, Data data) {
for (Data stringInstance : DefinedDataIterator.definedStrings(data)) { for (Data stringInstance : DefinedDataIterator.definedStrings(data)) {
addObject(createIndexedStringInstanceLocation(localProgram, stringInstance)); addObject(createIndexedStringInstanceLocation(localProgram, stringInstance));
} }
@ -202,6 +206,9 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
private static class DataValueColumn private static class DataValueColumn
extends AbstractProgramLocationTableColumn<ProgramLocation, StringDataInstance> { extends AbstractProgramLocationTableColumn<ProgramLocation, StringDataInstance> {
// Also see ViewStringsColumnConstrainProvider for filtering constraints that operate
// on the value of this column
private DataValueCellRenderer renderer = new DataValueCellRenderer(); private DataValueCellRenderer renderer = new DataValueCellRenderer();
@Override @Override
@ -241,14 +248,19 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
public String getFilterString(StringDataInstance t, Settings settings) { public String getFilterString(StringDataInstance t, Settings settings) {
return getText(t); return getText(t);
} }
@Override
public ColumnConstraintFilterMode getColumnConstraintFilterMode() {
return ColumnConstraintFilterMode.ALLOW_ALL_FILTERS;
}
} }
} }
private static class StringRepColumn private static class StringRepColumn
extends AbstractProgramLocationTableColumn<ProgramLocation, StringDataInstance> { extends AbstractProgramLocationTableColumn<ProgramLocation, String> {
private StringRepCellRenderer renderer = new StringRepCellRenderer(); // also see StringRepCellEditor in ViewStringsProvider
@Override @Override
public String getColumnName() { public String getColumnName() {
@ -256,12 +268,12 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
} }
@Override @Override
public StringDataInstance getValue(ProgramLocation rowObject, Settings settings, public String getValue(ProgramLocation rowObject, Settings settings,
Program program, ServiceProvider serviceProvider) throws IllegalArgumentException { Program program, ServiceProvider serviceProvider) throws IllegalArgumentException {
Data data = DataUtilities.getDataAtLocation(rowObject); Data data = DataUtilities.getDataAtLocation(rowObject);
if (StringDataInstance.isString(data)) { if (StringDataInstance.isString(data)) {
StringDataInstance sdi = StringDataInstance.getStringDataInstance(data); StringDataInstance sdi = StringDataInstance.getStringDataInstance(data);
return sdi; return sdi.getStringRepresentation();
} }
return null; return null;
} }
@ -271,27 +283,6 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
Program program, ServiceProvider serviceProvider) { Program program, ServiceProvider serviceProvider) {
return rowObject; return rowObject;
} }
@Override
public GColumnRenderer<StringDataInstance> getColumnRenderer() {
return renderer;
}
private class StringRepCellRenderer extends AbstractGColumnRenderer<StringDataInstance> {
@Override
protected String getText(Object value) {
if (value instanceof StringDataInstance) {
return ((StringDataInstance) value).getStringRepresentation();
}
return "";
}
@Override
public String getFilterString(StringDataInstance t, Settings settings) {
return getText(t);
}
}
} }
// data type to string column // data type to string column
@ -402,6 +393,31 @@ class ViewStringsTableModel extends AddressBasedTableModel<ProgramLocation> {
} }
private static class TranslatedValueColumn
extends AbstractProgramLocationTableColumn<ProgramLocation, String> {
@Override
public String getColumnName() {
return "Translated Value";
}
@Override
public String getValue(ProgramLocation rowObject, Settings settings, Program program,
ServiceProvider serviceProvider) throws IllegalArgumentException {
Data data = DataUtilities.getDataAtLocation(rowObject);
String s = TranslationSettingsDefinition.TRANSLATION.getTranslatedValue(data);
return s;
}
@Override
public ProgramLocation getProgramLocation(ProgramLocation rowObject, Settings settings,
Program program, ServiceProvider serviceProvider) {
return rowObject;
}
}
private static class UnicodeScriptColumn private static class UnicodeScriptColumn
extends AbstractProgramLocationTableColumn<ProgramLocation, String> { extends AbstractProgramLocationTableColumn<ProgramLocation, String> {

View file

@ -37,7 +37,7 @@ public class TranslationSettingsDefinition extends JavaEnumSettingsDefinition<TR
private final String s; private final String s;
private TRANSLATION_ENUM(String s) { TRANSLATION_ENUM(String s) {
this.s = s; this.s = s;
} }