Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Merge branch 'search-replace' into integration/master
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmason committed May 10, 2012
2 parents f89fd33 + 350cf09 commit decb240
Show file tree
Hide file tree
Showing 2 changed files with 318 additions and 79 deletions.
Expand Up @@ -22,9 +22,12 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;
Expand Down Expand Up @@ -99,25 +102,28 @@ public interface Display extends WidgetDisplay

HasClickHandlers addDocumentLabel(String docName);

HasData<TransUnit> addTUTable(Delegate<TransUnit> replaceDelegate, SelectionModel<TransUnit> selectionModel, ValueChangeHandler<Boolean> selectAllHandler);
HasData<TransUnitReplaceInfo> addTUTable(Delegate<TransUnitReplaceInfo> replaceDelegate, Delegate<TransUnitReplaceInfo> undoDelegate, SelectionModel<TransUnitReplaceInfo> selectionModel, ValueChangeHandler<Boolean> selectAllHandler);
}

private final CachingDispatchAsync dispatcher;
private final History history;
private AsyncCallback<GetProjectTransUnitListsResult> projectSearchCallback;
private Delegate<TransUnit> replaceButtonDelegate;
private Delegate<TransUnitReplaceInfo> replaceButtonDelegate;
private Delegate<TransUnitReplaceInfo> undoButtonDelegate;
private Comparator<TransUnitReplaceInfo> tuInfoComparator;


/**
* Model objects for tables in display. Changes to these are reflected in the
* view.
*/
private Map<Long, ListDataProvider<TransUnit>> documentDataProviders;
private Map<Long, ListDataProvider<TransUnitReplaceInfo>> documentDataProviders;

/**
* Selection model objects for tables in display. Used to determine which
* transunits are selected
*/
private Map<Long, MultiSelectionModel<TransUnit>> documentSelectionModels;
private Map<Long, MultiSelectionModel<TransUnitReplaceInfo>> documentSelectionModels;

