diff --git a/src/PGF.hs b/src/PGF.hs index b49a19db6..5cd499aec 100644 --- a/src/PGF.hs +++ b/src/PGF.hs @@ -20,12 +20,12 @@ module PGF( -- * Identifiers CId, mkCId, wildCId, showCId, readCId, - + -- * Languages Language, showLanguage, readLanguage, languages, abstractName, languageCode, - + -- * Types Type, Hypo, showType, readType, @@ -55,10 +55,10 @@ module PGF( -- ** Parsing parse, parseWithRecovery, canParse, parseAllLang, parseAll, - + -- ** Evaluation PGF.compute, paraphrase, - + -- ** Type Checking -- | The type checker in PGF does both type checking and renaming -- i.e. it verifies that all identifiers are declared and it @@ -71,7 +71,7 @@ module PGF( -- also lead to metavariables instantiations. checkType, checkExpr, inferExpr, TcError(..), ppTcError, - + -- ** Word Completion (Incremental Parsing) complete, Incremental.ParseState, @@ -79,7 +79,7 @@ module PGF( -- ** Generation generateRandom, generateAll, generateAllDepth, - + -- ** Morphological Analysis Lemma, Analysis, Morpho, lookupMorpho, buildMorpho, @@ -88,7 +88,10 @@ module PGF( graphvizAbstractTree, graphvizParseTree, graphvizDependencyTree, - graphvizAlignment + graphvizAlignment, + + -- * Browsing + browse ) where import PGF.CId @@ -114,8 +117,10 @@ import qualified Data.Map as Map import qualified Data.IntMap as IntMap import Data.Maybe import Data.Binary +import Data.List(mapAccumL) import System.Random (newStdGen) import Control.Monad +import Text.PrettyPrint --------------------------------------------------- -- Interface @@ -313,3 +318,35 @@ complete pgf from typ input = -- | Converts an expression to normal form compute :: PGF -> Expr -> Expr compute pgf = PGF.Data.normalForm (funs (abstract pgf)) 0 [] + +browse :: PGF -> CId -> Maybe (String,[CId],[CId]) +browse pgf id = fmap (\def -> (def,producers,consumers)) definition + where + definition = case Map.lookup id (funs (abstract pgf)) of + Just (ty,_,eqs) -> Just $ render (text "fun" <+> ppCId id <+> colon <+> ppType 0 [] ty $$ + if null eqs + then empty + else text "def" <+> vcat [let (scope,ds) = mapAccumL (ppPatt 9) [] patts + in ppCId id <+> hsep ds <+> char '=' <+> ppExpr 0 scope res | Equ patts res <- eqs]) + Nothing -> case Map.lookup id (cats (abstract pgf)) of + Just hyps -> Just $ render (text "cat" <+> ppCId id <+> hsep (snd (mapAccumL ppHypo [] hyps))) + Nothing -> Nothing + + (producers,consumers) = Map.foldWithKey accum ([],[]) (funs (abstract pgf)) + where + accum f (ty,_,_) (plist,clist) = + let !plist' = if id `elem` ps then f : plist else plist + !clist' = if id `elem` cs then f : clist else clist + in (plist',clist') + where + (ps,cs) = tyIds ty + + tyIds (DTyp hyps cat es) = (foldr expIds (cat:concat css) es,concat pss) + where + (pss,css) = unzip [tyIds ty | (_,_,ty) <- hyps] + + expIds (EAbs _ _ e) ids = expIds e ids + expIds (EApp e1 e2) ids = expIds e1 (expIds e2 ids) + expIds (EFun id) ids = id : ids + expIds (ETyped e _) ids = expIds e ids + expIds _ ids = ids diff --git a/src/server/FastCGIUtils.hs b/src/server/FastCGIUtils.hs index 603ca0db3..763eeb292 100644 --- a/src/server/FastCGIUtils.hs +++ b/src/server/FastCGIUtils.hs @@ -4,6 +4,7 @@ module FastCGIUtils (initFastCGI, loopFastCGI, stderrToFile, outputJSONP, outputPNG, + outputHTML, splitBy) where import Control.Concurrent @@ -170,6 +171,11 @@ outputPNG x = do setHeader "Content-Type" "image/png" outputStrict x +outputHTML :: String -> CGI CGIResult +outputHTML x = do + setHeader "Content-Type" "text/html" + outputStrict x + outputStrict :: String -> CGI CGIResult outputStrict x | x == x = output x | otherwise = fail "I am the pope." diff --git a/src/server/PGFService.hs b/src/server/PGFService.hs index 6ac7b1618..1158d9d12 100644 --- a/src/server/PGFService.hs +++ b/src/server/PGFService.hs @@ -52,6 +52,7 @@ pgfMain pgf command = "abstrtree" -> getTree >>= liftIO . doGraphvizAbstrTree pgf >>= outputPNG "parsetree" -> getTree >>= \t -> getFrom >>= \(Just l) -> liftIO (doGraphvizParseTree pgf l t) >>= outputPNG "alignment" -> getTree >>= liftIO . doGraphvizAlignment pgf >>= outputPNG + "browse" -> return (doBrowse pgf) `ap` getId `ap` getCSSClass `ap` getHRef >>= outputHTML _ -> throwCGIError 400 "Unknown command" ["Unknown command: " ++ show command] where getText :: CGI String @@ -78,6 +79,18 @@ pgfMain pgf command = getTo :: CGI (Maybe PGF.Language) getTo = getLang "to" + getId :: CGI PGF.CId + getId = do mb_id <- fmap (>>= PGF.readCId) (getInput "id") + case mb_id of + Just id -> return id + Nothing -> throwCGIError 400 "Bad identifier" [] + + getCSSClass :: CGI (Maybe String) + getCSSClass = getInput "css-class" + + getHRef :: CGI (Maybe String) + getHRef = getInput "href" + getLimit :: CGI (Maybe Int) getLimit = readInput "limit" @@ -139,8 +152,8 @@ doGrammar pgf macc = showJSON $ toJSObject ("languageCode", showJSON $ fromMaybe "" (PGF.languageCode pgf l)), ("canParse", showJSON $ PGF.canParse pgf l)] | l <- PGF.languages pgf] - categories = map toJSObject [[("name", PGF.showCId cat)] | cat <- PGF.categories pgf] - functions = map toJSObject [[("name", PGF.showCId fun)] | fun <- PGF.functions pgf] + categories = [PGF.showCId cat | cat <- PGF.categories pgf] + functions = [PGF.showCId fun | fun <- PGF.functions pgf] doGraphvizAbstrTree pgf tree = do let dot = PGF.graphvizAbstractTree pgf (True,True) tree @@ -154,6 +167,51 @@ doGraphvizAlignment pgf tree = do let dot = PGF.graphvizAlignment pgf tree readProcess "dot" ["-T","png"] (UTF8.encodeString dot) +doBrowse pgf id cssClass href = + case PGF.browse pgf id of + Just (def,ps,cs) -> "
"++annotate def++"
\n"++ + (if not (null ps) + then "
"++ + "

Producers

"++ + "

"++annotateCIds ps++"

\n" + else "")++ + (if not (null cs) + then "
"++ + "

Consumers

"++ + "

"++annotateCIds cs++"

\n" + else "") + Nothing -> "" + where + identifiers = PGF.functions pgf ++ PGF.categories pgf + + annotate [] = [] + annotate (c:cs) + | isSpace c = c : annotate cs + | otherwise = let (id,cs') = break isSpace (c:cs) + in (if PGF.mkCId id `elem` identifiers + then mkLink id + else if id == "fun" || id == "data" || id == "cat" || id == "def" + then ""++id++"" + else id) ++ + annotate cs' + annotateCIds ids = unwords (map (mkLink . PGF.showCId) ids) + + hrefAttr id = + case href of + Nothing -> "" + Just s -> "href=\""++substId id s++"\"" + + substId id [] = [] + substId id ('$':'I':'D':cs) = id ++ cs + substId id (c:cs) = c : substId id cs + + classAttr = + case cssClass of + Nothing -> "" + Just s -> "class=\""++s++"\"" + + mkLink s = ""++s++"" + instance JSON PGF.CId where readJSON x = readJSON x >>= maybe (fail "Bad language.") return . PGF.readLanguage showJSON = showJSON . PGF.showLanguage diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/BrowsePanel.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/BrowsePanel.java new file mode 100644 index 000000000..f9a159e58 --- /dev/null +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/BrowsePanel.java @@ -0,0 +1,156 @@ +package se.chalmers.cs.gf.gwt.client; + +import java.util.*; +import java.lang.*; +import com.google.gwt.core.client.*; +import com.google.gwt.user.client.ui.*; +import com.google.gwt.http.client.*; +import com.google.gwt.dom.client.*; + +public class BrowsePanel extends Composite { + + private PGFWrapper pgf; + private HTML sourceView; + private SuggestBox searchBox; + private CompletionOracle oracle; + private List identifiers = null; + + public BrowsePanel(PGFWrapper pgf) { + this.pgf = pgf; + + oracle = new CompletionOracle(); + + HorizontalPanel browsePanel = new HorizontalPanel(); + browsePanel.add(createSearchPanel(oracle)); + browsePanel.add(createSourcePanel()); + browsePanel.setCellWidth(sourceView,"100%"); + + initWidget(browsePanel); + setStylePrimaryName("my-BrowsePanel"); + + pgf.addSettingsListener(new MySettingsListener(pgf)); + } + + public native void onActivate() /*-{ + $doc.browsePanel = this; + $doc.callBrowse = @se.chalmers.cs.gf.gwt.client.BrowsePanel::callBrowse(Lse/chalmers/cs/gf/gwt/client/BrowsePanel;Ljava/lang/String;); + }-*/; + + protected Widget createSearchPanel(CompletionOracle oracle) { + searchBox = new SuggestBox(oracle); + searchBox.setLimit(10); + searchBox.addKeyboardListener(new KeyboardListenerAdapter() { + public void onKeyUp (Widget sender, char keyCode, int modifiers) { + if (keyCode == KEY_ENTER) { + browse(searchBox.getText()); + } + } + }); + + DecoratorPanel decorator = new DecoratorPanel(); + VerticalPanel vPanel = new VerticalPanel(); + vPanel.add(new Label("Search")); + vPanel.add(searchBox); + decorator.add(vPanel); + return decorator; + } + + private static void callBrowse(BrowsePanel panel, String id) { + panel.browse(id); + } + + protected void browse(String id) { + pgf.browse(id, "javascript:document.callBrowse(document.browsePanel,'$ID')", + "my-identifierLink", + new RequestCallback() { + public void onResponseReceived(Request request, Response response) { + sourceView.setHTML(response.getText()); + } + + public void onError(Request request, java.lang.Throwable exception) { + // errorHandler.onError(e); + } + }); + } + + protected Widget createSourcePanel() { + sourceView = new HTML(); + return sourceView; + } + + protected class CompletionOracle extends SuggestOracle { + + public CompletionOracle() { + } + + public void requestSuggestions(SuggestOracle.Request request, SuggestOracle.Callback callback) { + List list = new ArrayList(); + + int index = Collections.binarySearch(identifiers, request.getQuery()); + index = (index >= 0) ? index : -(index+1); + + for (; index < identifiers.size(); index++) { + String id = identifiers.get(index); + + if (id.startsWith(request.getQuery())) { + list.add(new CompletionSuggestion(id)); + } + else + break; + + if (list.size() > request.getLimit()) + break; + } + + callback.onSuggestionsReady(request, new SuggestOracle.Response(list)); + } + } + + protected static class CompletionSuggestion implements SuggestOracle.Suggestion { + private String string; + + public CompletionSuggestion(String string) { + this.string = string; + } + + public String getDisplayString() { + return string; + } + + public String getReplacementString() { + return string; + } + } + + protected class MySettingsListener implements PGFWrapper.SettingsListener { + + private PGFWrapper pgf; + + public MySettingsListener(PGFWrapper pgf) { + this.pgf = pgf; + } + + public void onAvailableGrammarsChanged() { } + public void onSelectedGrammarChanged() + { + List ids = new ArrayList(); + + for (int i = 0; i < pgf.getCategories().length(); i++) { + ids.add(pgf.getCategories().get(i)); + } + for (int i = 0; i < pgf.getFunctions().length(); i++) { + ids.add(pgf.getFunctions().get(i)); + } + + Collections.sort(ids); + + identifiers = ids; + sourceView.setText(""); + searchBox.setText(""); + } + public void onInputLanguageChanged() { } + public void onOutputLanguageChanged() { } + public void onStartCategoryChanged() { } + public void onSettingsError(String msg, Throwable e) { } + } +} \ No newline at end of file diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/CompletionOracle.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/CompletionOracle.java index 9e8fa35ec..6a8e5d1ed 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/CompletionOracle.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/CompletionOracle.java @@ -30,12 +30,10 @@ public class CompletionOracle extends SuggestOracle { this.errorHandler = errorHandler; pgf.addSettingsListener(new PGFWrapper.SettingsListener() { public void onAvailableGrammarsChanged() { clearState(); } - public void onAvailableLanguagesChanged() { clearState(); } + public void onSelectedGrammarChanged() { clearState(); } public void onInputLanguageChanged() { clearState(); } public void onOutputLanguageChanged() { clearState(); } - public void onAvailableCategoriesChanged() { clearState(); } public void onStartCategoryChanged() { clearState(); } - public void onAvailableFunctionsChanged() { clearState(); } public void onSettingsError(String msg, Throwable e) { clearState(); } }); } 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 2e20f713f..37270dffe 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 @@ -254,7 +254,7 @@ public class FridgeApp implements EntryPoint { } } } - public void onAvailableLanguagesChanged() { + public void onSelectedGrammarChanged() { if (pgf.getInputLanguage() == null) { pgf.setInputLanguage(pgf.getUserLanguage()); } @@ -265,13 +265,9 @@ public class FridgeApp implements EntryPoint { public void onOutputLanguageChanged() { update(); } - public void onAvailableCategoriesChanged() { - } public void onStartCategoryChanged() { update(); } - public void onAvailableFunctionsChanged() { - } public void onSettingsError(String msg, Throwable e) { showError(msg,e); } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGF.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGF.java index cd9fac9a8..5d742b737 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGF.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGF.java @@ -2,10 +2,9 @@ package se.chalmers.cs.gf.gwt.client; import se.chalmers.cs.gf.gwt.client.JSONRequestBuilder.Arg; -import com.google.gwt.core.client.JavaScriptObject; - -import java.util.List; -import java.util.ArrayList; +import java.util.*; +import com.google.gwt.core.client.*; +import com.google.gwt.http.client.*; public class PGF { @@ -29,9 +28,9 @@ public class PGF { public final native IterableJsArray getLanguages() /*-{ return this.languages; }-*/; - public final native IterableJsArray getCategories() /*-{ return this.categories; }-*/; + public final native JsArrayString getCategories() /*-{ return this.categories; }-*/; - public final native IterableJsArray getFunctions() /*-{ return this.functions; }-*/; + public final native JsArrayString getFunctions() /*-{ return this.functions; }-*/; } public static class Language extends JavaScriptObject { @@ -42,18 +41,6 @@ public class PGF { public final native boolean canParse() /*-{ return this.canParse; }-*/; } - public static class Category extends JavaScriptObject { - protected Category() { } - - public final native String getName() /*-{ return this.name; }-*/; - } - - public static class Function extends JavaScriptObject { - protected Function() { } - - public final native String getName() /*-{ return this.name; }-*/; - } - /* Translation */ public JSONRequest translate (String pgfURL, String input, String fromLang, String cat, String toLang, @@ -167,6 +154,26 @@ public class PGF { return JSONRequestBuilder.getQueryURL(pgfURL,args); } + public Request browse(String pgfURL, String id, String href, String cssClass, RequestCallback callback) { + List args = new ArrayList(); + args.add(new Arg("command", "browse")); + args.add(new Arg("id", id)); + args.add(new Arg("href", href)); + args.add(new Arg("css-class", cssClass)); + + Request request = null; + try { + RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, + JSONRequestBuilder.getQueryURL(pgfURL,args)); + builder.setCallback(callback); + request = builder.send(); + } catch (RequestException ex) { + callback.onError(request, ex); + } + + return request; + } + /* Common */ public JSONRequest sendGrammarRequest(String pgfURL, String resource, List args, final JSONCallback callback) { diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGFWrapper.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGFWrapper.java index 09b15ac07..f0729e0d7 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGFWrapper.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/PGFWrapper.java @@ -7,6 +7,7 @@ import java.util.LinkedList; import java.util.List; import com.google.gwt.http.client.*; import com.google.gwt.xml.client.*; +import com.google.gwt.core.client.*; public class PGFWrapper { @@ -36,8 +37,8 @@ public class PGFWrapper { private List parseableLanguages; - private List categories; - private List functions; + private JsArrayString categories; + private JsArrayString functions; // Event listeners @@ -114,19 +115,11 @@ public class PGFWrapper { parseableLanguages.add(name); } } - fireAvailableLanguagesChanged(); - categories = new ArrayList(); - for (PGF.Category category : grammar.getCategories().iterable()) { - categories.add(category.getName()); - } - fireAvailableCategoriesChanged(); + categories = grammar.getCategories(); + functions = grammar.getFunctions(); - functions = new ArrayList(); - for (PGF.Function function : grammar.getFunctions().iterable()) { - functions.add(function.getName()); - } - fireAvailableFunctionsChanged(); + fireSelectedGrammarChanged(); } public void onError (Throwable e) { @@ -163,6 +156,10 @@ public class PGFWrapper { return pgf.graphvizAlignment(grammarURL,abstractTree); } + public Request browse(String id, String href, String cssClass, RequestCallback callback) { + return pgf.browse(grammarURL, id, href, cssClass, callback); + } + // // Settings // @@ -220,11 +217,11 @@ public class PGFWrapper { fireStartCategoryChanged(); } - public List getCategories() { + public JsArrayString getCategories() { return categories; } - public List getFunctions() { + public JsArrayString getFunctions() { return functions; } @@ -267,23 +264,19 @@ public class PGFWrapper { public interface SettingsListener { public void onAvailableGrammarsChanged(); - public void onAvailableLanguagesChanged(); + public void onSelectedGrammarChanged(); public void onInputLanguageChanged(); public void onOutputLanguageChanged(); - public void onAvailableCategoriesChanged(); public void onStartCategoryChanged(); - public void onAvailableFunctionsChanged(); public void onSettingsError(String msg, Throwable e); } public static class SettingsAdapter implements SettingsListener { public void onAvailableGrammarsChanged() {} - public void onAvailableLanguagesChanged() {} + public void onSelectedGrammarChanged() {} public void onInputLanguageChanged() {} public void onOutputLanguageChanged() {} - public void onAvailableCategoriesChanged() {} public void onStartCategoryChanged() {} - public void onAvailableFunctionsChanged() {} public void onSettingsError(String msg, Throwable e) {} } @@ -297,9 +290,9 @@ public class PGFWrapper { } } - protected void fireAvailableLanguagesChanged() { + protected void fireSelectedGrammarChanged() { for (SettingsListener listener : listeners) { - listener.onAvailableLanguagesChanged(); + listener.onSelectedGrammarChanged(); } } @@ -315,23 +308,11 @@ public class PGFWrapper { } } - protected void fireAvailableCategoriesChanged() { - for (SettingsListener listener : listeners) { - listener.onAvailableCategoriesChanged(); - } - } - protected void fireStartCategoryChanged() { for (SettingsListener listener : listeners) { listener.onStartCategoryChanged(); } } - - protected void fireAvailableFunctionsChanged() { - for (SettingsListener listener : listeners) { - listener.onAvailableFunctionsChanged(); - } - } protected void fireSettingsError(String msg, Throwable e) { for (SettingsListener listener : listeners) { diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/SettingsPanel.java b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/SettingsPanel.java index 141631c1d..eb5155261 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/SettingsPanel.java +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/client/SettingsPanel.java @@ -75,7 +75,7 @@ public class SettingsPanel extends Composite { grammarBox.addItems(pgf.getGrammars()); } } - public void onAvailableLanguagesChanged() { + public void onSelectedGrammarChanged() { if (grammarBox != null) { grammarBox.setSelectedValue(pgf.getPGFName()); } @@ -108,9 +108,7 @@ public class SettingsPanel extends Composite { toLangBox.setSelectedValue(pgf.getOutputLanguage()); } } - public void onAvailableCategoriesChanged() { } public void onStartCategoryChanged() { } - public void onAvailableFunctionsChanged() { } public void onSettingsError(String msg, Throwable e) { } } 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 46f6329a4..d662f7011 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 @@ -17,6 +17,8 @@ public class TranslateApp implements EntryPoint { protected SuggestPanel suggestPanel; protected VerticalPanel outputPanel; + protected Widget translatePanel; + protected BrowsePanel browsePanel; protected StatusPopup statusPopup; // @@ -201,12 +203,28 @@ public class TranslateApp implements EntryPoint { // protected Widget createUI() { + translatePanel = createTranslatePanel(); + browsePanel = createBrowsePanel(); + VerticalPanel vPanel = new VerticalPanel(); + + HorizontalPanel hPanel = new HorizontalPanel(); + hPanel.setVerticalAlignment(HorizontalPanel.ALIGN_MIDDLE); + hPanel.setStylePrimaryName("my-HeaderPanel"); + + Widget linksPanel = createLinksPanel(vPanel); + hPanel.add(linksPanel); + hPanel.setCellHorizontalAlignment(linksPanel,HorizontalPanel.ALIGN_LEFT); + + Widget settingsPanel = createSettingsPanel(); + hPanel.add(settingsPanel); + hPanel.setCellHorizontalAlignment(settingsPanel,HorizontalPanel.ALIGN_RIGHT); + vPanel.setWidth("100%"); vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER); - vPanel.add(createSuggestPanel()); - vPanel.add(createSettingsPanel()); - vPanel.add(createTranslationsPanel()); + vPanel.add(hPanel); + vPanel.add(translatePanel); + return vPanel; } @@ -231,6 +249,43 @@ public class TranslateApp implements EntryPoint { return outputPanel; } + protected Widget createTranslatePanel() { + VerticalPanel translatePanel = new VerticalPanel(); + translatePanel.add(createSuggestPanel()); + translatePanel.add(createTranslationsPanel()); + return translatePanel; + } + + protected BrowsePanel createBrowsePanel() { + return new BrowsePanel(pgf); + } + + protected Widget createLinksPanel(final Panel parent) { + HorizontalPanel linksPanel = new HorizontalPanel(); + linksPanel.setStylePrimaryName("my-LinksPanel"); + + Hyperlink translateLink = new Hyperlink("Translate", null); + translateLink.addClickListener(new ClickListener() { + public void onClick(Widget sender) { + parent.remove(browsePanel); + parent.add(translatePanel); + } + }); + linksPanel.add(translateLink); + + Hyperlink browseLink = new Hyperlink("Browse", null); + browseLink.addClickListener(new ClickListener() { + public void onClick(Widget sender) { + parent.remove(translatePanel); + parent.add(browsePanel); + browsePanel.onActivate(); + } + }); + linksPanel.add(browseLink); + + return linksPanel; + } + protected Widget createLoadingWidget () { VerticalPanel loadingPanel = new VerticalPanel(); loadingPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER); @@ -287,7 +342,7 @@ public class TranslateApp implements EntryPoint { } } } - public void onAvailableLanguagesChanged() { + public void onSelectedGrammarChanged() { if (pgf.getInputLanguage() == null) { GWT.log("Setting input language to user language: " + pgf.getUserLanguage(), null); pgf.setInputLanguage(pgf.getUserLanguage()); @@ -300,13 +355,9 @@ public class TranslateApp implements EntryPoint { public void onOutputLanguageChanged() { update(); } - public void onAvailableCategoriesChanged() { - } public void onStartCategoryChanged() { update(); } - public void onAvailableFunctionsChanged() { - } public void onSettingsError(String msg, Throwable e) { showError(msg,e); } diff --git a/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Translate.css b/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Translate.css index 90fcc75ea..2a9c80528 100644 --- a/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Translate.css +++ b/src/server/gwt/src/se/chalmers/cs/gf/gwt/public/Translate.css @@ -20,6 +20,34 @@ margin: 0 0.4em; } +.my-LinksPanel * { + margin: 0 0.1em; +} + +.my-HeaderPanel { + width: 100%; + margin: 0 0.1em; + padding-top: 2px; + padding-bottom: 2px; + border-bottom-style: solid; + border-bottom-width: 1px; + border-bottom-color: rgb(122,165,214); +} + +.my-BrowsePanel { + width: 100%; + margin: 1em; + border-width: 5px; + border-color: rgb(122,165,214); +} + +.my-BrowseFrame { + width: 100%; + height: 100%; + margin: 1em; + border-style:none; +} + .my-translations { margin-top: 1em; } @@ -59,6 +87,17 @@ height: 300px; } +.my-identifierLink:link { + text-decoration: none; + color: black; +} + +.my-identifierLink:hover { + text-decoration: none; + color: black; + background-color: silver; +} + /* * [LANG=bg] { background-image: url("flags/bg.png"); } * [LANG=ca] { background-image: url("flags/catalonia.png"); }