001/*
002 *  Copyright 2012 GWT-Bootstrap
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.github.gwtbootstrap.client.ui;
017
018import com.github.gwtbootstrap.client.ui.constants.Constants;
019import com.github.gwtbootstrap.client.ui.resources.prettify.HasProgrammingLanguage;
020import com.github.gwtbootstrap.client.ui.resources.prettify.PrettifyHelper;
021import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
022import com.google.gwt.user.client.ui.HTMLPanel;
023import com.google.gwt.user.client.ui.HasHTML;
024
025//@formatter:off
026/**
027 * Block of Code with syntax highlighting.
028 * <p>
029 * Line breaks have to be escaped with "\n".
030 * 
031 * <p>
032 * <h3>UiBinder Usage:</h3>
033 * 
034 * <pre>
035 * {@code 
036 * <b:CodeBlock linenums="true">}
037 *     public class Person { \n
038 *     \n
039 *     private final String name;\n
040 *     private final int age;\n
041 *     }
042 * {@code </b:CodeBlock>}
043 * </pre>
044 * All arguments are optional.
045 * 
046 * @since 2.0.4.0
047 * 
048 * @author Dominik Mayer
049 * 
050 * @author Carlos Alexandro Becker
051 * 
052 * @see <a href="http://twitter.github.com/bootstrap/base-css.html#code">Bootstrap documentation</a>
053 * @see Code
054 */
055//@formatter:on
056public class CodeBlock extends HTMLPanel implements HasProgrammingLanguage, HasHTML {
057
058        private final PrettifyHelper helper;
059        private boolean linenums = false;
060
061        /**
062         * Creates an empty widget.
063         */
064        public CodeBlock() {
065                super("pre", "");
066                helper = new PrettifyHelper(this);
067        }
068
069        /**
070         * Creates a widget with the content set.
071         * 
072         * @param content
073         *            the content of the widget
074         */
075        public CodeBlock(String content) {
076                this();
077                setHTML(content);
078        }
079
080        /**
081         * Sets whether the widget should be restricted to a maximum height of 350
082         * px with y-axis scrollbars enabled.
083         * 
084         * @param scrollable
085         *            <code>true</code> to show scrollbars. Default:
086         *            <code>false</code>
087         */
088        public void setScrollable(boolean scrollable) {
089                if (scrollable)
090                    addStyleName(Constants.PRE_SCROLLABLE);
091                else
092                        removeStyleName(Constants.PRE_SCROLLABLE);
093        }
094
095        /**
096         * Sets whether line numbers are shown.
097         * 
098         * @param linenums
099         *            <code>true</code> to show line numbers. Default:
100         *            <code>false</code>
101         */
102        public void setLinenums(boolean linenums) {
103                this.linenums = linenums;
104        }
105
106        /**
107         * {@inheritDoc}
108         */
109        public String getHTML() {
110                return getElement().getInnerHTML();
111        }
112
113        /**
114         * Sets the widget's text.
115         * <p>
116         * Any HTML content is escaped and displayed as text.
117         * 
118         * @param html
119         *            the text to be set
120         */
121        public void setHTML(String html) {
122                String[] lines = html.split("\\\\n");
123                SafeHtmlBuilder shb = new SafeHtmlBuilder();
124
125                for (String s : lines) {
126                        shb.appendEscaped(s);
127                        shb.appendHtmlConstant("<br/>");
128                }
129                
130                if(getStyleName().contains("prettyprinted")) {
131                    removeStyleName("prettyprinted");
132                }
133
134                getElement().setInnerHTML(shb.toSafeHtml().asString());
135                
136                if(isAttached()) {
137                    helper.configure(linenums);
138                }
139                
140        }
141
142        /**
143         * {@inheritDoc}
144         */
145        public String getText() {
146                return getHTML();
147        }
148
149        /**
150         * {@inheritDoc}
151         */
152        public void setText(String text) {
153                setHTML(text);
154        }
155
156        /**
157         * {@inheritDoc}
158         */
159        public void setLang(String programmingLanguage) {
160                helper.setLang(programmingLanguage);
161        }
162
163        /**
164         * {@inheritDoc}
165         */
166        @Override
167        protected void onLoad() {
168                super.onLoad();
169                helper.configure(linenums);
170        }
171}