/**
* most recent history state that was responded to
Expand All @@ -137,8 +143,11 @@ protected void onBind()
{
projectSearchCallback = buildProjectSearchCallback();
replaceButtonDelegate = buildReplaceButtonDelegate();
documentDataProviders = new HashMap<Long, ListDataProvider<TransUnit>>();
documentSelectionModels = new HashMap<Long, MultiSelectionModel<TransUnit>>();
undoButtonDelegate = buildUndoButtonDelegate();
documentDataProviders = new HashMap<Long, ListDataProvider<TransUnitReplaceInfo>>();
documentSelectionModels = new HashMap<Long, MultiSelectionModel<TransUnitReplaceInfo>>();
tuInfoComparator = buildTransUnitReplaceInfoComparator();


registerHandler(display.getFilterTextBox().addValueChangeHandler(new ValueChangeHandler<String>()
{
Expand Down Expand Up @@ -208,9 +217,12 @@ public void onChange(ChangeEvent event)
public void onClick(ClickEvent event)
{
List<TransUnit> selected = new ArrayList<TransUnit>();
for (MultiSelectionModel<TransUnit> sm : documentSelectionModels.values())
for (MultiSelectionModel<TransUnitReplaceInfo> sm : documentSelectionModels.values())
{
selected.addAll(sm.getSelectedSet());
for (TransUnitReplaceInfo info : sm.getSelectedSet())
{
selected.add(info.getTransUnit());
}
}

if (selected.isEmpty())
Expand Down Expand Up @@ -271,43 +283,43 @@ public void onValueChange(ValueChangeEvent<String> event)
public void onTransUnitUpdated(final TransUnitUpdatedEvent event)
{
TransUnitUpdateInfo updateInfo = event.getUpdateInfo();
ListDataProvider<TransUnit> dataProvider = documentDataProviders.get(updateInfo.getDocumentId().getId());
if (dataProvider == null)
TransUnitReplaceInfo replaceInfo = getReplaceInfoForUpdatedTU(updateInfo);
if (replaceInfo == null)
{
Log.debug("document '" + updateInfo.getDocumentId().getId() + "' not found for TU update, id: " + updateInfo.getTransUnit().getId().getId());
Log.debug("no matching TU in document for TU update, id: " + updateInfo.getTransUnit().getId().getId());
return;
}
Log.debug("found matching TU for TU update, id: " + updateInfo.getTransUnit().getId().getId());

List<TransUnit> transUnits = dataProvider.getList();
//TransUnit does not appear to have .equals(o), so list items are manually compared
for (int i = 0; i < transUnits.size(); i++)
MultiSelectionModel<TransUnitReplaceInfo> selectionModel = documentSelectionModels.get(updateInfo.getDocumentId().getId());
if (selectionModel == null)
{
if (transUnits.get(i).getId().getId() == updateInfo.getTransUnit().getId().getId())
{
Log.debug("found matching TU for TU update, id: " + updateInfo.getTransUnit().getId().getId());
// must de-select before setting to prevent this TU being
// 'stuck' selected for the life of the selection model
// Leaving de-selected as this is currently the desired behaviour
MultiSelectionModel<TransUnit> selectionModel = documentSelectionModels.get(updateInfo.getDocumentId().getId());
// boolean isSelected = selectionModel.isSelected(transUnits.get(i)); //get selected state
if (selectionModel == null)
{
Log.error("missing selection model for document, id: " + updateInfo.getDocumentId().getId());
}
else
{
selectionModel.setSelected(transUnits.get(i), false);
}
Log.error("missing selection model for document, id: " + updateInfo.getDocumentId().getId());
}
else
{
// no need to do this as replaceInfo only has properties changed
// safe to remove if desired behaviour is keeping selected
selectionModel.setSelected(replaceInfo, false);
}

transUnits.set(i, updateInfo.getTransUnit());
// selectionModel.setSelected(transUnits.get(i), isSelected); //return to previous selection state
if (replaceInfo.isUndoable() && replaceInfo.getTransUnit().getVerNum() != updateInfo.getTransUnit().getVerNum())
{
// can't undo after new update
replaceInfo.setUndoable(false);
replaceInfo.setReplaceable(true);
replaceInfo.setReplacing(false);
replaceInfo.setReplaceInfo(null);
}
replaceInfo.setTransUnit(updateInfo.getTransUnit());

return;
}
// force table refresh as property changes are not detected
ListDataProvider<TransUnitReplaceInfo> dataProvider = documentDataProviders.get(updateInfo.getDocumentId().getId());
if (dataProvider != null)
{
dataProvider.refresh();
}
Log.debug("no matching TU in document for TU update, id: " + updateInfo.getTransUnit().getId().getId());
}

}));

}
Expand Down Expand Up @@ -366,21 +378,21 @@ public void onClick(ClickEvent event)

});

final MultiSelectionModel<TransUnit> selectionModel = new MultiSelectionModel<TransUnit>();
final ListDataProvider<TransUnit> dataProvider = new ListDataProvider<TransUnit>();
final MultiSelectionModel<TransUnitReplaceInfo> selectionModel = new MultiSelectionModel<TransUnitReplaceInfo>();
final ListDataProvider<TransUnitReplaceInfo> dataProvider = new ListDataProvider<TransUnitReplaceInfo>();

// TODO set selected value for header based on selection of rows?
HasData<TransUnit> table = display.addTUTable(replaceButtonDelegate, selectionModel, new ValueChangeHandler<Boolean>()
HasData<TransUnitReplaceInfo> table = display.addTUTable(replaceButtonDelegate, undoButtonDelegate, selectionModel, new ValueChangeHandler<Boolean>()
{

@Override
public void onValueChange(ValueChangeEvent<Boolean> event)
{
if (event.getValue())
{
for (TransUnit tu : dataProvider.getList())
for (TransUnitReplaceInfo info : dataProvider.getList())
{
selectionModel.setSelected(tu, true);
selectionModel.setSelected(info, true);
}
}
else
Expand All @@ -392,9 +404,12 @@ public void onValueChange(ValueChangeEvent<Boolean> event)
});
dataProvider.addDataDisplay(table);

List<TransUnit> data = dataProvider.getList();
data.addAll(result.getUnits(docId));
Collections.sort(data, TransUnit.getRowIndexComparator());
List<TransUnitReplaceInfo> data = dataProvider.getList();
for (TransUnit tu : result.getUnits(docId))
{
data.add(new TransUnitReplaceInfo(tu));
}
Collections.sort(data, tuInfoComparator);
documentDataProviders.put(docId, dataProvider);
documentSelectionModels.put(docId, selectionModel);
}
Expand All @@ -403,14 +418,28 @@ public void onValueChange(ValueChangeEvent<Boolean> event)
};
}

private Delegate<TransUnit> buildReplaceButtonDelegate()
private Delegate<TransUnitReplaceInfo> buildReplaceButtonDelegate()
{
return new Delegate<TransUnitReplaceInfo>() {

@Override
public void execute(TransUnitReplaceInfo tu)
{
fireReplaceTextEvent(Collections.singletonList(tu.getTransUnit()));
}
};
}

private Delegate<TransUnitReplaceInfo> buildUndoButtonDelegate()
{
return new Delegate<TransUnit>() {
return new Delegate<TransUnitReplaceInfo>() {

@Override
public void execute(TransUnit tu)
public void execute(TransUnitReplaceInfo info)
{
fireReplaceTextEvent(Collections.singletonList(tu));
eventBus.fireEvent(new NotificationEvent(Severity.Error, "Undo not implemented"));
// FIXME fire this when it exists
// fireUndoUpdateEvent(Collections.singletonList(tu));
}
};
}
Expand All @@ -420,6 +449,7 @@ public void execute(TransUnit tu)
*/
private void fireReplaceTextEvent(List<TransUnit> toReplace)
{
// TODO set info to replacing... before calling this event
String searchText = currentHistoryState.getProjectSearchText();
String replacement = currentHistoryState.getProjectSearchReplacement();
boolean caseSensitive = currentHistoryState.getProjectSearchCaseSensitive();
Expand All @@ -433,15 +463,163 @@ public void onFailure(Throwable e)
Log.error("[SearchResultsPresenter] Replace text failure " + e, e);
// TODO use localised string
eventBus.fireEvent(new NotificationEvent(Severity.Error, "Replace text failed"));
// TODO consider whether possible/desired to change TU state from 'replacing'
}

