package org.basex.gui.view.text; import static org.basex.core.Text.*; import static org.basex.gui.GUIConstants.*; import static org.basex.util.Token.*; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.Box; import org.basex.core.Command; import org.basex.data.Nodes; import org.basex.gui.GUICommands; import org.basex.gui.GUIConstants.Fill; import org.basex.gui.GUIProp; import org.basex.gui.dialog.Dialog; import org.basex.gui.layout.BaseXBack; import org.basex.gui.layout.BaseXButton; import org.basex.gui.layout.BaseXEditor; import org.basex.gui.layout.BaseXFileChooser; import org.basex.gui.layout.BaseXFileChooser.Mode; import org.basex.gui.layout.BaseXLabel; import org.basex.gui.layout.BaseXLayout; import org.basex.gui.layout.BaseXTextField; import org.basex.gui.layout.TableLayout; import org.basex.gui.layout.XMLSyntax; import org.basex.gui.view.View; import org.basex.gui.view.ViewNotifier; import org.basex.io.IO; import org.basex.io.out.ArrayOutput; import org.basex.io.out.PrintOutput; import org.basex.io.serial.Serializer; import org.basex.util.Util; /** * This class offers a fast text view, using the {@link BaseXEditor} class. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class TextView extends View implements ActionListener { /** Header string. */ private final BaseXLabel header; /** Home button. */ private final BaseXButton home; /** Text Area. */ private final BaseXEditor area; /** Result command. */ private Command cmd; /** Result nodes. */ private Nodes ns; /** Refresh flag. */ private boolean refresh; /** * Default constructor. * @param man view manager */ public TextView(final ViewNotifier man) { super(TEXTVIEW, man); border(6, 6, 6, 6).layout(new BorderLayout(0, 4)).setFocusable(false); final BaseXBack b = new BaseXBack(Fill.NONE).layout(new BorderLayout()); home = BaseXButton.command(GUICommands.C_HOME, gui); home.setEnabled(false); BaseXBack sp = new BaseXBack(Fill.NONE).layout(new TableLayout(1, 2)); sp.add(home); sp.add(Box.createHorizontalStrut(8)); b.add(sp, BorderLayout.WEST); header = new BaseXLabel(TEXT, true, false); b.add(header, BorderLayout.CENTER); final BaseXButton save = new BaseXButton(gui, "save", token(H_SAVE_RESULT)); save.addActionListener(this); /* Find text field. */ final BaseXTextField find = new BaseXTextField(gui); BaseXLayout.setHeight(find, (int) save.getPreferredSize().getHeight()); sp = new BaseXBack(Fill.NONE).layout(new TableLayout(1, 3)); sp.add(find); sp.add(Box.createHorizontalStrut(5)); sp.add(save); b.add(sp, BorderLayout.EAST); add(b, BorderLayout.NORTH); area = new BaseXEditor(false, gui); area.setSyntax(new XMLSyntax()); area.setSearch(find); add(area, BorderLayout.CENTER); refreshLayout(); } @Override public void refreshInit() { refreshContext(true, true); } @Override public void refreshFocus() { } @Override public void refreshMark() { if(refresh) refresh = false; else setText(gui.context.marked); } @Override public void refreshContext(final boolean more, final boolean quick) { setText(gui.context.current()); } @Override public void refreshLayout() { header.setFont(lfont); area.setFont(mfont); } @Override public void refreshUpdate() { refreshContext(true, true); } @Override public boolean visible() { return gui.gprop.is(GUIProp.SHOWTEXT); } @Override public void visible(final boolean v) { gui.gprop.set(GUIProp.SHOWTEXT, v); } @Override protected boolean db() { return false; } /** * Serializes the specified nodes. * @param n nodes to display */ private void setText(final Nodes n) { ns = n; if(!visible()) return; try { final ArrayOutput ao = new ArrayOutput().max(gui.gprop.num(GUIProp.MAXTEXT)); if(n != null) n.serialize(Serializer.get(ao)); setText(ao, null); refresh = false; } catch(final IOException ex) { Util.debug(ex); } } /** * Sets the output text. * @param out cached output * @param c command */ public void setText(final ArrayOutput out, final Command c) { final byte[] buf = out.buffer(); final int size = (int) out.size(); final byte[] chop = token(DOTS); if(out.finished() && size >= chop.length) { System.arraycopy(chop, 0, buf, size - chop.length, chop.length); } area.setText(buf, size); header.setText(TEXT + (out.finished() ? CHOPPED : "")); home.setEnabled(gui.context.data() != null); refresh = true; if(!out.finished()) { cmd = null; ns = null; } else { cmd = c; } } @Override public void actionPerformed(final ActionEvent e) { final BaseXFileChooser fc = new BaseXFileChooser(SAVE_AS, gui.gprop.get(GUIProp.SAVEPATH), gui); final IO file = fc.select(Mode.FSAVE); if(file == null) return; gui.gprop.set(GUIProp.SAVEPATH, file.path()); PrintOutput out = null; try { out = new PrintOutput(file.toString()); if(cmd != null) { cmd.execute(gui.context, out); } else if(ns != null) { ns.serialize(Serializer.get(out)); } else { final byte[] txt = area.getText(); for(final byte t : txt) if(t < 0 || t > ' ' || ws(t)) out.write(t); } } catch(final IOException ex) { Dialog.error(gui, FILE_NOT_SAVED); } finally { if(out != null) try { out.close(); } catch(final IOException ex) { } } } }