diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java index da639d796..10727d236 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeApp.java @@ -1,23 +1,35 @@ package se.chalmers.cs.gf.gwt.client; +import java.util.List; + import com.allen_sauer.gwt.dnd.client.PickupDragController; import com.allen_sauer.gwt.dnd.client.drop.DropController; +import com.google.gwt.core.client.EntryPoint; +import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.History; +import com.google.gwt.user.client.HistoryListener; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.ChangeListener; import com.google.gwt.user.client.ui.ClickListener; import com.google.gwt.user.client.ui.HorizontalPanel; -import com.google.gwt.user.client.ui.Hyperlink; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; -public class FridgeApp extends TranslateApp { +public class FridgeApp implements EntryPoint { + + protected static final String pgfBaseURL = "/pgf"; + + protected PGFWrapper pgf; + + protected JSONRequest translateRequest = null; private FridgeBagPanel bagPanel; private FridgeTextPanel textPanel; + protected VerticalPanel outputPanel; + protected StatusPopup statusPopup; private MagnetFactory magnetFactory; @@ -34,49 +46,102 @@ public class FridgeApp extends TranslateApp { // Translation // - protected Widget createTranslation(String language, String text) { - Hyperlink l = new Hyperlink(text, makeToken(language, text)); - l.addStyleName("my-translation"); - String lang = pgf.getLanguageCode(language); - if (lang != null) { - l.getElement().setLang(lang); + protected void translate() { + outputPanel.clear(); + outputPanel.addStyleDependentName("working"); + if (translateRequest != null) { + translateRequest.cancel(); } - return l; + translateRequest = pgf.translate(getText(), + new PGF.TranslateCallback() { + public void onResult (PGF.Translations translations) { + outputPanel.removeStyleDependentName("working"); + for (PGF.Translation t : translations.iterable()) { + outputPanel.add(createTranslation(t.getTo(), t.getText())); + } + } + public void onError (Throwable e) { + showError("Translation failed", e); + } + }); } - // - // Available words - // + protected ClickListener translationClickListener = new ClickListener () { + public void onClick(Widget widget) { + Magnet magnet = (Magnet)widget; + setInputLanguage(magnet.getLanguage()); // FIXME: this causes an unnecessary update() + setText(magnet.getText(), magnet.getLanguage()); + } + }; - private String makeToken (String language, String text) { - return pgf.getPGFName() + "/" + language + "/" + text; + protected Widget createTranslation(String language, String text) { + Magnet magnet = magnetFactory.createUsedMagnet(text, language); + magnet.addClickListener(translationClickListener); + String lang = pgf.getLanguageCode(language); + if (lang != null) { + magnet.getElement().setLang(lang); + } + return magnet; } // // Current text // + public String getText () { + return textPanel.getText(); + } + + public void setText(String text, String language) { + textPanel.setText(text, language); + } + private void clear() { textPanel.clear(); } - // History stuff + // + // Status stuff + // - protected void updateSettingsFromHistoryToken(String[] tokenParts) { - super.updateSettingsFromHistoryToken(tokenParts); - if (tokenParts.length >= 3 && tokenParts[2].length() > 0) { - setText(tokenParts[2]); - update(); - } + protected void setStatus(String msg) { + statusPopup.setStatus(msg); } + protected void showError(String msg, Throwable e) { + statusPopup.showError(msg, e); + } + + protected void clearStatus() { + statusPopup.clearStatus(); + } // GUI protected Widget createUI() { PickupDragController dragController = new PickupDragController(RootPanel.get(), false); - magnetFactory = new MagnetFactory(dragController); + dragController.setBehaviorDragStartSensitivity(1); + dragController.setBehaviorDragProxy(true); + dragController.setBehaviorConstrainedToBoundaryPanel(true); + /* + dragController.addDragHandler(new DragHandlerAdapter() { + public void onDragStart(DragStartEvent event) { + Widget w = event.getContext().draggable; + if (w instanceof Magnet) { + bagPanel.cloneMagnet((Magnet)w); + } + } + }); + */ + + ClickListener magnetClickListener = new ClickListener () { + public void onClick(Widget widget) { + Magnet magnet = (Magnet)widget; + textPanel.addMagnet(magnet); + } + }; + magnetFactory = new MagnetFactory(dragController, magnetClickListener); VerticalPanel vPanel = new VerticalPanel(); vPanel.setWidth("100%"); @@ -101,8 +166,6 @@ public class FridgeApp extends TranslateApp { } }); - textSource = textPanel; - return textPanel; } @@ -121,8 +184,84 @@ public class FridgeApp extends TranslateApp { return bagPanel; } + protected Widget createSettingsPanel () { + return new SettingsPanel(pgf, true, false); + } + protected Widget createTranslationsPanel () { + outputPanel = new VerticalPanel(); + outputPanel.addStyleName("my-translations"); + return outputPanel; + } + + // + // History stuff + // + + protected class MyHistoryListener implements HistoryListener { + public void onHistoryChanged(String historyToken) { + updateSettingsFromHistoryToken(); + } + }; + + protected void updateSettingsFromHistoryToken() { + updateSettingsFromHistoryToken(History.getToken().split("/")); + } + + protected void updateSettingsFromHistoryToken(String[] tokenParts) { + if (tokenParts.length >= 1 && tokenParts[0].length() > 0) { + setPGFName(tokenParts[0]); + } + if (tokenParts.length >= 2 && tokenParts[1].length() > 0) { + setInputLanguage(tokenParts[1]); + } + } + + protected void setPGFName (String pgfName) { + if (pgfName != null && !pgfName.equals(pgf.getPGFName())) { + pgf.setPGFName(pgfName); + } + } + + protected void setInputLanguage (String inputLanguage) { + if (inputLanguage != null && !inputLanguage.equals(pgf.getInputLanguage())) { + pgf.setInputLanguage(inputLanguage); + } + } + + // // Initialization + // + + protected class MySettingsListener implements PGFWrapper.SettingsListener { + // Will only happen on load + public void onAvailableGrammarsChanged() { + if (pgf.getPGFName() == null) { + List grammars = pgf.getGrammars(); + if (!grammars.isEmpty()) { + pgf.setPGFName(grammars.get(0)); + } + } + } + public void onAvailableLanguagesChanged() { + if (pgf.getInputLanguage() == null) { + GWT.log("Setting input language to user language: " + pgf.getUserLanguage(), null); + pgf.setInputLanguage(pgf.getUserLanguage()); + } + } + public void onInputLanguageChanged() { + clear(); + } + public void onOutputLanguageChanged() { + update(); + } + public void onCatChanged() { + update(); + } + public void onSettingsError(String msg, Throwable e) { + showError(msg,e); + } + } public void onModuleLoad() { statusPopup = new StatusPopup(); diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java index 46579c578..a2f356ed7 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeBagPanel.java @@ -1,22 +1,19 @@ package se.chalmers.cs.gf.gwt.client; import com.google.gwt.core.client.GWT; -import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; -public class FridgeBagPanel extends Composite { +public class FridgeBagPanel extends FlowPanel { private PGFWrapper pgf; private MagnetFactory magnetFactory; - private FlowPanel mainPanel; + protected JSONRequest completeRequest = null; public FridgeBagPanel (PGFWrapper pgf, MagnetFactory magnetFactory) { this.pgf = pgf; this.magnetFactory = magnetFactory; - mainPanel = new FlowPanel(); - initWidget(mainPanel); setStylePrimaryName("my-FridgeBagPanel"); } @@ -24,21 +21,24 @@ public class FridgeBagPanel extends Composite { updateBag(text, ""); } - public void updateBag (String text, String prefix) { - mainPanel.clear(); + public void updateBag (final String text, String prefix) { + clear(); int limit = 100; - pgf.complete(text + " " + prefix, + if (completeRequest != null) { + completeRequest.cancel(); + } + completeRequest = pgf.complete(text + " " + prefix, limit, new PGF.CompleteCallback() { public void onResult(PGF.Completions completions) { - mainPanel.clear(); - for (PGF.Completion completion : completions.iterable()) { - String text = completion.getText(); - if (!completion.getText().equals(text + " ")) { - String[] words = text.split("\\s+"); + clear(); + for (PGF.Completion completion : completions.iterable()) { + String newText = completion.getText(); + if (!newText.equals(text + " ")) { + String[] words = newText.split("\\s+"); if (words.length > 0) { String word = words[words.length - 1]; - Magnet magnet = magnetFactory.createMagnet(word); - mainPanel.add(magnet); + Magnet magnet = magnetFactory.createMagnet(word, completion.getFrom()); + add(magnet); } } } @@ -49,5 +49,16 @@ public class FridgeBagPanel extends Composite { } }); } + +/* + public void cloneMagnet (Magnet magnet) { + int i = getWidgetIndex(magnet); + GWT.log("cloneMagnet: " + magnet.getParent(), null); + if (i != -1) { + GWT.log("cloning", null); + insert(magnetFactory.createMagnet(magnet), i); + } + } +*/ } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java index b16b10ed1..8ab4ed6aa 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/FridgeTextPanel.java @@ -4,15 +4,13 @@ import com.google.gwt.user.client.ui.ChangeListener; import com.google.gwt.user.client.ui.ChangeListenerCollection; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; -import com.google.gwt.user.client.ui.HasText; -import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; -public class FridgeTextPanel extends Composite implements HasText { +public class FridgeTextPanel extends Composite { private MagnetFactory magnetFactory; - - private Panel mainPanel; + + private FlowPanel mainPanel; private ChangeListenerCollection listeners = null; @@ -30,7 +28,7 @@ public class FridgeTextPanel extends Composite implements HasText { removeStyleDependentName("engage"); } } - + public String getText () { StringBuilder sb = new StringBuilder(); for (Widget w : mainPanel) { @@ -43,12 +41,15 @@ public class FridgeTextPanel extends Composite implements HasText { return sb.toString(); } - public void setText (String text) { - clear(); - for (String word : text.split("\\s+")) { - if (word.length() > 0) { - addMagnet(magnetFactory.createMagnet(word)); + public void setText (String text, String language) { + if (!text.equals(getText())) { + mainPanel.clear(); + for (String word : text.split("\\s+")) { + if (word.length() > 0) { + mainPanel.add(magnetFactory.createUsedMagnet(word, language)); + } } + fireChange(); } } @@ -56,16 +57,16 @@ public class FridgeTextPanel extends Composite implements HasText { mainPanel.clear(); fireChange(); } - + public void addMagnet (Magnet magnet) { - mainPanel.add(magnet); + mainPanel.add(magnetFactory.createUsedMagnet(magnet)); fireChange(); } protected void fireChange() { listeners.fireChange(this); } - + public void addChangeListener(ChangeListener listener) { if (listeners == null) { listeners = new ChangeListenerCollection(); diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java index 12eca5e97..bea21d4ed 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/Magnet.java @@ -1,12 +1,19 @@ package se.chalmers.cs.gf.gwt.client; -import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.HTML; -public class Magnet extends Label { +public class Magnet extends HTML { - public Magnet (String text) { - setText(text); + private String language; + + public Magnet (String text, String language) { + this.language = language; + setHTML(text); setStylePrimaryName("my-Magnet"); } + + public String getLanguage() { + return language; + } } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java index 496cb4fb5..4199eea18 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/MagnetFactory.java @@ -1,17 +1,34 @@ package se.chalmers.cs.gf.gwt.client; import com.allen_sauer.gwt.dnd.client.PickupDragController; +import com.google.gwt.user.client.ui.ClickListener; public class MagnetFactory { private PickupDragController dragController; - public MagnetFactory (PickupDragController dragController) { + private ClickListener clickListener; + + public MagnetFactory (PickupDragController dragController, ClickListener clickListener) { this.dragController = dragController; + this.clickListener = clickListener; } - public Magnet createMagnet(String text) { - Magnet magnet = new Magnet(text); + public Magnet createUsedMagnet(Magnet magnet) { + return createUsedMagnet(magnet.getText(), magnet.getLanguage()); + } + + public Magnet createUsedMagnet(String text, String language) { + return new Magnet(text, language); + } + + public Magnet createMagnet(Magnet magnet) { + return createMagnet(magnet.getText(), magnet.getLanguage()); + } + + public Magnet createMagnet(String text, String language) { + Magnet magnet = new Magnet(text, language); + magnet.addClickListener(clickListener); dragController.makeDraggable(magnet); return magnet; } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java index 1a5dea6c8..21f9b4bdf 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/TranslateApp.java @@ -6,7 +6,6 @@ import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; import com.google.gwt.user.client.History; import com.google.gwt.user.client.HistoryListener; -import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; import com.google.gwt.user.client.ui.VerticalPanel; @@ -19,7 +18,7 @@ public class TranslateApp implements EntryPoint { protected PGFWrapper pgf; - protected HasText textSource; + protected SuggestPanel suggestPanel; protected VerticalPanel outputPanel; protected StatusPopup statusPopup; @@ -28,12 +27,7 @@ public class TranslateApp implements EntryPoint { // public String getText () { - return textSource.getText(); - } - - public void setText(String text) { - textSource.setText(text); - update(); + return suggestPanel.getText(); } protected void update () { @@ -47,9 +41,10 @@ public class TranslateApp implements EntryPoint { protected void translate() { outputPanel.clear(); outputPanel.addStyleDependentName("working"); - pgf.translate(textSource.getText(), + pgf.translate(getText(), new PGF.TranslateCallback() { public void onResult (PGF.Translations translations) { + outputPanel.clear(); outputPanel.removeStyleDependentName("working"); for (PGF.Translation t : translations.iterable()) { outputPanel.add(createTranslation(t.getTo(), t.getText())); @@ -102,16 +97,13 @@ public class TranslateApp implements EntryPoint { } protected Widget createSuggestPanel () { - SuggestPanel suggestPanel = new SuggestPanel(pgf); + suggestPanel = new SuggestPanel(pgf); suggestPanel.setButtonText("Translate"); suggestPanel.addSubmitListener(new SuggestPanel.SubmitListener() { public void onSubmit(String text) { translate(); } - }); - - textSource = suggestPanel; - + }); return suggestPanel; } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css b/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css index 22ec8adad..449387173 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Fridge.css @@ -7,7 +7,7 @@ body { } .my-FridgeTextPanel, .my-FridgeBagPanel { - min-height: 2em; + min-height: 2.4em; padding: 0.2em; overflow: auto; } @@ -18,8 +18,8 @@ body { } .my-FridgeTextPanel-engage { - border-color: #aaaaaa; - background-color: #ccff99; + border-color: #666666; + background-color: #dddddd; } .my-FridgeBagPanel { @@ -38,7 +38,9 @@ body { } .my-translations { - border: 1px solid silver; + min-height: 2.4em; + padding: 0.2em; + border: 3px solid silver; } .my-translation {