@Override
public void onSuccess(UpdateTransUnitResult result)
{
Set<Long> updatedDocs = new HashSet<Long>();
for (TransUnitUpdateInfo updateInfo : result.getUpdateInfoList())
{
if (updateInfo.isSuccess())
{
TransUnitReplaceInfo replaceInfo = getReplaceInfoForUpdatedTU(updateInfo);
if (replaceInfo != null)
{
replaceInfo.setReplaceInfo(updateInfo);
replaceInfo.setUndoable(true);
replaceInfo.setReplaceable(false);
replaceInfo.setReplacing(false);
//this should be done when the TU update event comes in anyway
//may want to remove this
replaceInfo.setTransUnit(updateInfo.getTransUnit());
}
updatedDocs.add(updateInfo.getDocumentId().getId());
}
// individual failure behaviour not yet defined
}

// force table refresh as property changes are not detected
for (Long docId : updatedDocs)
{
ListDataProvider<TransUnitReplaceInfo> dataProvider = documentDataProviders.get(docId);
if (dataProvider != null)
{
dataProvider.refresh();
}
}

// TODO use localised string
eventBus.fireEvent(new NotificationEvent(Severity.Info, "Successfully replaced text"));
}
});
}

public class TransUnitReplaceInfo
{
private TransUnit tu;
private TransUnitUpdateInfo replaceInfo = null;
private boolean replaceable;
private boolean replacing;
private boolean undoable;

public TransUnitReplaceInfo(TransUnit tu)
{
this.tu = tu;
replaceInfo = null;
replaceable = true;
replacing = false;
undoable = false;
}

public TransUnit getTransUnit()
{
return tu;
}

public void setTransUnit(TransUnit tu)
{
this.tu = tu;
}

public TransUnitUpdateInfo getReplaceInfo()
{
return replaceInfo;
}

public void setReplaceInfo(TransUnitUpdateInfo replaceInfo)
{
this.replaceInfo = replaceInfo;
}

public boolean isReplaceable()
{
return replaceable;
}

public void setReplaceable(boolean canReplace)
{
this.replaceable = canReplace;
}

public boolean isReplacing()
{
return replacing;
}

public void setReplacing(boolean isReplacing)
{
this.replacing = isReplacing;
}

public boolean isUndoable()
{
return undoable;
}

public void setUndoable(boolean undoable)
{
this.undoable = undoable;
}

}

private Comparator<TransUnitReplaceInfo> buildTransUnitReplaceInfoComparator()
{
return new Comparator<SearchResultsPresenter.TransUnitReplaceInfo>()
{

@Override
public int compare(TransUnitReplaceInfo o1, TransUnitReplaceInfo o2)
{
if (o1 == o2)
{
return 0;
}
if (o1 != null)
{
return (o2 != null ? Integer.valueOf(o1.getTransUnit().getRowIndex()).compareTo(o2.getTransUnit().getRowIndex()) : 1);
}
return -1;
}
};
}

/**
* @param updateInfo
* @param replaceInfo
* @return the replace info for the updated {@link TransUnit}, or null if the
* current search results do not contain the TransUnit
*/
private TransUnitReplaceInfo getReplaceInfoForUpdatedTU(TransUnitUpdateInfo updateInfo)
{
ListDataProvider<TransUnitReplaceInfo> dataProvider = documentDataProviders.get(updateInfo.getDocumentId().getId());
if (dataProvider == null)
{
Log.debug("document '" + updateInfo.getDocumentId().getId() + "' not found for TU update, id: " + updateInfo.getTransUnit().getId().getId());
return null;
}

List<TransUnitReplaceInfo> replaceInfoList = dataProvider.getList();
//TransUnit does not appear to have .equals(o), so list items are manually compared
for (TransUnitReplaceInfo info : replaceInfoList)
{
if (info.getTransUnit().getId().getId() == updateInfo.getTransUnit().getId().getId())
{
return info;
}
}
return null;
}
}

0 comments on commit decb240

Please sign in to comment.