001    /*
002     * Copyright (C) 2010 eXo Platform SAS.
003     *
004     * This is free software; you can redistribute it and/or modify it
005     * under the terms of the GNU Lesser General Public License as
006     * published by the Free Software Foundation; either version 2.1 of
007     * the License, or (at your option) any later version.
008     *
009     * This software is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012     * Lesser General Public License for more details.
013     *
014     * You should have received a copy of the GNU Lesser General Public
015     * License along with this software; if not, write to the Free
016     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018     */
019    
020    package org.crsh.shell.ui;
021    
022    import org.crsh.shell.io.ShellWriter;
023    
024    import java.io.IOException;
025    import java.util.ArrayList;
026    import java.util.Collections;
027    import java.util.List;
028    
029    /**
030     * @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a>
031     */
032    public class TableElement extends Element {
033    
034      /** . */
035      public final int MARGIN = 5;
036    
037      /** . */
038      private List<RowElement> rows = new ArrayList<RowElement>();
039    
040      /** . */
041      private List<Integer> colsSize = new ArrayList<Integer>();
042    
043      /** . */
044      protected boolean border;
045    
046      public TableElement addRow(RowElement row) {
047        rows.add(row);
048        return this;
049      }
050      
051      @Override
052      void doPrint(UIWriterContext ctx, ShellWriter writer) throws IOException {
053    
054        //
055        ctx = new UIWriterContext(ctx);
056        colsSize = computeColSize(ctx.getConsoleWidth());
057    
058        // Print top line
059        if (border) {
060          ctx.parentUIContext.pad(writer);
061          ctx.printLine(width() - 2, writer);
062        }
063    
064        //
065        ctx.parentUIContext.pad(writer);
066        for (RowElement e : rows) {
067          e.print(ctx, writer);
068        }
069        ctx.pad(writer);
070    
071        //
072        if (border) {
073          writer.append("|");
074        }
075        writer.append("\n");
076    
077        // Print bottom line
078        if (border) {
079          ctx.parentUIContext.pad(writer);
080          ctx.printLine(width() - 2, writer);
081        }
082    
083      }
084    
085      public List<RowElement> getRows() {
086        return rows;
087      }
088    
089      public List<Integer> getColsSize() {
090        return Collections.unmodifiableList(colsSize);
091      }
092    
093      private List<Integer> computeColSize(int consoleWidth) {
094    
095        List<Integer> colsSize = new ArrayList<Integer>();
096    
097        int colSum = 0;
098        if (border) {
099            colSum += 3;
100          }
101        for (int i = 0; i < columnNumber(); ++i) {
102          int colSize = 0;
103          for (RowElement row : rows) {
104            colSize = Math.max(colSize, row.getValues().get(i).width() + MARGIN);
105            int missingSpace = (colSum + colSize) - consoleWidth;
106            if (missingSpace > 0) {
107              colSize -= missingSpace;
108            }
109          }
110          colsSize.add(colSize);
111          colSum += colSize;
112          if (border) {
113            colSum += 2;
114          }
115        }
116    
117        return colsSize;
118        
119      }
120    
121      public void setBorder(boolean border) {
122        this.border = border;
123      }
124    
125      private int columnNumber() {
126    
127        int n = 0;
128    
129        for (RowElement row : rows) {
130          n = Math.max(n, row.getValues().size());
131        }
132    
133        return n;
134    
135      }
136    
137      @Override
138      int width() {
139    
140        //
141        int sum = 0;
142        for (int colSize : colsSize) sum += colSize;
143        if (border) {
144          sum += (colsSize.size() * 2) + 1;
145        }
146    
147        //
148        return sum;
149    
150      }
151    }