Java tutorial
/* * Copyright 2010, Red Hat, Inc. and individual contributors as indicated by the * @author tags. See the copyright.txt file in the distribution for a full * listing of individual contributors. * * This is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF * site: http://www.fsf.org. */ package org.zanata.webtrans.client.view; import org.zanata.rest.dto.stats.ContainerTranslationStatistics; import org.zanata.util.CoverageIgnore; import org.zanata.webtrans.client.Application; import org.zanata.webtrans.client.events.NotificationEvent; import org.zanata.webtrans.client.presenter.KeyShortcutPresenter; import org.zanata.webtrans.client.presenter.MainView; import org.zanata.webtrans.client.presenter.NotificationDetailListener; import org.zanata.webtrans.client.presenter.SearchResultsPresenter; import org.zanata.webtrans.client.presenter.TranslationPresenter; import org.zanata.webtrans.client.resources.WebTransMessages; import org.zanata.webtrans.client.ui.Breadcrumb; import org.zanata.webtrans.client.ui.HasTranslationStats.LabelFormat; import org.zanata.webtrans.client.ui.NotificationDetailsBox; import org.zanata.webtrans.client.ui.TransUnitCountBar; import org.zanata.webtrans.client.ui.UnorderedListWidget; import org.zanata.webtrans.shared.model.UserWorkspaceContext; import com.google.gwt.core.shared.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.dom.client.UListElement; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.resources.client.CssResource; import com.google.gwt.safehtml.client.SafeHtmlTemplates; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlBuilder; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.InlineLabel; import com.google.gwt.user.client.ui.LayoutPanel; import com.google.gwt.user.client.ui.TabLayoutPanel; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; public class AppView extends Composite implements AppDisplay, NotificationDetailListener { private Timer deactivateNotificationTimer = new Timer() { @Override public void run() { deactivateNotification(notificationList); } }; interface AppViewUiBinder extends UiBinder<LayoutPanel, AppView> { } interface Styles extends CssResource { String disableTab(); String selectedTab(); String highlightedTab(); } private static AppViewUiBinder uiBinder = GWT.create(AppViewUiBinder.class); private static NotificationTemplate notificationTemplate = GWT.create(NotificationTemplate.class); private static final String ELLIPSIS = ""; private static final int MAX_LENGTH_DOC_NAME = 66; @UiField(provided = true) TransUnitCountBar translationStatsBar; @UiField InlineLabel readOnlyLabel; @UiField InlineLabel obsoleteLabel; @UiField(provided = true) Breadcrumb selectedDocumentSpan; @UiField(provided = true) Breadcrumb projectLink; @UiField(provided = true) Breadcrumb versionLink; @UiField(provided = true) Breadcrumb filesLink; @UiField LayoutPanel sideMenuContainer, rootContainer; @UiField HTMLPanel contentContainer; @UiField TabLayoutPanel content; @UiField Styles style; @UiField Anchor editorTab, searchAndReplaceTab, documentListTab, keyShortcuts; @UiField(provided = true) Anchor newEditorLink; @UiField UnorderedListWidget notifications; @UiField UListElement notificationList; private final NotificationDetailsBox notificationDetailsBox; private final WebTransMessages messages; private Listener listener; private final UserWorkspaceContext userWorkspaceContext; @Inject public AppView(WebTransMessages messages, DocumentListDisplay documentListView, SearchResultsPresenter.Display searchResultsView, TranslationPresenter.Display translationView, SideMenuDisplay sideMenuView, KeyShortcutPresenter keyShortcutPresenter, final UserWorkspaceContext userWorkspaceContext) { // this must be initialized before uiBinder.createAndBindUi(), or an // exception will be thrown at runtime this.userWorkspaceContext = userWorkspaceContext; this.messages = messages; translationStatsBar = new TransUnitCountBar(userWorkspaceContext, messages, LabelFormat.PERCENT_COMPLETE_HRS, true); // hide until there is a value to translationStatsBar.setVisible(false); projectLink = new Breadcrumb(true, false, Application.getProjectHomeURL(userWorkspaceContext.getWorkspaceContext().getWorkspaceId())); versionLink = new Breadcrumb(false, false, Application.getVersionHomeURL(userWorkspaceContext.getWorkspaceContext().getWorkspaceId())); filesLink = new Breadcrumb(false, false, ""); // filesLink.setHref(Application.getVersionFilesURL(userWorkspaceContext.getWorkspaceContext().getWorkspaceId())); selectedDocumentSpan = new Breadcrumb(false, true, ""); newEditorLink = new Anchor(); newEditorLink.setTarget("_blank"); newEditorLink.setText(messages.newEditorMessage()); newEditorLink.addStyleName("is-invisible"); initWidget(uiBinder.createAndBindUi(this)); readOnlyLabel.setTitle(messages.readOnlyTooltip()); obsoleteLabel.setTitle(messages.obsoleteTooltip()); keyShortcuts.setTitle(messages.availableKeyShortcutsTitle()); sideMenuContainer.add(sideMenuView.asWidget()); searchAndReplaceTab.setTitle(messages.projectWideSearchAndReplace()); documentListTab.setTitle(messages.documentListTitle()); editorTab.setTitle(messages.editor()); content.add(documentListView.asWidget()); content.add(translationView.asWidget()); content.add(searchResultsView.asWidget()); notificationDetailsBox = new NotificationDetailsBox(messages, keyShortcutPresenter); notifications.ensureDebugId("notifications"); Window.enableScrolling(false); } @Override public Widget asWidget() { return this; } // Order of the tab private final static int DOCUMENT_VIEW = 0; private final static int EDITOR_VIEW = 1; private final static int SEARCH_AND_REPLACE_VIEW = 2; private final static int REVIEW_VIEW = 3; @Override public void showInMainView(MainView view) { switch (view) { case Documents: content.selectTab(DOCUMENT_VIEW); selectedDocumentSpan.setVisible(false); newEditorLink.addStyleName("is-invisible"); setSelectedTab(documentListTab); break; case Search: content.selectTab(SEARCH_AND_REPLACE_VIEW); selectedDocumentSpan.setVisible(true); newEditorLink.addStyleName("is-invisible"); setSelectedTab(searchAndReplaceTab); break; case Editor: content.selectTab(EDITOR_VIEW); selectedDocumentSpan.setVisible(true); newEditorLink.removeStyleName("is-invisible"); setSelectedTab(editorTab); } } private void setSelectedTab(Widget tab) { editorTab.removeStyleName(style.selectedTab()); searchAndReplaceTab.removeStyleName(style.selectedTab()); documentListTab.removeStyleName(style.selectedTab()); tab.addStyleName(style.selectedTab()); } @Override public void setProjectLinkLabel(String text) { projectLink.setText(text); } @Override public void setVersionLinkLabel(String text) { versionLink.setText(text); } @Override public void setFilesLinkLabel(String text) { filesLink.setText(text); } @Override public void setListener(Listener listener) { this.listener = listener; } public static String shorten(String s, int maxLength) { if (s.length() <= maxLength) { return s; } return s.substring(0, maxLength - ELLIPSIS.length()) + ELLIPSIS; } @Override public void setDocumentLabel(String docPath, String docName) { String selectedDocId = docPath + docName; selectedDocumentSpan.setText(shorten(selectedDocId, MAX_LENGTH_DOC_NAME)); newEditorLink .setHref(Application.getNewEditorLink(userWorkspaceContext.getWorkspaceContext().getWorkspaceId(), // docId does not need to substitute / with , since the redux // editor treats everything between the version slug and query // string as docId. selectedDocId)); } @Override public void setStats(ContainerTranslationStatistics transStats, boolean statsByWords) { translationStatsBar.setStats(transStats, statsByWords); translationStatsBar.setVisible(true); } @Override public void setReadOnlyVisible(boolean visible) { readOnlyLabel.setVisible(visible); } @Override public void setObsoleteVisible(boolean visible) { obsoleteLabel.setVisible(visible); } private final static double MIN_MENU_WIDTH = 2; private final static double EXPENDED_MENU_RIGHT = 23; private final static double MINIMISED_EDITOR_RIGHT = 21.5; private final static int ANIMATE_DURATION = 100; @Override public void showSideMenu(boolean isShowing) { rootContainer.forceLayout(); if (isShowing) { rootContainer.setWidgetLeftRight(contentContainer, 0.0, Unit.EM, MINIMISED_EDITOR_RIGHT, Unit.EM); rootContainer.setWidgetRightWidth(sideMenuContainer, 0.0, Unit.PX, EXPENDED_MENU_RIGHT, Unit.EM); } else { rootContainer.setWidgetLeftRight(contentContainer, 0.0, Unit.EM, 0.0, Unit.EM); rootContainer.setWidgetRightWidth(sideMenuContainer, 0.0, Unit.EM, MIN_MENU_WIDTH, Unit.EM); } rootContainer.animate(ANIMATE_DURATION); } @UiHandler("keyShortcuts") public void onKeyShortcutsIconClick(ClickEvent event) { listener.onKeyShortcutsClicked(); } @Override public void enableTab(MainView view, boolean enable) { switch (view) { case Search: enableTab(searchAndReplaceTab, enable); break; case Documents: enableTab(documentListTab, enable); break; case Editor: enableTab(editorTab, enable); break; } } @UiHandler("filesLink") public void onFilesLinkClick(ClickEvent event) { listener.onDocumentListClicked(); } @UiHandler("documentListTab") public void onDocumentListTabClick(ClickEvent event) { listener.onDocumentListClicked(); } @UiHandler("editorTab") public void onEditorTabClick(ClickEvent event) { listener.onEditorClicked(); } @UiHandler("searchAndReplaceTab") public void onSearchAndReplaceTabTabClick(ClickEvent event) { listener.onSearchAndReplaceClicked(); } private void enableTab(Widget tab, boolean enable) { if (enable) { tab.removeStyleName(style.disableTab()); } else { tab.addStyleName(style.disableTab()); } } @Override public void setKeyboardShorcutColor(boolean aliasKeyListening) { if (aliasKeyListening) { keyShortcuts.addStyleName(style.highlightedTab()); } else { keyShortcuts.removeStyleName(style.highlightedTab()); } } public void showNotification(NotificationEvent notification) { notificationList.setInnerHTML( createListItem(getMessageClass(notification.getSeverity()), notification.getMessage()).asString()); activateNotification(notificationList); if (notification.getSeverity() == NotificationEvent.Severity.Info || notification.getSeverity() == NotificationEvent.Severity.Warning) { deactivateNotificationTimer.schedule(5000); } } @Override public void showNotificationDetail(NotificationEvent notificationEvent) { notificationDetailsBox.setMessage(notificationEvent); notificationDetailsBox.center(); } @Override public void closeMessage(NotificationEvent notificationEvent) { notifications.clear(); } private static SafeHtml createListItem(String messageStyle, String message) { return notificationTemplate.listItem(messageStyle, new SafeHtmlBuilder().appendEscaped(message).toSafeHtml()); } private static String getMessageClass(NotificationEvent.Severity severity) { switch (severity) { case Warning: return "message--warning"; case Error: return "message--danger app-error"; case Info: return "message--highlight"; } return "message--highlight"; } // @formatter:off @CoverageIgnore("JSNI") private static native void activateNotification(Element element) /*-{ $wnd.zanata.messages.activate(element); }-*/; @CoverageIgnore("JSNI") private static native void deactivateNotification(Element element) /*-{ $wnd.zanata.messages.deactivate(element); }-*/; // @formatter:on public interface NotificationTemplate extends SafeHtmlTemplates { @Template("<li class='{0} message--removable js-message-removable'>{1}" + "<a href='#' class='message__remove js-message-remove'><i class='i i--cancel'></i></a>" + "</li>") SafeHtml listItem(String messageStyle, SafeHtml message); } }