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"); }