mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-24 03:52:50 -06:00
TranslateApp now have browser for abstract syntax
This commit is contained in:
51
src/PGF.hs
51
src/PGF.hs
@@ -20,12 +20,12 @@ module PGF(
|
|||||||
-- * Identifiers
|
-- * Identifiers
|
||||||
CId, mkCId, wildCId,
|
CId, mkCId, wildCId,
|
||||||
showCId, readCId,
|
showCId, readCId,
|
||||||
|
|
||||||
-- * Languages
|
-- * Languages
|
||||||
Language,
|
Language,
|
||||||
showLanguage, readLanguage,
|
showLanguage, readLanguage,
|
||||||
languages, abstractName, languageCode,
|
languages, abstractName, languageCode,
|
||||||
|
|
||||||
-- * Types
|
-- * Types
|
||||||
Type, Hypo,
|
Type, Hypo,
|
||||||
showType, readType,
|
showType, readType,
|
||||||
@@ -55,10 +55,10 @@ module PGF(
|
|||||||
|
|
||||||
-- ** Parsing
|
-- ** Parsing
|
||||||
parse, parseWithRecovery, canParse, parseAllLang, parseAll,
|
parse, parseWithRecovery, canParse, parseAllLang, parseAll,
|
||||||
|
|
||||||
-- ** Evaluation
|
-- ** Evaluation
|
||||||
PGF.compute, paraphrase,
|
PGF.compute, paraphrase,
|
||||||
|
|
||||||
-- ** Type Checking
|
-- ** Type Checking
|
||||||
-- | The type checker in PGF does both type checking and renaming
|
-- | The type checker in PGF does both type checking and renaming
|
||||||
-- i.e. it verifies that all identifiers are declared and it
|
-- i.e. it verifies that all identifiers are declared and it
|
||||||
@@ -71,7 +71,7 @@ module PGF(
|
|||||||
-- also lead to metavariables instantiations.
|
-- also lead to metavariables instantiations.
|
||||||
checkType, checkExpr, inferExpr,
|
checkType, checkExpr, inferExpr,
|
||||||
TcError(..), ppTcError,
|
TcError(..), ppTcError,
|
||||||
|
|
||||||
-- ** Word Completion (Incremental Parsing)
|
-- ** Word Completion (Incremental Parsing)
|
||||||
complete,
|
complete,
|
||||||
Incremental.ParseState,
|
Incremental.ParseState,
|
||||||
@@ -79,7 +79,7 @@ module PGF(
|
|||||||
|
|
||||||
-- ** Generation
|
-- ** Generation
|
||||||
generateRandom, generateAll, generateAllDepth,
|
generateRandom, generateAll, generateAllDepth,
|
||||||
|
|
||||||
-- ** Morphological Analysis
|
-- ** Morphological Analysis
|
||||||
Lemma, Analysis, Morpho,
|
Lemma, Analysis, Morpho,
|
||||||
lookupMorpho, buildMorpho,
|
lookupMorpho, buildMorpho,
|
||||||
@@ -88,7 +88,10 @@ module PGF(
|
|||||||
graphvizAbstractTree,
|
graphvizAbstractTree,
|
||||||
graphvizParseTree,
|
graphvizParseTree,
|
||||||
graphvizDependencyTree,
|
graphvizDependencyTree,
|
||||||
graphvizAlignment
|
graphvizAlignment,
|
||||||
|
|
||||||
|
-- * Browsing
|
||||||
|
browse
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import PGF.CId
|
import PGF.CId
|
||||||
@@ -114,8 +117,10 @@ import qualified Data.Map as Map
|
|||||||
import qualified Data.IntMap as IntMap
|
import qualified Data.IntMap as IntMap
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Binary
|
import Data.Binary
|
||||||
|
import Data.List(mapAccumL)
|
||||||
import System.Random (newStdGen)
|
import System.Random (newStdGen)
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
import Text.PrettyPrint
|
||||||
|
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
-- Interface
|
-- Interface
|
||||||
@@ -313,3 +318,35 @@ complete pgf from typ input =
|
|||||||
-- | Converts an expression to normal form
|
-- | Converts an expression to normal form
|
||||||
compute :: PGF -> Expr -> Expr
|
compute :: PGF -> Expr -> Expr
|
||||||
compute pgf = PGF.Data.normalForm (funs (abstract pgf)) 0 []
|
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
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ module FastCGIUtils (initFastCGI, loopFastCGI,
|
|||||||
stderrToFile,
|
stderrToFile,
|
||||||
outputJSONP,
|
outputJSONP,
|
||||||
outputPNG,
|
outputPNG,
|
||||||
|
outputHTML,
|
||||||
splitBy) where
|
splitBy) where
|
||||||
|
|
||||||
import Control.Concurrent
|
import Control.Concurrent
|
||||||
@@ -170,6 +171,11 @@ outputPNG x = do
|
|||||||
setHeader "Content-Type" "image/png"
|
setHeader "Content-Type" "image/png"
|
||||||
outputStrict x
|
outputStrict x
|
||||||
|
|
||||||
|
outputHTML :: String -> CGI CGIResult
|
||||||
|
outputHTML x = do
|
||||||
|
setHeader "Content-Type" "text/html"
|
||||||
|
outputStrict x
|
||||||
|
|
||||||
outputStrict :: String -> CGI CGIResult
|
outputStrict :: String -> CGI CGIResult
|
||||||
outputStrict x | x == x = output x
|
outputStrict x | x == x = output x
|
||||||
| otherwise = fail "I am the pope."
|
| otherwise = fail "I am the pope."
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ pgfMain pgf command =
|
|||||||
"abstrtree" -> getTree >>= liftIO . doGraphvizAbstrTree pgf >>= outputPNG
|
"abstrtree" -> getTree >>= liftIO . doGraphvizAbstrTree pgf >>= outputPNG
|
||||||
"parsetree" -> getTree >>= \t -> getFrom >>= \(Just l) -> liftIO (doGraphvizParseTree pgf l t) >>= outputPNG
|
"parsetree" -> getTree >>= \t -> getFrom >>= \(Just l) -> liftIO (doGraphvizParseTree pgf l t) >>= outputPNG
|
||||||
"alignment" -> getTree >>= liftIO . doGraphvizAlignment pgf >>= 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]
|
_ -> throwCGIError 400 "Unknown command" ["Unknown command: " ++ show command]
|
||||||
where
|
where
|
||||||
getText :: CGI String
|
getText :: CGI String
|
||||||
@@ -78,6 +79,18 @@ pgfMain pgf command =
|
|||||||
getTo :: CGI (Maybe PGF.Language)
|
getTo :: CGI (Maybe PGF.Language)
|
||||||
getTo = getLang "to"
|
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 :: CGI (Maybe Int)
|
||||||
getLimit = readInput "limit"
|
getLimit = readInput "limit"
|
||||||
|
|
||||||
@@ -139,8 +152,8 @@ doGrammar pgf macc = showJSON $ toJSObject
|
|||||||
("languageCode", showJSON $ fromMaybe "" (PGF.languageCode pgf l)),
|
("languageCode", showJSON $ fromMaybe "" (PGF.languageCode pgf l)),
|
||||||
("canParse", showJSON $ PGF.canParse pgf l)]
|
("canParse", showJSON $ PGF.canParse pgf l)]
|
||||||
| l <- PGF.languages pgf]
|
| l <- PGF.languages pgf]
|
||||||
categories = map toJSObject [[("name", PGF.showCId cat)] | cat <- PGF.categories pgf]
|
categories = [PGF.showCId cat | cat <- PGF.categories pgf]
|
||||||
functions = map toJSObject [[("name", PGF.showCId fun)] | fun <- PGF.functions pgf]
|
functions = [PGF.showCId fun | fun <- PGF.functions pgf]
|
||||||
|
|
||||||
doGraphvizAbstrTree pgf tree = do
|
doGraphvizAbstrTree pgf tree = do
|
||||||
let dot = PGF.graphvizAbstractTree pgf (True,True) tree
|
let dot = PGF.graphvizAbstractTree pgf (True,True) tree
|
||||||
@@ -154,6 +167,51 @@ doGraphvizAlignment pgf tree = do
|
|||||||
let dot = PGF.graphvizAlignment pgf tree
|
let dot = PGF.graphvizAlignment pgf tree
|
||||||
readProcess "dot" ["-T","png"] (UTF8.encodeString dot)
|
readProcess "dot" ["-T","png"] (UTF8.encodeString dot)
|
||||||
|
|
||||||
|
doBrowse pgf id cssClass href =
|
||||||
|
case PGF.browse pgf id of
|
||||||
|
Just (def,ps,cs) -> "<PRE>"++annotate def++"</PRE>\n"++
|
||||||
|
(if not (null ps)
|
||||||
|
then "<BR/>"++
|
||||||
|
"<H3>Producers</H3>"++
|
||||||
|
"<P>"++annotateCIds ps++"</P>\n"
|
||||||
|
else "")++
|
||||||
|
(if not (null cs)
|
||||||
|
then "<BR/>"++
|
||||||
|
"<H3>Consumers</H3>"++
|
||||||
|
"<P>"++annotateCIds cs++"</P>\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 "<B>"++id++"</B>"
|
||||||
|
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 = "<A "++hrefAttr s++" "++classAttr++">"++s++"</A>"
|
||||||
|
|
||||||
instance JSON PGF.CId where
|
instance JSON PGF.CId where
|
||||||
readJSON x = readJSON x >>= maybe (fail "Bad language.") return . PGF.readLanguage
|
readJSON x = readJSON x >>= maybe (fail "Bad language.") return . PGF.readLanguage
|
||||||
showJSON = showJSON . PGF.showLanguage
|
showJSON = showJSON . PGF.showLanguage
|
||||||
|
|||||||
156
src/server/gwt/src/se/chalmers/cs/gf/gwt/client/BrowsePanel.java
Normal file
156
src/server/gwt/src/se/chalmers/cs/gf/gwt/client/BrowsePanel.java
Normal file
@@ -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<String> 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<CompletionSuggestion> 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<String> 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) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,12 +30,10 @@ public class CompletionOracle extends SuggestOracle {
|
|||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
pgf.addSettingsListener(new PGFWrapper.SettingsListener() {
|
pgf.addSettingsListener(new PGFWrapper.SettingsListener() {
|
||||||
public void onAvailableGrammarsChanged() { clearState(); }
|
public void onAvailableGrammarsChanged() { clearState(); }
|
||||||
public void onAvailableLanguagesChanged() { clearState(); }
|
public void onSelectedGrammarChanged() { clearState(); }
|
||||||
public void onInputLanguageChanged() { clearState(); }
|
public void onInputLanguageChanged() { clearState(); }
|
||||||
public void onOutputLanguageChanged() { clearState(); }
|
public void onOutputLanguageChanged() { clearState(); }
|
||||||
public void onAvailableCategoriesChanged() { clearState(); }
|
|
||||||
public void onStartCategoryChanged() { clearState(); }
|
public void onStartCategoryChanged() { clearState(); }
|
||||||
public void onAvailableFunctionsChanged() { clearState(); }
|
|
||||||
public void onSettingsError(String msg, Throwable e) { clearState(); }
|
public void onSettingsError(String msg, Throwable e) { clearState(); }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ public class FridgeApp implements EntryPoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onAvailableLanguagesChanged() {
|
public void onSelectedGrammarChanged() {
|
||||||
if (pgf.getInputLanguage() == null) {
|
if (pgf.getInputLanguage() == null) {
|
||||||
pgf.setInputLanguage(pgf.getUserLanguage());
|
pgf.setInputLanguage(pgf.getUserLanguage());
|
||||||
}
|
}
|
||||||
@@ -265,13 +265,9 @@ public class FridgeApp implements EntryPoint {
|
|||||||
public void onOutputLanguageChanged() {
|
public void onOutputLanguageChanged() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
public void onAvailableCategoriesChanged() {
|
|
||||||
}
|
|
||||||
public void onStartCategoryChanged() {
|
public void onStartCategoryChanged() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
public void onAvailableFunctionsChanged() {
|
|
||||||
}
|
|
||||||
public void onSettingsError(String msg, Throwable e) {
|
public void onSettingsError(String msg, Throwable e) {
|
||||||
showError(msg,e);
|
showError(msg,e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ package se.chalmers.cs.gf.gwt.client;
|
|||||||
|
|
||||||
import se.chalmers.cs.gf.gwt.client.JSONRequestBuilder.Arg;
|
import se.chalmers.cs.gf.gwt.client.JSONRequestBuilder.Arg;
|
||||||
|
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import java.util.*;
|
||||||
|
import com.google.gwt.core.client.*;
|
||||||
import java.util.List;
|
import com.google.gwt.http.client.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class PGF {
|
public class PGF {
|
||||||
|
|
||||||
@@ -29,9 +28,9 @@ public class PGF {
|
|||||||
|
|
||||||
public final native IterableJsArray<Language> getLanguages() /*-{ return this.languages; }-*/;
|
public final native IterableJsArray<Language> getLanguages() /*-{ return this.languages; }-*/;
|
||||||
|
|
||||||
public final native IterableJsArray<Category> getCategories() /*-{ return this.categories; }-*/;
|
public final native JsArrayString getCategories() /*-{ return this.categories; }-*/;
|
||||||
|
|
||||||
public final native IterableJsArray<Function> getFunctions() /*-{ return this.functions; }-*/;
|
public final native JsArrayString getFunctions() /*-{ return this.functions; }-*/;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Language extends JavaScriptObject {
|
public static class Language extends JavaScriptObject {
|
||||||
@@ -42,18 +41,6 @@ public class PGF {
|
|||||||
public final native boolean canParse() /*-{ return this.canParse; }-*/;
|
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 */
|
/* Translation */
|
||||||
|
|
||||||
public JSONRequest translate (String pgfURL, String input, String fromLang, String cat, String toLang,
|
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);
|
return JSONRequestBuilder.getQueryURL(pgfURL,args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Request browse(String pgfURL, String id, String href, String cssClass, RequestCallback callback) {
|
||||||
|
List<Arg> args = new ArrayList<Arg>();
|
||||||
|
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 */
|
/* Common */
|
||||||
|
|
||||||
public <T extends JavaScriptObject> JSONRequest sendGrammarRequest(String pgfURL, String resource, List<Arg> args, final JSONCallback<T> callback) {
|
public <T extends JavaScriptObject> JSONRequest sendGrammarRequest(String pgfURL, String resource, List<Arg> args, final JSONCallback<T> callback) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.google.gwt.http.client.*;
|
import com.google.gwt.http.client.*;
|
||||||
import com.google.gwt.xml.client.*;
|
import com.google.gwt.xml.client.*;
|
||||||
|
import com.google.gwt.core.client.*;
|
||||||
|
|
||||||
public class PGFWrapper {
|
public class PGFWrapper {
|
||||||
|
|
||||||
@@ -36,8 +37,8 @@ public class PGFWrapper {
|
|||||||
|
|
||||||
private List<String> parseableLanguages;
|
private List<String> parseableLanguages;
|
||||||
|
|
||||||
private List<String> categories;
|
private JsArrayString categories;
|
||||||
private List<String> functions;
|
private JsArrayString functions;
|
||||||
|
|
||||||
// Event listeners
|
// Event listeners
|
||||||
|
|
||||||
@@ -114,19 +115,11 @@ public class PGFWrapper {
|
|||||||
parseableLanguages.add(name);
|
parseableLanguages.add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fireAvailableLanguagesChanged();
|
|
||||||
|
|
||||||
categories = new ArrayList<String>();
|
categories = grammar.getCategories();
|
||||||
for (PGF.Category category : grammar.getCategories().iterable()) {
|
functions = grammar.getFunctions();
|
||||||
categories.add(category.getName());
|
|
||||||
}
|
|
||||||
fireAvailableCategoriesChanged();
|
|
||||||
|
|
||||||
functions = new ArrayList<String>();
|
fireSelectedGrammarChanged();
|
||||||
for (PGF.Function function : grammar.getFunctions().iterable()) {
|
|
||||||
functions.add(function.getName());
|
|
||||||
}
|
|
||||||
fireAvailableFunctionsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onError (Throwable e) {
|
public void onError (Throwable e) {
|
||||||
@@ -163,6 +156,10 @@ public class PGFWrapper {
|
|||||||
return pgf.graphvizAlignment(grammarURL,abstractTree);
|
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
|
// Settings
|
||||||
//
|
//
|
||||||
@@ -220,11 +217,11 @@ public class PGFWrapper {
|
|||||||
fireStartCategoryChanged();
|
fireStartCategoryChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getCategories() {
|
public JsArrayString getCategories() {
|
||||||
return categories;
|
return categories;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getFunctions() {
|
public JsArrayString getFunctions() {
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,23 +264,19 @@ public class PGFWrapper {
|
|||||||
|
|
||||||
public interface SettingsListener {
|
public interface SettingsListener {
|
||||||
public void onAvailableGrammarsChanged();
|
public void onAvailableGrammarsChanged();
|
||||||
public void onAvailableLanguagesChanged();
|
public void onSelectedGrammarChanged();
|
||||||
public void onInputLanguageChanged();
|
public void onInputLanguageChanged();
|
||||||
public void onOutputLanguageChanged();
|
public void onOutputLanguageChanged();
|
||||||
public void onAvailableCategoriesChanged();
|
|
||||||
public void onStartCategoryChanged();
|
public void onStartCategoryChanged();
|
||||||
public void onAvailableFunctionsChanged();
|
|
||||||
public void onSettingsError(String msg, Throwable e);
|
public void onSettingsError(String msg, Throwable e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SettingsAdapter implements SettingsListener {
|
public static class SettingsAdapter implements SettingsListener {
|
||||||
public void onAvailableGrammarsChanged() {}
|
public void onAvailableGrammarsChanged() {}
|
||||||
public void onAvailableLanguagesChanged() {}
|
public void onSelectedGrammarChanged() {}
|
||||||
public void onInputLanguageChanged() {}
|
public void onInputLanguageChanged() {}
|
||||||
public void onOutputLanguageChanged() {}
|
public void onOutputLanguageChanged() {}
|
||||||
public void onAvailableCategoriesChanged() {}
|
|
||||||
public void onStartCategoryChanged() {}
|
public void onStartCategoryChanged() {}
|
||||||
public void onAvailableFunctionsChanged() {}
|
|
||||||
public void onSettingsError(String msg, Throwable e) {}
|
public void onSettingsError(String msg, Throwable e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,9 +290,9 @@ public class PGFWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fireAvailableLanguagesChanged() {
|
protected void fireSelectedGrammarChanged() {
|
||||||
for (SettingsListener listener : listeners) {
|
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() {
|
protected void fireStartCategoryChanged() {
|
||||||
for (SettingsListener listener : listeners) {
|
for (SettingsListener listener : listeners) {
|
||||||
listener.onStartCategoryChanged();
|
listener.onStartCategoryChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fireAvailableFunctionsChanged() {
|
|
||||||
for (SettingsListener listener : listeners) {
|
|
||||||
listener.onAvailableFunctionsChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void fireSettingsError(String msg, Throwable e) {
|
protected void fireSettingsError(String msg, Throwable e) {
|
||||||
for (SettingsListener listener : listeners) {
|
for (SettingsListener listener : listeners) {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public class SettingsPanel extends Composite {
|
|||||||
grammarBox.addItems(pgf.getGrammars());
|
grammarBox.addItems(pgf.getGrammars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onAvailableLanguagesChanged() {
|
public void onSelectedGrammarChanged() {
|
||||||
if (grammarBox != null) {
|
if (grammarBox != null) {
|
||||||
grammarBox.setSelectedValue(pgf.getPGFName());
|
grammarBox.setSelectedValue(pgf.getPGFName());
|
||||||
}
|
}
|
||||||
@@ -108,9 +108,7 @@ public class SettingsPanel extends Composite {
|
|||||||
toLangBox.setSelectedValue(pgf.getOutputLanguage());
|
toLangBox.setSelectedValue(pgf.getOutputLanguage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onAvailableCategoriesChanged() { }
|
|
||||||
public void onStartCategoryChanged() { }
|
public void onStartCategoryChanged() { }
|
||||||
public void onAvailableFunctionsChanged() { }
|
|
||||||
public void onSettingsError(String msg, Throwable e) { }
|
public void onSettingsError(String msg, Throwable e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public class TranslateApp implements EntryPoint {
|
|||||||
|
|
||||||
protected SuggestPanel suggestPanel;
|
protected SuggestPanel suggestPanel;
|
||||||
protected VerticalPanel outputPanel;
|
protected VerticalPanel outputPanel;
|
||||||
|
protected Widget translatePanel;
|
||||||
|
protected BrowsePanel browsePanel;
|
||||||
protected StatusPopup statusPopup;
|
protected StatusPopup statusPopup;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -201,12 +203,28 @@ public class TranslateApp implements EntryPoint {
|
|||||||
//
|
//
|
||||||
|
|
||||||
protected Widget createUI() {
|
protected Widget createUI() {
|
||||||
|
translatePanel = createTranslatePanel();
|
||||||
|
browsePanel = createBrowsePanel();
|
||||||
|
|
||||||
VerticalPanel vPanel = new VerticalPanel();
|
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.setWidth("100%");
|
||||||
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
|
vPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
|
||||||
vPanel.add(createSuggestPanel());
|
vPanel.add(hPanel);
|
||||||
vPanel.add(createSettingsPanel());
|
vPanel.add(translatePanel);
|
||||||
vPanel.add(createTranslationsPanel());
|
|
||||||
return vPanel;
|
return vPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +249,43 @@ public class TranslateApp implements EntryPoint {
|
|||||||
return outputPanel;
|
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 () {
|
protected Widget createLoadingWidget () {
|
||||||
VerticalPanel loadingPanel = new VerticalPanel();
|
VerticalPanel loadingPanel = new VerticalPanel();
|
||||||
loadingPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
|
loadingPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
|
||||||
@@ -287,7 +342,7 @@ public class TranslateApp implements EntryPoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void onAvailableLanguagesChanged() {
|
public void onSelectedGrammarChanged() {
|
||||||
if (pgf.getInputLanguage() == null) {
|
if (pgf.getInputLanguage() == null) {
|
||||||
GWT.log("Setting input language to user language: " + pgf.getUserLanguage(), null);
|
GWT.log("Setting input language to user language: " + pgf.getUserLanguage(), null);
|
||||||
pgf.setInputLanguage(pgf.getUserLanguage());
|
pgf.setInputLanguage(pgf.getUserLanguage());
|
||||||
@@ -300,13 +355,9 @@ public class TranslateApp implements EntryPoint {
|
|||||||
public void onOutputLanguageChanged() {
|
public void onOutputLanguageChanged() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
public void onAvailableCategoriesChanged() {
|
|
||||||
}
|
|
||||||
public void onStartCategoryChanged() {
|
public void onStartCategoryChanged() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
public void onAvailableFunctionsChanged() {
|
|
||||||
}
|
|
||||||
public void onSettingsError(String msg, Throwable e) {
|
public void onSettingsError(String msg, Throwable e) {
|
||||||
showError(msg,e);
|
showError(msg,e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,34 @@
|
|||||||
margin: 0 0.4em;
|
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 {
|
.my-translations {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
@@ -59,6 +87,17 @@
|
|||||||
height: 300px;
|
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=bg] { background-image: url("flags/bg.png"); }
|
||||||
* [LANG=ca] { background-image: url("flags/catalonia.png"); }
|
* [LANG=ca] { background-image: url("flags/catalonia.png"); }
|
||||||
|
|||||||
Reference in New Issue
Block a user