diff --git a/build.xml b/build.xml index 6cb105c..278bf9a 100644 --- a/build.xml +++ b/build.xml @@ -36,7 +36,7 @@ This Jakarta Ant buildfile is used to build Jskad, Savant, - QuillDriver, and the Translation Tool. The docs at + QuillDriver, Tibbibl, and the Translation Tool. The docs at http://thdltools.sf.net/api are created using this buildfile, for example. Read the comments of this buildfile to learn more, or see http://thdltools.sourceforge.net/BuildSystems.html. @@ -49,6 +49,7 @@ + @@ -159,6 +160,7 @@ + @@ -219,16 +221,17 @@ + @@ -281,6 +284,25 @@ + + + + + + + + + + + + + + + + + @@ -505,6 +527,7 @@ + @@ -590,6 +613,18 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/org/thdl/tib/bibl/DiacriticPanel.java b/source/org/thdl/tib/bibl/DiacriticPanel.java new file mode 100644 index 0000000..6f79a80 --- /dev/null +++ b/source/org/thdl/tib/bibl/DiacriticPanel.java @@ -0,0 +1,261 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +//import java.awt.event.WindowAdapter; +//import java.awt.event.WindowEvent; +import java.io.File; +import java.io.FileReader; +import java.io.BufferedReader; +import java.io.IOException; +import javax.swing.SwingConstants; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.ScrollPaneConstants; +import javax.swing.BorderFactory; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; +import javax.swing.text.*; + + /** + *

+ * This class creates a panel that displays all the relevant diacritic characters used in Asian Studies. + * In the context of TibEdit, it's constructor takes a TibFrame which is its parent. When the mouse is clicked + * on any diacritic character displayed in DiacriticPanel, it inserts that character at the cursor of the + * TibFrame's {@link TextPane}. All characters are, of course, in Unicode. The file that is the list of diacrtics + * is dia.dat in the /bin/ directory. It is a flat file list of the hexadecimal codes for the Unicode diacritics. + * These are read and converted into characters by DiacriticPanel and they are displayed in the order they are read. + * Thus, to reorder, modify, or add diacritics, one needs only to make the appropriate changes to the dia.dat file. + *

+ */ + +public class DiacriticPanel extends JPanel implements TibConstants +{ + + // Attributes + protected TibFrame frame; + protected JTextComponent jtc; + private TiblEdit controller; + //private StringTokenizer dataSplitter; + private char chosenChar; + private boolean hasPicked; + private boolean isGeneral; + + /** + * Sets the panel's layout, size, and background, and reads in the diacritic data. + */ + private void init() + { + // Creating content panel to use for frame's content & initialize + + //JPanel charPanel = new JPanel(new BorderLayout()); + setLayout(new GridLayout(0,3)); + setSize(new Dimension(100,450)); + setBackground(Color.white); + + // Split the data, create individual line labels + try { + BufferedReader br = new BufferedReader(new FileReader(new File(DEFAULT_DIRECTORY + DIA_DATA))); + String line = br.readLine(); + while(line != null) { + char diaChar = (char)Long.parseLong(line.trim(),16); + String diaStr = Character.toString(diaChar); + JLabel diaLab = getDiaLabel(diaStr); + this.add(diaLab); + line = br.readLine(); + } + br.close(); + } catch (IOException ioe) { + System.out.println("An IOE caught: " + ioe.getMessage()); + ioe.printStackTrace(); + } + } + + // Accessors + /** + * This method takes a character, which is actually a String variable and creates a label + * with a border and a margin with the supplied character string as the + * centered text. Adds a MouseListener that is a {@link #TiblEditMouseAdapter}. It is called by the {@link #init} method. + * + * @param ch - A string variable that is the character associated with this label/button. + * + * @return JLabel - the label created. + */ + public JLabel getDiaLabel(String ch) + { + JLabel lab = new JLabel(ch); + lab.setFont(DEFAULT_FONT); + lab.setHorizontalAlignment(SwingConstants.CENTER); + lab.setBorder(new CompoundBorder(new LineBorder(Color.black),BorderFactory.createEmptyBorder(2,2,2,2))); + if(isGeneral) { + lab.addMouseListener(new GenMouseAdapter()); + } else { + lab.addMouseListener(new TiblEditMouseAdapter()); + } + return lab; + + } + public void setChosenChar(char aChar) + { + chosenChar = aChar; + hasPicked = true; + } + + public char getChosenChar() + { + char rValue = chosenChar; + chosenChar = ' '; + hasPicked = false; + return rValue; + } + + public void setController(TiblEdit te) + { + controller = te; + } + + public TiblEdit getController() + { + return controller; + } + + public void setFrame(TibFrame tf) + { + frame = tf; + } + + public JFrame getFrame() + { + return frame; + } + + public void setJTC(JTextComponent jtextc) + { + jtc = jtextc; + } + + public JTextComponent getJTC() + { + return jtc; + } + + // Constructors + + public DiacriticPanel(boolean isGen, Container cont) + { + super(); + isGeneral = isGen; + if(cont instanceof TibFrame) { + setFrame((TibFrame)cont); + } else if(cont instanceof JTextComponent) { + setJTC((JTextComponent)cont); + } + + init(); + hasPicked = false; + } + + public DiacriticPanel(TibFrame tf) + { + this(false,tf); + setFrame(tf); + setController(tf.getController()); + } + + public DiacriticPanel(JTextComponent jtc) + { + this(true,jtc); + } + + + // Inner Classes + // The Mouse Adapter + /** + *

+ * This inner class is a MouseAdapter that implements "mousePressed". It is added to a label with a diacritic + * so that when that label is clicked, the corresponding Unicode diacritic character is inserted in the + * open document, a {@link TextPane}, at the cursor. + *

+ */ + + private class TiblEditMouseAdapter extends MouseAdapter + { + /** + *

+ * This version of mousePressed. Takes the {@link TibFrame} supplied with the DiacriticPanel's constructor + * and gets its {@link TextPane}. It then inserts the Unicode diacritic character from the source + * label at the cursor of this text pane. + *

+ */ + public void mousePressed(MouseEvent me) + { + TextPane tp = frame.getTextPane(); + if(tp.isEditable()) { + JLabel source = (JLabel)me.getSource(); + String dia = source.getText(); + int pos = tp.getCaret().getDot(); + try { + tp.getDocument().insertString(pos,dia,tp.getCharacterAttributes()); + } catch (BadLocationException ble) + { + System.out.println("Bad location exception while inserting diacritic (" + +pos+")! \n"); + } + } + } + } + + private class GenMouseAdapter extends MouseAdapter + { + /** + *

+ * This version of mousePressed. Takes the {@link TibFrame} supplied with the DiacriticPanel's constructor + * and gets its {@link TextPane}. It then inserts the Unicode diacritic character from the source + * label at the cursor of this text pane. + *

+ */ + public void mousePressed(MouseEvent me) + { + JLabel source = (JLabel)me.getSource(); + String dia = source.getText(); + jtc.replaceSelection(dia); + } + } + // Main Method for testing + public static void main(String[] args) + {/* + TibFrame tf = new TibFrame("Diacritic Test"); + DiacriticPanel dp = new DiacriticPanel(); + JScrollPane jsp = new JScrollPane(dp, + ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); + tf.setContentPane(jsp); + tf.pack(); + tf.show();*/ + } +} diff --git a/source/org/thdl/tib/bibl/DiscDialog.java b/source/org/thdl/tib/bibl/DiscDialog.java new file mode 100644 index 0000000..1e2b0d5 --- /dev/null +++ b/source/org/thdl/tib/bibl/DiscDialog.java @@ -0,0 +1,1091 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.border.*; +import javax.swing.text.*; +import javax.swing.text.StyleContext.*; +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import org.jdom.*; + +/** +* This extension of JDialog is used for entering in discussion concerning a specific title in a Tibbibl document. +* There are two types of discussion: brief (no paragraphs) and long (with paragraphs). It provides the user +* with a {@link DiacriticPanel} so that diacritics can be easily entered into the discussion. It also provides +* means to format the text as either bold and/or italic. +*/ +public class DiscDialog extends JDialog implements TibConstants, ActionListener +{ + + // Attributes + TibFrame parent; + TibDoc doc; + org.jdom.Element textDisc; + + JComboBox styleBox, typeBox, discBox; + JPanel content, tempPanel, filler; + DiscTextPane jta; + JLabel headLabel, header; + Action boldAction,italicAction; + + Color bgColor = Color.gray; + Dimension fillerSize = new Dimension(50,20); + Dimension dialogSize = new Dimension(700,550); + Dimension contentSize = new Dimension(300,400); + Dimension maxLine = new Dimension(600,50); + int marg = 8; + int sectionSelection; + int returnType; + + Hashtable actions; + + public static final int CANCEL = -1; + public static final int ENTER = 1; + public static String NORMSTY = "Normal"; + public static String STRONG = "Strong"; + public static String WEAK = "Weak"; + public static String TITLE = "Title"; + public static String TIBSTY = "Tibetan"; + public static String LIST = "List"; + public static String CITATION = "Citation"; + public static String LIST_MARK = "- "; + + String[] titleTypes = {BRIEF,FULL}; + + // Methods + public void init() + { + // Setting general parameters + setSize(dialogSize); + parent = (TibFrame)getOwner(); + returnType = CANCEL; + + // Content panel & header + content = new JPanel(); + content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS)); + content.setBorder(new EmptyBorder(marg,marg,marg,marg)); + tempPanel = new JPanel(); + tempPanel.setBorder(new EmptyBorder(0,0,marg,0)); + headLabel = new JLabel(); + headLabel.setFont(BOLD_FONT); + headLabel.setHorizontalAlignment(SwingConstants.RIGHT); + tempPanel.add(headLabel); + header = new JLabel(); + header.setFont(DEFAULT_FONT); + header.setHorizontalAlignment(SwingConstants.LEFT); + header.setMaximumSize(maxLine); + tempPanel.add(header); + //tempPanel.setMaximumSize(maxLine); + content.add(tempPanel); + + // menu & tool bars + tempPanel = getTempPanel(); + JMenuBar jmbar = new JMenuBar(); + JToolBar tools = new JToolBar(); + tools.setFloatable(false); + jmbar.add(tools); + tempPanel.add(jmbar); + tempPanel.setMaximumSize(maxLine); + content.add(tempPanel); + + tempPanel = getTempPanel(); + tempPanel.setBorder(new CompoundBorder(new EmptyBorder(marg,0,0,0), LineBorder.createBlackLineBorder())); + + // The Text pane + jta = new DiscTextPane(); //setTextPane(); + tempPanel.add(getScrollPane(jta)); + jta.addKeyListener(new DiscKeyAdapter()); + tempPanel.setPreferredSize(contentSize); + content.add(tempPanel); + setKeys(jta); + + // The tool bar + // Style/Mark up combobox + JLabel lab = new JLabel("Mark-up: "); + lab.setFont(BOLD_FONT); + tools.add(lab); + styleBox = new JComboBox(jta.getStyleTypes(titleTypes[0])); + styleBox.setMaximumSize(new Dimension(60,30)); + styleBox.setRenderer(new StyleBoxRenderer()); + tools.add(styleBox); + styleBox.addActionListener(new ActionListener() { + public void actionPerformed (ActionEvent ae) { + String sname = (String)styleBox.getSelectedItem(); + if(sname != null) {jta.setStyle(sname);} + jta.grabFocus(); + }}); + + tools.add(new JLabel(" ")); + + // The Discussion type comboBox + lab = new JLabel(" Type: "); + lab.setFont(BOLD_FONT); + tools.add(lab); + + typeBox = new JComboBox(titleTypes); + typeBox.setBorder(BorderFactory.createLoweredBevelBorder()); + typeBox.setBackground(Color.white); + typeBox.setMaximumSize(new Dimension(60,30)); + tools.add(typeBox); + typeBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + styleBox.setModel(new DefaultComboBoxModel(jta.getStyleTypes(titleTypes[typeBox.getSelectedIndex()]))); + jta.grabFocus(); + } + }); + tools.add(new JLabel(" ")); + + // The Section Combo Box + lab = new JLabel(" Section: "); + lab.setFont(BOLD_FONT); + tools.add(lab); + discBox.setMaximumSize(new Dimension(150,30)); + tools.add(discBox); + tools.setMaximumSize(maxLine); + + // The Button Panel + tempPanel = getTempPanel(); + tempPanel.setBorder(new EmptyBorder(10,0,0,0)); + tempPanel.add(getFiller()); + + JButton enter = new JButton("Enter"); + enter.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + returnType = ENTER; + java.util.List results = jta.makeXML(); + ComboBoxElement cbe = (ComboBoxElement)discBox.getSelectedItem(); + org.jdom.Element tibl = cbe.getElement(); + cbe.setElement(writeDiscussion(tibl,results)); + setVisible(false); + } + }); + enter.setBorder(new CompoundBorder(BorderFactory.createRaisedBevelBorder(), new EmptyBorder(3,8,3,8))); + tempPanel.add(enter); + tempPanel.add(getFiller()); + JButton cancel = new JButton("Cancel"); + cancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) { + returnType = CANCEL; + setVisible(false); + } + }); + cancel.setBorder(new CompoundBorder(BorderFactory.createRaisedBevelBorder(), new EmptyBorder(3,8,3,8))); + tempPanel.add(cancel); + tempPanel.add(getFiller()); + tempPanel.setMaximumSize(maxLine); + content.add(tempPanel); + + + DiacriticPanel diaPanel = new DiacriticPanel(jta); + JScrollPane contentSP = getScrollPane(content); + JSplitPane jsplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,getScrollPane(diaPanel),contentSP); + jsplit.setContinuousLayout(true); + setContentPane(jsplit); + setLocation(10,10); + jta.setContent(((ComboBoxElement)discBox.getSelectedItem()).getElement()); + jta.addMouseListener(new MouseStyleListener()); + pack(); + setSize(dialogSize); + jsplit.setDividerLocation(0.25D); + addWindowListener(new WindowAdapter() { + public void windowActivated(WindowEvent e) { + jta.requestFocus(); + } + }); + sectionSelection = discBox.getSelectedIndex(); + } + + public void setTibDoc(TibDoc td) + { + org.jdom.Element sections, temp; + sections = null; + Vector discTibls = new Vector(); + doc = td; + discTibls.add(new ComboBoxElement(doc.getRoot())); + sections = td.findElement(SECTIONS); + if(sections != null) { + java.util.List tibAnals = sections.getChildren(TIBANAL); + discTibls.addAll(processSections(tibAnals)); + } + discBox = new JComboBox(discTibls); + discBox.addActionListener(this); + + } + + public Vector processSections(java.util.List tibAnals) + { + Vector totalSections = new Vector(); + for(Iterator it = tibAnals.iterator(); it.hasNext();) { + org.jdom.Element tibAn = (org.jdom.Element)it.next(); + java.util.List children = tibAn.getChildren(TIBL); + if(children != null) { + for(Iterator childIt = children.iterator(); childIt.hasNext();) { + org.jdom.Element child = (org.jdom.Element)childIt.next(); + totalSections.add(new ComboBoxElement(child)); + if(child.getChildren(TIBANAL) != null) { + totalSections.addAll(processSections(child.getChildren(TIBANAL))); + } + } + } + } + + return totalSections; + } + + public TibDoc getTibDoc() + { + return doc; + } + + private JPanel getTempPanel() + { + JPanel jp = new JPanel(); + jp.setLayout(new BoxLayout(jp, BoxLayout.X_AXIS)); + //jp.setBackground(bgColor); + return jp; + } + + private JPanel getFiller() + { + JPanel filler = new JPanel(); + filler.setPreferredSize(fillerSize); + return filler; + } + + private JScrollPane getScrollPane(Component comp) + { + JScrollPane jsp = new JScrollPane(comp, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + return jsp; + } + + public void setHeader(String txt) + { + if(txt.length()>50) { + int ind = txt.indexOf(" ",50); + if(ind == -1) {ind=txt.length();} + txt = txt.substring(0,ind) + " ..."; + } + header.setText(txt); + repaint(); + } + + public void setTitleText(String title) + { + headLabel.setText("Discussion on Title: "); + setHeader(title); + } + + public JTextPane setTextPane() + { + JTextPane workTP = new JTextPane(); + workTP.setFont(DEFAULT_FONT); + return workTP; + } + + public void setKeys(JTextPane workTP) + { + + Keymap kmap = workTP.addKeymap("dialogKeyMap",workTP.getKeymap()); + boldAction = new StyledEditorKit.BoldAction(); + KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_B, + Event.CTRL_MASK); + kmap.addActionForKeyStroke(key,boldAction); + boldAction.putValue(Action.NAME," Bold (Ctrl+B) "); + + italicAction = new StyledEditorKit.ItalicAction(); + key = KeyStroke.getKeyStroke(KeyEvent.VK_I, + Event.CTRL_MASK); + kmap.addActionForKeyStroke(key, italicAction); + italicAction.putValue(Action.NAME," Italic (Ctrl+I) "); + workTP.setKeymap(kmap); + } + + private void createActionTable(JTextComponent textComponent) { + actions = new Hashtable(); + Action[] actionsArray = textComponent.getActions(); + for (int i = 0; i < actionsArray.length; i++) { + Action a = actionsArray[i]; + actions.put(a.getValue(Action.NAME), a); + //System.out.println(a.getValue(Action.NAME)); + } + } + + private Action getActionByName(String name) { + return (Action)(actions.get(name)); + } + + public void setDiscussionText(org.jdom.Element tdecl) + { + StyledDocument doc = jta.getStyledDocument(); + Style norm = doc.getLogicalStyle(0); + Style boldSt = doc.addStyle(BOLD,norm); + boldSt.addAttribute(StyleConstants.FontConstants.Bold,new Boolean(true)); + Style italSt = doc.addStyle(ITALIC,norm); + italSt.addAttribute(StyleConstants.FontConstants.Italic,new Boolean(true)); + org.jdom.Element disc = TiblEdit.locateDisc(tdecl); + if(disc.getAttributeValue(TYPE) == null) { disc.setAttribute(TYPE,BRIEF); } + String discType = disc.getAttributeValue(TYPE); + try { + if(discType.equalsIgnoreCase(BRIEF)) { + typeBox.setSelectedIndex(0); + for(Iterator it = disc.getContent().iterator();it.hasNext();) { + Object child = it.next(); + //System.out.println("Item in Discussion: " + child.toString()); + if(child instanceof org.jdom.Text) { + String txt = ((org.jdom.Text)child).getText(); + doc.insertString(doc.getLength(),txt,norm); + } else if (child instanceof String) { + String txt = (String)child; + doc.insertString(doc.getLength(),txt,norm); + } else if (child instanceof org.jdom.Element) { + org.jdom.Element hiEl = (org.jdom.Element)child; + String txt = hiEl.getText(); + String rend = hiEl.getAttributeValue(REND); + if(rend == null) { + doc.insertString(doc.getLength(),txt,norm); + } else if(rend.equalsIgnoreCase(BOLD)) { + doc.insertString(doc.getLength(),txt,boldSt); + } else if(rend.equalsIgnoreCase(ITALIC)) { + doc.insertString(doc.getLength(),txt,italSt); + } else { + System.out.println("Unknown rend type in setting discussion text (DiscDialog: 250)!"); + } + } + } + } else { + typeBox.setSelectedIndex(1); + org.jdom.Element[] paras = TibDoc.toElementArray(disc.getChildren(P)); + for(int n=0; n-1) {results.remove(null);} + org.jdom.Element intelDecl, discElem, physDecl; + intelDecl = tibl.getChild(INTDECL); + Object item = null; + if(intelDecl == null) { + intelDecl = new org.jdom.Element(INTDECL); + java.util.List tiblContent = tibl.getContent(); + for(Iterator it=tiblContent.iterator(); it.hasNext();) { + item = it.next(); + if(item instanceof org.jdom.Element) { + org.jdom.Element elem = (org.jdom.Element)item; + if(elem.getName().equals(PHYSDEC)) { break; } + } + } + int index = tiblContent.indexOf(item) + 1; + if(index >= tiblContent.size()) { + tiblContent.add(intelDecl); + } else { + tiblContent.add(index, intelDecl); + } + } + discElem = null; + item = null; + for(Iterator it = intelDecl.getChildren(DISC).iterator(); it.hasNext();) { + item = it.next(); + if(item instanceof org.jdom.Element) { + org.jdom.Element child = (org.jdom.Element)item; + if(child.getAttributeValue(TYPE).equals(SUMMARY)) { + discElem = child; + discElem.setContent(results); + discElem.setAttribute(RESP,parent.getController().getEditorsInitials()); + discElem.setAttribute(REND,((String)typeBox.getSelectedItem()).toLowerCase()); + return tibl; + } + } + } + discElem = getDiscussion(parent.getController().getEditorsInitials()); + discElem.setContent(results); + if(intelDecl.getChildren().size()<1) { + org.jdom.Element dox = new org.jdom.Element(DOX); + dox.setAttribute(TYPE,RELAT); + org.jdom.Element tibLevel = TibDoc.getAncestor(TIBL,intelDecl); + String level = (tibLevel == null?"section":tibLevel.getAttributeValue(LVL)); + dox.setText("NGB " + level + " proper."); + intelDecl.addContent(dox); + } + intelDecl.addContent(discElem); + return tibl; + } + + public org.jdom.Element getDiscussion(String editor) + { + System.out.println("Getting discussion for " + editor); + org.jdom.Element discElement; + discElement = new org.jdom.Element(DISC); + discElement.setAttribute(RESP,editor); + discElement.setAttribute(TYPE,SUMMARY); + StyledDocument doc = jta.getStyledDocument(); + String discType = getDiscussionType(); + if (discType.equalsIgnoreCase(BRIEF)) + { + discElement.setAttribute(REND,BRIEF); + } else { + discElement.setAttribute(REND,FULL); + } + //System.out.println("The returned text is: \n" + TiblEdit.outputString(discElement)); + return discElement; + } + + public String getDiscussionType() + { + return (String)typeBox.getSelectedItem(); + } + + public void setDiscussionType(String type) { + if(type.equalsIgnoreCase(FULL)) { + typeBox.setSelectedIndex(1); + } else { + typeBox.setSelectedIndex(0); + } + } + + public String getTextString() + { + String retText = new String(); + StyledDocument sd = jta.getStyledDocument(); + try { + retText = sd.getText(0,sd.getLength()); + } catch (BadLocationException ble) { + } + return retText; + } + + public int getReturnValue() + { + return returnType; + } + + // Implementations + public void actionPerformed(ActionEvent ae) + { + + if(ae.getSource().equals(discBox)) { + JComboBox source = (JComboBox)ae.getSource(); + ComboBoxElement cbe = (ComboBoxElement)source.getItemAt(sectionSelection); + org.jdom.Element tibl = cbe.getElement(); + cbe.setElement(writeDiscussion(tibl,jta.makeXML())); + cbe = (ComboBoxElement)source.getSelectedItem(); + sectionSelection = source.getSelectedIndex(); + jta.setContent(cbe.getElement()); + jta.grabFocus(); + } + } + + + // Constructors + + public DiscDialog(TibFrame owner, TibDoc doc) + { + super(owner,DISC_DIA_TITLE,true); + setTibDoc(doc); + init(); + this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void closingWindow(WindowEvent we) { + returnType = 0; + } + }); + //setDiscussionText(); + //setVisible(true); + } + + public class DiscKeyAdapter extends KeyAdapter + { + public void keyPressed(KeyEvent ke) { + String sname = (String)styleBox.getSelectedItem(); + if(sname != null) {jta.setCharacterAttributes(jta.getStyle(sname),true);} + } + + public void keyReleased(KeyEvent ke) { + if(ke.getKeyCode() == KeyEvent.VK_ENTER) { + StyledDocument sd = jta.getStyledDocument(); + int len = jta.getCaretPosition(); + + try { + if(typeBox.getSelectedIndex() == 0) { + sd.remove(len-1,1); + } else { + sd.insertString(len,"\n",null); + } + } catch (BadLocationException ble) { + System.out.println("Bad location in trying to add extra newline in DiscDialog!"); + } + jta.doDiscEnter(styleBox); + + } else if(ke.getModifiers() == KeyEvent.ALT_MASK) { + //System.out.println("In switch keycode is: " + ke.getKeyCode() + " ["+ke.getKeyChar() + "]"); + switch(ke.getKeyCode()) { + case KeyEvent.VK_C: styleBox.setSelectedIndex(5); break; // if 'Alt-c' is pressed, choose citation + case KeyEvent.VK_I: styleBox.setSelectedIndex(4); break; // if 'Alt-i' is pressed, choose title + case KeyEvent.VK_L: styleBox.setSelectedIndex(6); break; // if 'Alt-l' is pressed, choose list + case KeyEvent.VK_S: styleBox.setSelectedIndex(1); break; // if 'Alt-s' is pressed, choose strong + case KeyEvent.VK_T: styleBox.setSelectedIndex(3); break; // if 'Alt-t' is pressed, choose title + case KeyEvent.VK_W: styleBox.setSelectedIndex(2); break; // if 'Alt-w' is pressed, choose weak + case KeyEvent.VK_N: styleBox.setSelectedIndex(0); break; // 'Alt-n' means normal + case KeyEvent.VK_B: typeBox.setSelectedIndex(0); break; // 'Alt-b' means a brief discussion. + case KeyEvent.VK_F: typeBox.setSelectedIndex(1); break; + } + } + } + } + + public class MouseStyleListener extends MouseAdapter + { + public void mouseReleased(MouseEvent me) { + int dot = jta.getCaretPosition(); + AttributeSet as = jta.getStyledDocument().getCharacterElement(dot).getAttributes(); + String caretStyle = as.getAttribute(AttributeSet.NameAttribute).toString(); + if(caretStyle != null) { + styleBox.getModel().setSelectedItem(caretStyle); + } else { + System.out.println("Caret style is null! at " + dot); + } + } + } + + public class ComboBoxElement + { + org.jdom.Element theElement, intelDecl, disc; + + public void setElement(org.jdom.Element el) + { + theElement = el; + } + + public org.jdom.Element getElement() + { + return theElement; + } + + public void setDiscussion(java.util.List content) + { + if(content != null) {disc.setContent(content);} + } + + public org.jdom.Element getDiscussion() + { + return disc; + } + + public String toString() + { + String level = theElement.getAttributeValue(LVL); + if(level != null && level.equalsIgnoreCase(TXT)) { + return "Whole Text"; + } + org.jdom.Element head = theElement.getChild(HEAD); + if(head == null) {return "Unnamed Section!";} + return TibDoc.cleanString(head.getText()); + } + + public ComboBoxElement(org.jdom.Element el) + { + setElement(el); + } + } + + public class DiscTextPane extends JTextPane + { + Object[][] styleTable = { + {NORMSTY,StyleConstants.FontConstants.FontFamily,BASE_FONT_NAME, + StyleConstants.FontConstants.Bold,new Boolean(false), + StyleConstants.FontConstants.Italic,new Boolean(false), + StyleConstants.CharacterConstants.Underline,new Boolean(false)}, + + {STRONG, StyleConstants.FontConstants.Bold,new Boolean(true), + StyleConstants.FontConstants.Italic,new Boolean(false), + StyleConstants.CharacterConstants.Underline,new Boolean(false)}, + + {WEAK, StyleConstants.FontConstants.Italic,new Boolean(true), + StyleConstants.FontConstants.Bold,new Boolean(false), + StyleConstants.CharacterConstants.Underline,new Boolean(false)}, + + {TIBSTY, StyleConstants.FontConstants.Italic,new Boolean(true), + StyleConstants.FontConstants.Bold,new Boolean(false), + StyleConstants.CharacterConstants.Underline,new Boolean(false), + StyleConstants.ColorConstants.Foreground,Color.blue}, + + {TITLE, StyleConstants.CharacterConstants.Underline,new Boolean(true), + StyleConstants.FontConstants.Bold,new Boolean(false), + StyleConstants.FontConstants.Italic,new Boolean(false)}, + + {CITATION, StyleConstants.FontConstants.Italic,new Boolean(false), + StyleConstants.FontConstants.Bold,new Boolean(false), + StyleConstants.CharacterConstants.Underline,new Boolean(false), + StyleConstants.ColorConstants.Foreground,Color.red}, + + {LIST, StyleConstants.ParagraphConstants.LeftIndent,new Float(12.0F), + StyleConstants.FontConstants.Italic, new Boolean(false), + StyleConstants.FontConstants.Bold,new Boolean(false), + StyleConstants.CharacterConstants.Underline,new Boolean(false)}}; + + NamedStyle normal = null; + + //Vector styleChoices = new Vector(); + + String NEW_PARA = "NewPara"; + + public void init() + { + for(int r = 0; r sd.getLength()) { paraStart = sd.getLength(); } + String paraBeg = (paraStart==sd.getLength()?new String():sd.getText(paraStart,LIST_MARK.length())); + if(!paraBeg.equals(LIST_MARK)) { + sd.insertString(paraStart,LIST_MARK,newStyle); + } + } catch (BadLocationException ble) { + System.out.println("Bad location in inserting list mark at DiscDialog 692"); + } + } + setParagraphAttributes(newStyle,true); + setCharacterAttributes(newStyle,true); + + } else if(styleName.equals(NORMSTY)) { + int offset = sd.getParagraphElement(getCaretPosition()).getStartOffset(); + try { + String prefix = sd.getText(offset,LIST_MARK.length()); + if(prefix.equals(LIST_MARK)) { sd.remove(offset,LIST_MARK.length()); } + } catch (BadLocationException ble) { + // It checks for a prefix of dash space in case it's a list + // if not it throw this exception which just needs to be caught. + // probably a bad way of doing it... should be reworked. + } + setParagraphAttributes(newStyle,true); + setCharacterAttributes(newStyle,true); + } else { + setCharacterAttributes(newStyle,true); + } + // Stylechoices holds arrays which tell offset and style name for all style changes. + //styleChoices.add(new String[] {Integer.toString(sd.getLength()),styleName}); + //System.out.println("added line for " + styleName + " to stylechoices!"); + } + + public String[] getStyleTypes(String type) + { + String[] outTable; + if(type.equals(titleTypes[0])) { + outTable = new String[styleTable.length-1]; + } else { + outTable = new String[styleTable.length]; + } + for(int r=0;r1 || !p.getText().equals("")) ) { + returnList.add(p); } + if(list != null) { returnList.add(list); list = null;} + p = new org.jdom.Element(P); + } + } + + if(ch.charAt(0) == (char)Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR) { + newPara = true; + if(list != null) {c++;} + continue; + } else { + newPara = false; + } + + if(currSty != null && !currSty.equals(oldSty)) { + if(list == null) { + if(openElem == null) { + p.addContent(textRun.toString()); + } else { + openElem.addContent(textRun.toString()); + } + openElem = getDiscElement(currSty); + if(openElem != null) { p.addContent(openElem); } + } else { + openElem.addContent(textRun.toString()); + if(!currSty.equals(LIST)) { + org.jdom.Element tempItem = openElem; + openElem = getDiscElement(currSty); + if(openElem != null) { + tempItem.addContent(openElem); + } else if(tempItem != null) { + openElem = tempItem; + } + } else if(!openElem.getName().equals(ITEM)) { + openElem = openElem.getParent(); + } + } + textRun = new StringBuffer(); + } + + + + // for all + textRun.append(ch); + if(textRun.indexOf(LIST_MARK) == 0) { + textRun = textRun.delete(0,LIST_MARK.length()); + } + oldStyle = nameVal; + + } // End of for character loop + if(textRun != null) { + if(openElem != null) { + openElem.addContent(textRun.toString()); + } else if(p!= null) { + p.addContent(textRun.toString()); + } + } + if(list != null) {returnList.add(list); } else {returnList.add(p);} + return returnList; + + } + + + + private org.jdom.Element getDiscElement(String styleType) + { + org.jdom.Element retElem = null; + if(styleType.equals(STRONG)) { + retElem = new org.jdom.Element(HI); + retElem.setAttribute(REND,STRONG.toLowerCase()); + } else if(styleType.equals(WEAK)) { + retElem = new org.jdom.Element(HI); + retElem.setAttribute(REND,WEAK.toLowerCase()); + } else if(styleType.equals(TIBSTY)) { + retElem = new org.jdom.Element(HI); + retElem.setAttribute(LANG,TIB); + } else if(styleType.equals(TITLE)) { + retElem = new org.jdom.Element(TibConstants.TITLE); + } else if(styleType.equals(CITATION)) { + retElem = new org.jdom.Element(QUOTE); + } else if(styleType.equals(LIST)) { + retElem = new org.jdom.Element(ITEM); + } + return retElem; + } + + private java.util.List processParagraph(StyledDocument sd, int start, int endPos) + { + org.jdom.Element currentEl = null; + org.jdom.Text textRun = new org.jdom.Text(null); + Vector returnList = new Vector(); + NamedStyle lastAs = null; + for(int c=start;c<= endPos;c++) { + NamedStyle as = (NamedStyle)sd.getCharacterElement(c).getAttributes(); + if(as == null) {continue;} + String styName = as.getName(); + returnList.add(styName); + lastAs = as; + } + return returnList; + } + + public DiscTextPane() + { + super(); + init(); + } + + } + + +public class StyleBoxRenderer extends JLabel + implements ListCellRenderer { + public StyleBoxRenderer() { + setOpaque(true); + } + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) + { + String item = value.toString(); + setText(item); + this.setFont(this.getFont().deriveFont(Font.PLAIN)); + this.setForeground(Color.black); + this.setHorizontalAlignment(SwingConstants.LEFT); + + if(item.equals("Tibetan")) { + this.setForeground(Color.blue); + + } else if(item.equals("Citation")) { + this.setForeground(Color.red); + + } else if(item.equals("Strong")) { + this.setFont(this.getFont().deriveFont(Font.BOLD)); + + } else if(item.equals("Weak")) { + this.setFont(this.getFont().deriveFont(Font.ITALIC)); + + } else if(item.equals("Title")) { + this.setText("Title"); // The only way to get a label underlined!! + + } else if(item.equals("List")) { + this.setHorizontalAlignment(SwingConstants.CENTER); + this.setText("- List"); + + } + + return this; + } +} + +} diff --git a/source/org/thdl/tib/bibl/DoxWindow.java b/source/org/thdl/tib/bibl/DoxWindow.java new file mode 100644 index 0000000..fc1e86b --- /dev/null +++ b/source/org/thdl/tib/bibl/DoxWindow.java @@ -0,0 +1,714 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import javax.swing.*; +import javax.swing.border.*; +import java.awt.*; +import java.awt.event.*; +import java.util.StringTokenizer; +import java.util.NoSuchElementException; + +/** +* This class displays a separate window with information concerning a texts doxographical category and it +* allows the user to set the doxographical categorization for a text. It changes options as the category is +* specificed and allows the user to view the categories in either English or Tibetan. +*/ + +public class DoxWindow extends JFrame +{ + private TiblEdit controller; + + // Static Type Definitions + + static int MAIN = 0; + static int SUB = 1; + static int SUBSUB = 2; + static String DOXDELIM = ":"; + static String IDDELIM = "."; + + + // The Data on the DoxCats. + String[] mainDox = {"a ti yo ga","a nu yo ga","ma h\u0101 yo ga","sna tshogs"}; + String[] mainEng = {"Atiyoga","Anuyoga","Mah\u0101yoga","Miscellaneous"}; + + String[][] subDox = new String[4][6]; + + // ati subs + String[] ati = {"sems sde","klong sde","man ngag sde","spyi ti","yang ti","sna tshogs"}; + // anu subs = + String[] anu = {"rtsa ba'i rgyud bzhi","mtha' drug gsal bar byed pa'i rgyud drug","dkon rgyud","sna tshogs"}; + // Maha subs + String[] maha = {"rgyud sde","sgrub sde bka' brgyad","sna tshogs"}; + + + String[][][] subSubDox = new String[4][6][]; + + // Atiyoga sub subs + String[] semsSde = {"sems sde bco brgyad","kun byed skor","sna tshogs"}; + String[] manNgagSde = {"phyi nang skor","gsang skor","snying thig","sna tshogs"}; + String[] yangTi = {"bram ze'i skor","pad ma'i skor","sna tshogs"}; + + // Mahayoga sub subs + String[] rgyudSde = { "rtsa bar gyur sgyu 'phrul sde brgyad", + "bshad pa dang cha mthun gyi rgyud tantra sde bco brgyad", + "sna tshogs"}; + + String[] sgrubSde = { "sgrub sde", + "bka' brgyad", + "sna tshogs"}; + + String[][][][] subSubSubDox = new String[4][6][3][]; + // Mahayoga sub sub subs + String[] rgyud18 = { "sku", + "gsung", + "thugs", + "yon tan", + "phrin las", + "spyi" }; + + String[] sgrubSdeSub = { "bla ma dgongs pa 'dus pa", + "bde gshegs 'dus pa", + "sna tshogs" }; + + String[] bkaBrgyad = { "'jam dpal sku'i skor", + "pad ma gsung gi rgyud", + "yang dag thugs kyi rgyud", + "bdud rtsi yon tan gyi rgyud", + "phrin las phur pa'i skor", + "ma mo rbod gtong skor", + "bstan srung mchod bstod", + "drag sngags skor", + "sna tshogs" }; + // English of categories + // Sub categories + String[][] subEng = new String[4][6]; + + String[] atiEng = {"Mind Series", + "Space Series", + "Experiential Precept Series", + "Crown Pith", + "Ultra Pith", + "Miscellaneous"}; + + String[] anuEng = { "The Four Root S\u016Btras", + "The Six Tantras Clarifying the Limits", + "The Twelve Rare Tantras", + "Miscellaneous"}; + + String[] mahaEng = { "Tantra Series", + "Practice Series of the Eight Proclamation Deities", + "Micellanesou"}; + + // SubSub Categories + String[][][] subSubEng = new String[4][6][]; + // Atiyoga + String[] semsSdeEng = {"The Eighteen Mind Series Texts", + "The All Creating Cycle", + "Miscellaneous"}; + + String[] manNgagSdeEng = {"External and internal cycles", + "Esoteric Cycles", + "Seminal Heart", + "Miscellaneous"}; + + String[] yangTiEng = {"Brahmin cycles", + "Padma-related", + "Miscellaneous"}; + + // None for Anuyoga + + // Mahayoga + String[] rgyudSdeEng = {"The Eightfold Set of Root Magical Emanation Tantras", + "The Eighteenfold Set of Explanatory Tantras", + "Miscellaneous"}; + + String[] sgrubSdeEng = {"The Practice Series", + "The Eight Proclamation Deities", + "Miscellaneous"}; + + // Sub sub sub categories + String[][][][] subSubSubEng = new String [4][6][3][]; + + String[] rgyud18Eng = {"Enlightened Body", + "Enlightened Speech", + "Enlightened Mind", + "Enlightened Qualities", + "Enlightened Activities", + "General"}; + + String[] sgrubSdeSubEng = {"Summary of the Highest Intention", + "Consortium of Sugatas", + "Miscellaneous"}; + + String[] bkaBrgyadEng = {"The Ma\u00F1jushr\u012B Cycle on Enlightened Form", + "The Lotus Tantras on Enlightened Communication", + "The Real Tantras on Enlightened Mind", + "The Nectar Tantras on Enlightened Qualities", + "The Sacred Dagger Cycle on Enlightened Activities", + "The Cycle on Invoking the Fierce Ma-mo Deities", + "Offerings and Praises to Protect the Teachings", + "The Cycle on Fierce Mantras", + "Miscellaneous"}; + + + // The Components of the Dox screen + JFrame frame; + JPanel contentPanel; + + static String DOX_INSTRUCTIONS = "Use this window to choose the doxographical category for this text. " + + "The categories can be viewed in either Tibetan or English, but both " + + "forms will be entered into the text's markup. The categories available " + + "will change as choices are made higher in the hierarchy. The numbers " + + "assigned to each category will be used to create the text's ID number. " + + "(The last section of the ID or the unique ID number will temporarily be " + + "assigned by the program until that category is filled out and ordered)"; + + TCombo mainDoxBox; + TCombo subDoxBox; + TCombo subSubDoxBox; + TCombo subSubSubDoxBox; + JTextField numberInCategory; + + JRadioButton tib, eng; + + JButton submit,cancel; + + JLabel fileName; + +// The init method + public void init() + { + // Initializing the data ... + // The 3 main divisions, plus misc, are defined above as mainDox + + // 3 main categories' subdivisiongs + subDox[0] = ati; + subDox[1] = anu; + subDox[2] = maha; + subDox[3] = null; + + // Ati sub subs + subSubDox[0][0] = semsSde; + subSubDox[0][2] = manNgagSde; + subSubDox[0][4] = yangTi; + + //no Anu sub subs + + // Maha sub subs + subSubDox[2][0] = rgyudSde; + subSubDox[2][1] = sgrubSde; + + // Maha sub sub subs + // rgyud sde - 18 tantras + subSubSubDox[2][0][1] = rgyud18; + + //sgrub sde - practice series + subSubSubDox[2][1][0] = sgrubSdeSub; + + // sgrub sde - 8 proclamation deities + subSubSubDox[2][1][1] = bkaBrgyad; + + // English + subEng[0] = atiEng; + subEng[1] = anuEng; + subEng[2] = mahaEng; + subEng[3] = null; + + subSubEng[0][0] = semsSdeEng; + subSubEng[0][2] = manNgagSdeEng; + subSubEng[0][4] = yangTiEng; + + subSubEng[2][0] = rgyudSdeEng; + subSubEng[2][1] = sgrubSdeEng; + + subSubSubEng[2][0][1] = rgyud18Eng; + subSubSubEng[2][1][0] = sgrubSdeSubEng; + subSubSubEng[2][1][1] = bkaBrgyadEng; + + // Setting up the Swing components + mainDoxBox = new TCombo(mainDox); + + subDoxBox = new TCombo(subDox[0],mainDoxBox); + + subSubDoxBox = new TCombo(subSubDox[0][0],subDoxBox); + + subSubSubDoxBox = new TCombo(subSubDoxBox); + + mainDoxBox.addActionListener(new DoxEar(MAIN,subDoxBox)); + subDoxBox.addActionListener(new DoxEar(SUB,subSubDoxBox)); + subSubDoxBox.addActionListener(new DoxEar(SUBSUB,subSubSubDoxBox)); + + // The Frame and panels + getContentPane().setLayout(new BorderLayout()); + + contentPanel = new JPanel(); + contentPanel.setBorder(new EmptyBorder(10,10,10,10)); + + JTextArea instructions = new JTextArea(DOX_INSTRUCTIONS); + instructions.setEditable(false); + instructions.setFont(new Font("Arial",Font.PLAIN,12)); + instructions.setBorder(new EmptyBorder(5,10,5,5)); + instructions.setBackground(contentPanel.getBackground()); + instructions.setLineWrap(true); + instructions.setWrapStyleWord(true); + contentPanel.add(instructions); + + fileName = new JLabel(" "); + + contentPanel.add(fileName); + + JPanel doxList = new JPanel(); + doxList.setLayout(new GridLayout(4,1)); + //doxList.setBorder(new EmptyBorder(25,25,25,25)); + + + JPanel doxPanel = new JPanel(new BorderLayout()); + doxPanel.setBorder(new EmptyBorder(10,10,10,10)); + doxPanel.add(mainDoxBox,BorderLayout.CENTER); + doxList.add(doxPanel); + + doxPanel = new JPanel(new BorderLayout()); + doxPanel.setBorder(new EmptyBorder(10,10,10,10)); + doxPanel.add(subDoxBox,BorderLayout.CENTER); + doxList.add(doxPanel); + + doxPanel = new JPanel(new BorderLayout()); + doxPanel.setBorder(new EmptyBorder(10,10,10,10)); + doxPanel.add(subSubDoxBox,BorderLayout.CENTER); + doxList.add(doxPanel); + + doxPanel = new JPanel(new BorderLayout()); + doxPanel.setBorder(new EmptyBorder(10,10,10,10)); + doxPanel.add(subSubSubDoxBox,BorderLayout.CENTER); + doxList.add(doxPanel); + + /*doxPanel = new JPanel(); + doxPanel.setBorder(new EmptyBorder(10,10,10,10)); + JLabel label = new JLabel("Number in category: "); + doxPanel.add(label); + numberInCategory = new JTextField(); + doxPanel.add(numberInCategory); + doxList.add(doxPanel);*/ + + doxList.setSize(450,125); + + contentPanel.add(doxList); + + tib = new JRadioButton("Tibetan"); + eng = new JRadioButton("English"); + ButtonGroup group = new ButtonGroup(); + group.add(tib); + group.add(eng); + group.setSelected(tib.getModel(),true); + + LangChanger langListener = new LangChanger(); + + tib.addActionListener(langListener); + eng.addActionListener(langListener); + + JPanel controlPanel = new JPanel();//new GridLayout(2,5) + //controlPanel.setBorder(new EmptyBorder(0,10,10,10)); + controlPanel.add(new JLabel()); + controlPanel.add(tib); + controlPanel.add(new JLabel()); + controlPanel.add(eng); + controlPanel.add(new JLabel()); + + controlPanel.add(new JLabel()); + + submit = new JButton("Submit"); + submit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) + { + submit(); + } + }); + controlPanel.add(submit); + + controlPanel.add(new JLabel()); + + cancel = new JButton("Cancel"); + cancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) + { + close(); + } + }); + + controlPanel.add(cancel); + controlPanel.add(new JLabel()); + + contentPanel.add(controlPanel); + + + getContentPane().add(contentPanel,BorderLayout.CENTER); + + show(); + + instructions.setSize(contentPanel.getSize().width-20,200); + + } + + public void setCategories(String masterID) + { + StringTokenizer stoke = new StringTokenizer(masterID,IDDELIM); + try { + String doxStr = stoke.nextToken(); + if(doxStr == null) {return;} + doxStr = doxStr.substring(doxStr.length()-1); + int index = -1; + try { + index = Integer.parseInt(doxStr)-1; + } catch (NumberFormatException nfe) {return;} + if(index>-1) { + mainDoxBox.setSelectedIndex(index); + } else {return;} + + doxStr = stoke.nextToken(); + if(doxStr == null) {return;} + doxStr.trim(); + index = -1; + try { + index = Integer.parseInt(doxStr)-1; + } catch (NumberFormatException nfe) {return;} + if(index>-1) { + subDoxBox.setSelectedIndex(index); + } else {return;} + + doxStr = stoke.nextToken(); + if(doxStr == null) {return;} + doxStr.trim(); + index = -1; + try { + index = Integer.parseInt(doxStr)-1; + } catch (NumberFormatException nfe) {return;} + if(index>-1) { + subSubDoxBox.setSelectedIndex(index); + } else {return;} + + doxStr = stoke.nextToken(); + if(doxStr == null) {return;} + doxStr.trim(); + index = -1; + try { + index = Integer.parseInt(doxStr)-1; + } catch (NumberFormatException nfe) {return;} + if(index>-1) { + subSubSubDoxBox.setSelectedIndex(index); + } else {return;} + } catch (NoSuchElementException nsee) {return;} + catch(IllegalArgumentException iae) {return;} + } + + public void setFileName() + { + if(controller == null) {return;} + java.io.File currFile = controller.getCurrentFile(); + fileName.setText("File name: " + currFile.getName()); + } + + // Accessor Methods + public String getDoxString(String lang) + { + String out = new String(); + + if(lang.equals("eng")) { + eng.doClick(); + } else { + tib.doClick(); + } + + out += (String)mainDoxBox.getSelectedItem() + DOXDELIM; + out += (String)subDoxBox.getSelectedItem(); + if(subSubDoxBox.isVisible()) { + out += DOXDELIM + (String)subSubDoxBox.getSelectedItem(); + if(subSubSubDoxBox.isVisible()) { + out += DOXDELIM + (String)subSubSubDoxBox.getSelectedItem(); + } + } + + return out; + } + + public String getID() + { + String out = new String("Ng"); + out += Integer.toString(mainDoxBox.getSelectedIndex()+1) + IDDELIM; + out += Integer.toString(subDoxBox.getSelectedIndex()+1); + if(subSubDoxBox.isVisible()) { + out += IDDELIM + Integer.toString(subSubDoxBox.getSelectedIndex()+1); + if(subSubSubDoxBox.isVisible()) { + out += IDDELIM + Integer.toString(subSubSubDoxBox.getSelectedIndex()+1); + } + } + + return out; + } + + + // Helper Methods + public void submit() + { + hide(); + //JOptionPane.showMessageDialog(this,"Id is: " + getID(), "Master ID", JOptionPane.INFORMATION_MESSAGE); + controller.enterDox(this); + close(); + } + + + public void close() + { + hide(); + dispose(); + } + + public DoxWindow(String title) + { + super(title); + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //********* CHANGE IN ACTUAL IMPLEMENTATION + setBounds(100,100,500,400); // *************** + this.controller = controller; + init(); + } + public DoxWindow(String title, String masterID, TiblEdit controller) + { + this(title); + this.controller = controller; + setCategories(masterID); + setFileName(); + } + + public static void main(String[] args) + { + try { + UIManager.setLookAndFeel( + "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Exception e) { + System.err.println("Exception: " + e.getMessage() + "\n" + + e.getClass().getName()); + } + + DoxWindow dw = new DoxWindow("Testing the Dox Window"); + + } + + public class TCombo extends JComboBox + { + TCombo parent; + String lang; + Dimension size = new Dimension(450,25); + + // fix the size of the combo box + public Dimension getMinimumSize() { + return getPreferredSize(); + } + public Dimension getPreferredSize() { + return size; + } + public Dimension getMaximumSize() { + return getPreferredSize(); + } + + public void setSize(Dimension d) { + } + public void setSize(int h, int w) { + } + + public void setVisible(boolean b) + { + super.setVisible(b); + try { + if(b == false) { + setSelectedIndex(0); + } + } catch (IllegalArgumentException iae) {} + } + + public TCombo getTComboParent() + { + return parent; + } + + public boolean hasParent() + { + if(parent == null) {return false;} + return true; + } + + public String getLang() + { + return lang; + } + + public void setLang(String lang) + { + this.lang = lang; + } + + public TCombo(String[] labels, TCombo parent) + { + super(labels); + this.parent = parent; + setSize(size); + setLang("tib"); + } + + public TCombo(String[] labels) + { + super(labels); + parent = null; + setSize(size); + setLang("tib"); + } + + public TCombo(TCombo parent) + { + super(); + this.parent = parent; + setSize(size); + setVisible(false); + setLang("tib"); + } + } + + public class DoxEar implements ActionListener + { + int type; + TCombo child; + String[] data; + + + public DoxEar(int type, TCombo child) + { + this.type = type; + this.child = child; + } + + + public void actionPerformed(ActionEvent ae) + { + TCombo parent = (TCombo)ae.getSource(); + String lang = parent.getLang(); + int parentIndex = parent.getSelectedIndex(); + data = null; + try { + if(lang.equals("tib")) { + if(type==MAIN) { + data = subDox[parentIndex]; + } else if(type == SUB) { + TCombo grampa = parent.getTComboParent(); + int grampsIndex = grampa.getSelectedIndex(); + data = subSubDox[grampsIndex][parentIndex]; + } else if(type == SUBSUB) { + TCombo grampa = parent.getTComboParent(); + int grampsIndex = grampa.getSelectedIndex(); + TCombo ancestor = grampa.getTComboParent(); + int ancestorIndex = ancestor.getSelectedIndex(); + data = subSubSubDox[ancestorIndex][grampsIndex][parentIndex]; + } + } else if(lang.equals("eng")) { + + if(type==MAIN) { + data = subEng[parentIndex]; + } else if(type == SUB) { + TCombo grampa = parent.getTComboParent(); + int grampsIndex = grampa.getSelectedIndex(); + data = subSubEng[grampsIndex][parentIndex]; + } else if(type == SUBSUB) { + TCombo grampa = parent.getTComboParent(); + int grampsIndex = grampa.getSelectedIndex(); + TCombo ancestor = grampa.getTComboParent(); + int ancestorIndex = ancestor.getSelectedIndex(); + data = subSubSubEng[ancestorIndex][grampsIndex][parentIndex]; + } + } + + if(data != null) { + DefaultComboBoxModel dcomboMod = new DefaultComboBoxModel(data); + child.setModel(dcomboMod); + child.setVisible(true); + child.repaint(); + child.setSelectedIndex(0); + } else { + child.setVisible(false); + child.repaint(); + } + } catch (ArrayIndexOutOfBoundsException aiob) { + } catch (NullPointerException npe) { + } + + } + } + + public class LangChanger implements ActionListener + { + + public void actionPerformed(ActionEvent ae) + { + int main,sub,subsb,subsbsb; + String command = ae.getActionCommand(); + try { + if(command.equals("Tibetan")) { + + main = mainDoxBox.getSelectedIndex(); + sub = subDoxBox.getSelectedIndex(); + subsb = subSubDoxBox.getSelectedIndex(); + subsbsb = subSubSubDoxBox.getSelectedIndex(); + + mainDoxBox.setLang("tib"); + mainDoxBox.setModel(new DefaultComboBoxModel(mainDox)); + subDoxBox.setLang("tib"); + subSubDoxBox.setLang("tib"); + subSubSubDoxBox.setLang("tib"); + + mainDoxBox.setSelectedIndex(main); + subDoxBox.setSelectedIndex(sub); + subSubDoxBox.setSelectedIndex(subsb); + subSubSubDoxBox.setSelectedIndex(subsbsb); + + + } else if(command.equals("English")) { + main = mainDoxBox.getSelectedIndex(); + sub = subDoxBox.getSelectedIndex(); + subsb = subSubDoxBox.getSelectedIndex(); + subsbsb = subSubSubDoxBox.getSelectedIndex(); + + + subSubSubDoxBox.setLang("eng"); + subSubDoxBox.setLang("eng"); + subDoxBox.setLang("eng"); + mainDoxBox.setLang("eng"); + mainDoxBox.setModel(new DefaultComboBoxModel(mainEng)); + + mainDoxBox.setSelectedIndex(main); + subDoxBox.setSelectedIndex(sub); + subSubDoxBox.setSelectedIndex(subsb); + subSubSubDoxBox.setSelectedIndex(subsbsb); + + } + } catch (NullPointerException npe) { + System.out.println("Null pointer exception caught!"); + } + } + + } + + +} diff --git a/source/org/thdl/tib/bibl/EditAction.java b/source/org/thdl/tib/bibl/EditAction.java new file mode 100644 index 0000000..8ad8ae5 --- /dev/null +++ b/source/org/thdl/tib/bibl/EditAction.java @@ -0,0 +1,65 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.event.ActionEvent; + +/** +*

+* This extension of {@link TibAction} is for Edit menu actions.Its constructor takes a String name and a TibFrame parent. With these it calls its +* super constructor. The action performed takes the following action commands: +*

+*
    +*
  • {@link TibConstants.TRANS_EDIT TRANS_EDIT} - calls {@link TiblEdit#editTranslation()} +*
  • {@link TibConstants.NORM_EDIT NORM_EDIT} - calls {@link TiblEdit#enterTranslation()} +*
  • {@link TibConstants.REMOVE_APP REMOVE_APP} - calls {@link TiblEdit#removeApp()} +*
  • {@link TibConstants.REMOVE_TITLE REMOVE_TITLE} - calls {@link TiblEdit#removeTitle()} +*
+*/ + +public class EditAction extends TibAction +{ + + public EditAction(String name, TibFrame f) + { + super(name,f); + } + + public void actionPerformed(ActionEvent e) + { + String command = e.getActionCommand(); + + if(command.equals(TRANS_EDIT)) + { + getController().editTranslation(); + } else if(command.equals(NORM_EDIT)) + { + org.jdom.Element normTitle = getController().getTibDoc().getTitleFactory().getNormalizedTitle(); + getController().setSelectedElement(normTitle); + getController().enterTranslation(); + } else if(command.equals(REMOVE_APP)) + { + getController().removeApp(); + } else if(command.equals(REMOVE_TITLE)) { + getController().removeTitle(); + } else if(command.equals(REMOVE_EDITION)) { + getFrame().chooseEdition(); + } + } +} diff --git a/source/org/thdl/tib/bibl/ElementList.java b/source/org/thdl/tib/bibl/ElementList.java new file mode 100644 index 0000000..a499b21 --- /dev/null +++ b/source/org/thdl/tib/bibl/ElementList.java @@ -0,0 +1,91 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import org.jdom.*; + +/** +*

+* Element List is a list of elements and ranges. The ranges refer to the {@link TextPanel} locations +* where the text for that element is found. The {@link #getElement} method takes an integer location +* in the TextPanel and returns the org.jdom.Element that is associated with that location +* if ther is one! If not, it returns null, indicating there is nothing to edit at +* that location. This is created by the TextPanel and given to the {@link TiblEdit} controller so +* it can turn on and off menu options and functionality, depending on the position of the cursor in +* the TextPane. +*

+* +* @author Than Garson, Tibetan and Himalayan Digital Library +* @version 1.0 +*/ + +public class ElementList implements TibConstants +{ + // + Vector entries; + int start, end, leng; + org.jdom.Element element; + Entry ent, lastEntry; + + public void addEntry(int st, int en, ElementStyle es) + { + ent = new Entry(st,en,es); + entries.add(ent); + lastEntry = ent; + } + + public org.jdom.Element getElementAt(int pos) + { + org.jdom.Element returnElement = NO_ELEM; + Iterator ents = entries.iterator(); + while(ents.hasNext()) { + Entry ent = (Entry)ents.next(); + if(ent.start<=pos && ent.end>=pos) { + //System.out.println("returning a found element: " + TiblEdit.outputString(ent.element)); + return ent.element; + } + } + + return returnElement; + } + + // Contructor + + public ElementList() + { + entries = new Vector(); + lastEntry = new Entry(-1,-1,new ElementStyle("","",NO_ELEM)); + } + + + protected class Entry + { + // + int start, end; + org.jdom.Element element; + + protected Entry(int start, int end, ElementStyle es) + { + this.start = start; + this.end = end; + element = es.getElement(); + } + } +} diff --git a/source/org/thdl/tib/bibl/ElementStyle.java b/source/org/thdl/tib/bibl/ElementStyle.java new file mode 100644 index 0000000..77977f5 --- /dev/null +++ b/source/org/thdl/tib/bibl/ElementStyle.java @@ -0,0 +1,56 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import org.jdom.*; + +/** +* This wrapper class associates a String of text with a Style (as defined in {@link TibConstants}?) and a particular +* element. It is used for interactivity with the {@link TextPane} so that highlighting or clicking on a string in the +* text pane can be associated with actions for processing the text within an element. +*/ + +public class ElementStyle implements TibConstants +{ + String style; + org.jdom.Element element; + String text; + + public String getStyle() + { + return style; + } + + public String getText() + { + return text; + } + + public org.jdom.Element getElement() + { + return element; + } + + public ElementStyle(String t, String s, org.jdom.Element e) + { + text = t; + style = s; + element = e; + } +} diff --git a/source/org/thdl/tib/bibl/FileAction.java b/source/org/thdl/tib/bibl/FileAction.java new file mode 100644 index 0000000..4754e9a --- /dev/null +++ b/source/org/thdl/tib/bibl/FileAction.java @@ -0,0 +1,57 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.event.ActionEvent; + +/** +* This class is used to associate actions with the File menu of {@link TibFrame}. +*/ + +public class FileAction extends TibAction +{ + + public FileAction(String name, TibFrame f) + { + super(name,f); + } + + public void actionPerformed(ActionEvent e) + { + String command = e.getActionCommand(); + if(command.equals(OPENFILE)) + { + getController().openFile(); + } else + if(command.equals(CLOSEFILE)) + { + getController().closeFile(); + } else + + if(command.equals(SAVE)) + { + boolean success = getController().saveTibbibl(); + + } else + if(command.equals(EXIT)) + { + getController().exit(); + } + } +} diff --git a/source/org/thdl/tib/bibl/GenericTibFactory.java b/source/org/thdl/tib/bibl/GenericTibFactory.java new file mode 100644 index 0000000..f2a0eb3 --- /dev/null +++ b/source/org/thdl/tib/bibl/GenericTibFactory.java @@ -0,0 +1,79 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import org.jdom.*; +import org.jdom.output.*; + +/** +* This abstract class is extended by both {@link IDFactory} and {@link TitleFactory}, and provides general functionality +* such as setting the document associated with the factory and setting text/styles for the {@link TextPane}. +*/ + +abstract class GenericTibFactory implements TibConstants +{ + // Attributes + protected TibDoc tibDoc; + protected Vector outStyles; + protected Iterator it; + org.jdom.Element grandparent, parent, child; + protected java.util.List children; + + // Accessors + protected void setDoc(TibDoc td) + { + tibDoc = td; + } + + // Generic methods for Setting text, styles and elements + protected void doReg(String st) + { + outStyles.add(new ElementStyle(st,TextPane.REG,NO_ELEM)); + } + + protected void doHeader(String st) + { + outStyles.add(new ElementStyle(st,TextPane.HEAD,NO_ELEM)); + } + + protected void doLabel(String st) + { + outStyles.add(new ElementStyle(st,TextPane.BOLD,NO_ELEM)); + } + + protected void addLineBreak() + { + doReg("\n"); + } + + protected void addSeparator() + { + doReg(SEPARATOR); + } + + protected abstract void processDoc(); + + // Constructor + protected GenericTibFactory(TibDoc td) + { + setDoc(td); + processDoc(); + } +} diff --git a/source/org/thdl/tib/bibl/IDFactory.java b/source/org/thdl/tib/bibl/IDFactory.java new file mode 100644 index 0000000..36829b4 --- /dev/null +++ b/source/org/thdl/tib/bibl/IDFactory.java @@ -0,0 +1,433 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import org.jdom.*; +import org.jdom.output.*; + +/** +* Like its sister class, {@link TitleFactory}, this class is used to access and display the information +* in the ID section of a TIBBIBL record. +*/ + +public class IDFactory extends GenericTibFactory implements TibConstants +{ + /** + *

+ * IDFactory is a helper class that takes a {@link TibDoc} in its constructor, + * processes that doc so that certain information (tags and data) within it is + * easily accessible for display and modification. This information has to do with + * the identification of the text. ID numbers and so forth. + *

+ **/ + // Attributes + org.jdom.Element tibidDecl, topTibid, masterTibid, tibid, altid, physdecl, pagination; + org.jdom.Element num, sourceFiles; + org.jdom.Element[] ed_tibids, nums; + org.jdom.Attribute att; + String sigla, value; + Vector editions; + Hashtable ed_names, textNums, vols, vol_lets, num_in_vols, pages; + + /** + *

+ * This methods is called as the initializing method for this class. It takes + * the {@link TibDoc} given in the constructor and processes it finding the relavant + * information for its identification. It does this by reading through the TIBID elements + * contained in the TIBIDDECL and extracting from their children edition name, sigla, volume + * volume letter, text number, pagination. + * And from the sources listed in the control info section. + *

+ **/ + protected void processDoc() + { + editions = new Vector(); + ed_names = new Hashtable(); + textNums = new Hashtable(); + vols = new Hashtable(); + vol_lets = new Hashtable(); + num_in_vols = new Hashtable(); + pages = new Hashtable(); + + tibidDecl = tibDoc.getRoot().getChild(TIDDECL); + + if(tibidDecl == null) { + System.out.println("Could not set TibidDecl in IDFactory!\n" + + TiblEdit.outputString(tibDoc.getRoot())); + return; + } + + ed_tibids = tibDoc.toElementArray(tibidDecl.getChildren(TID)); + + if(ed_tibids == null) { + System.out.println("Can't find any children tibids of tibiddecl in IDFactory!\n" + + TiblEdit.outputString(tibidDecl)); + return; + } + + for(int n=0; n-1) { + sigla = NG; + tibid.setAttribute(CORRESP,NG); + masterTibid = tibid; + } + if(sigla == null || sigla.equals("")) {System.out.println("Null sigla: " + TiblEdit.outputString(tibid)); continue; } + editions.add(sigla); + ed_names.put(sigla,value); + // the edition sigla Tibid is skipped as it is the same as the corresp value + // instead get it's two children (text num and vol num) + children = tibid.getChild(TID).getChildren(TID); + if(children == null) { + System.out.println("Can't find the children of the sigla tibid in IDFactory!\n" + + TiblEdit.outputString(ed_tibids[n])); + continue; + } + + // deal with ed text number + tibid = (org.jdom.Element)children.get(0); + if(tibid == null) { + System.out.println("No ed text number tibid in IDFactory!\n" + + TiblEdit.outputString(ed_tibids[n])); + } else { + value = tibDoc.cleanString(tibid.getText()); + textNums.put(sigla,value); + } + + // deal with vol info + if(children.size()<2) { + /*System.out.println("Only one children in vol info!\n" + + TiblEdit.outputString(tibid.getParent()));*/ + continue; + } + tibid =(org.jdom.Element)children.get(1); + if(tibid == null) { + /*System.out.println("No vol info for tibid in IDFactory!\n" + + TiblEdit.outputString(ed_tibids[n]));*/ + continue; + } + + // volume number + value = tibDoc.cleanString(tibid.getText()); + vols.put(sigla,value); + + // volume letter + altid = tibid.getChild(ALT); + if(altid == null) { + System.out.println("Can't find altID in IDFactory!\n" + + TiblEdit.outputString(ed_tibids[n])); + } else { + value = tibDoc.cleanString(altid.getText()); + vol_lets.put(sigla,value); + } + // text number in volume + tibid = tibid.getChild(TID); + if(tibid == null) { + System.out.println("Can't find volume text number TID in IDFactory!\n" + + TiblEdit.outputString(ed_tibids[n])); + continue; + } + value = tibDoc.cleanString(tibid.getText()); + num_in_vols.put(sigla,value); + } + + // Find paginations and add to their hashtable + physdecl = tibDoc.getRoot().getChild(PHYSDEC); + if(physdecl == null) { + System.out.println("No physdecl for this text in IDFactory!\n" + + TiblEdit.outputString(tibDoc.getRoot())); + return; + } + pagination = physdecl.getChild(PAGIN); + if(pagination == null) { + System.out.println("No pagination for this text in IDFactory!\n" + + TiblEdit.outputString(physdecl)); + return; + } + nums = tibDoc.toElementArray(pagination.getChildren(NUM)); + if(nums == null) { + System.out.println("Can't find any individual num elements in pagination in IDFactory!\n" + + TiblEdit.outputString(pagination)); + return; + } + for(int n=0;n + * This method returns the String version of the master ID where all the subcategories are + * delimited by a period, e.g. Ng1.4.2. It does this by recursively looking for a child Tibid + * within the master Tibid and adding the period delimiter between each of the content strings. + *

+ * + * @return String - the formatted Master ID string. + */ + public String getMasterID() + { + String out = new String(); + child = masterTibid.getChild(TID); + int n=0; + while(child != null) { + out += tibDoc.cleanString(child.getText()); + child = child.getChild(TID); + if(child != null) { out += DOX_DELIM;} + } + return out; + } + + /** + *

+ * This method takes a string as its parameter that is in the usual master ID format with subcategories + * separated by the period or the {@link TibConstants#DOX_DELIM DOX_DELIM}. It parses it through a + * StringTokenizer and using the {@link #masterTibid} fills out the information. It does not however + * set the text's number within the category but it leaves a last Tibid empty ready for that information. + *

+ * + * @param String - the master ID string + * + * @Return String - the new file name based on the master ID + */ + public void setMasterID(String masterID) + { + if(masterID == null) {return;} + StringTokenizer toker = new StringTokenizer(masterID.trim(),DOX_DELIM); + + // The first child is the Ng1, Ng2, Ng3,or Ng4 sigla. + child = masterTibid.getChild(TID); + child.setAttribute(TYPE,ED); + child.setAttribute(SYS,SIG); + + while(child != null && toker.hasMoreTokens()) { + child.setText(toker.nextToken()); + child.setAttribute(TYPE,CLASS); + child.setAttribute(SYS,NUMB); + parent = child; + child = child.getChild(TID); + } + + while(toker.hasMoreTokens()) { + child = new org.jdom.Element(TID); + child.setAttribute(TYPE,CLASS); + child.setAttribute(SYS,NUMB); + child.setText(toker.nextToken()); + parent.addContent(child); + parent = child; + child = null; + } + + if(child == null) { + child = new org.jdom.Element(TID); + parent.addContent(child); + } + + // For the text number use the first three words of the title for now. + child.setAttribute(TYPE,TEXT); + child.setAttribute(SYS,NUMB); + + } + + public org.jdom.Element[] getSourceFiles() + { + org.jdom.Element controlinfo = tibDoc.findElement(CONTROL); + Iterator it = controlinfo.getChildren(RESPSTM).iterator(); + if(it != null) { + while(it.hasNext()) { + org.jdom.Element respStmt = (org.jdom.Element)it.next(); + String nAtt = respStmt.getAttributeValue(N); + if(nAtt != null && nAtt.equals(SRC)) + return tibDoc.toElementArray(respStmt.getChildren(NAME)); + } + } + return null; + } + + public boolean hasEdition(String sigla) + { + if(editions.indexOf(sigla)>-1) { + return true; + } + return false; + } + + public String getEdName(String sigla) + { + return (String)ed_names.get(sigla); + } + + public String getTextNum(String sigla) + { + return (String)textNums.get(sigla); + } + + public String getVolNum(String sigla) + { + return (String)vols.get(sigla); + } + + public String getVolLet(String sigla) + { + return (String)vol_lets.get(sigla); + } + + public String getNumInVol(String sigla) + { + return (String)num_in_vols.get(sigla); + } + + public String getPagination(String sigla) + { + return (String)pages.get(sigla); + } + + public Vector getEditionsConsulted() + { + return editions; + } + + public boolean addEditionConsulted(String[] info) + { + //System.out.println("Text's TibidDecl: \n" + TiblEdit.outputString(tibidDecl)); + if(info.length != NEW_ED_INFO_SPECS.length) { + System.out.println("The information given to add an edition in IDFactory is not the right size: " + info.length); + return false; + } + try{ + sigla = info[1]; + + grandparent = new org.jdom.Element(TID); + grandparent.setAttribute(CORRESP,sigla); + grandparent.setAttribute(TYPE,ED); + grandparent.setAttribute(SYS,LET); + grandparent.setText(info[0]); + + parent = new org.jdom.Element(TID); + parent.setAttribute(TYPE,ED); + parent.setAttribute(SYS,SIG); + parent.setText(sigla); + grandparent.addContent(parent); + + tibid = new org.jdom.Element(TID); + tibid.setAttribute(TYPE,TEXT); + tibid.setAttribute(SYS,NUMB); + tibid.setText(info[2]); + parent.addContent(tibid); + + tibid = new org.jdom.Element(TID); + tibid.setAttribute(TYPE,VOL); + tibid.setAttribute(SYS,NUMB); + tibid.setText(info[3]); + parent.addContent(tibid); + + parent = tibid; + altid = new org.jdom.Element(ALT); + altid.setAttribute(SYS,LET); + altid.setAttribute(LANG,TIB); + altid.setText(info[4]); + parent.addContent(altid); + + tibid = new org.jdom.Element(TID); + tibid.setAttribute(TYPE,TXT); + tibid.setAttribute(SYS,NUMB); + tibid.setText(info[5]); + parent.addContent(tibid); + + tibidDecl.addContent(grandparent); + + num = new org.jdom.Element(NUM); + num.setAttribute(CORRESP,sigla); + num.setText(info[6]); + pagination.addContent(num); + + processDoc(); + + return true; + + } catch (org.jdom.IllegalAddException iae) { + System.out.println("Illegal add exception (JDOM) caught in trying to create new edition tibid in IDFactory!"); + } + addSourceConsulted(sigla,tibDoc.getEditorID(),tibDoc.getEditorName()); + return false; + } + + public void removeEd(String sigla) + { + tibid = findEdTibid(sigla); + if(tibid != null) + { + tibid.detach(); + } + } + + public org.jdom.Element findEdTibid(String sigla) + { + if(ed_tibids == null) {return null;} + for(int n=0;nThis extension of {@link TibAction} is used for the actions associated with the Insert menu of +* the {@link TibFrame}. Its constructor takes a String name and a TibFrame parent. With these it calls its +* super constructor. The action performed takes the following action commands: +*

+*
    +*
  • {@link TibConstants.ED_INFO ED_INFO} - calls {@link TiblEdit#insertNewEdition()} +*
  • {@link TibConstants.CRIT_TITLE CRIT_TITLE} - calls {@link TiblEdit#insertCritTitle()} +*
  • {@link TibConstants.ED_TITLE ED_TITLE} - calls {@link TiblEdit#insertEdTitle()} +*
  • {@link TibConstants.TITLE_DISC TITLE_DISC} - calls {@link TiblEdit#insertDiscussion()} +*
  • {@link TibConstants.INSERT_APP INSERT_APP} - calls {@link TiblEdit#insertApp()} +*
+*/ + +public class InsertAction extends TibAction +{ + + + public InsertAction(String name, TibFrame f) + { + super(name,f); + } + + public void actionPerformed(ActionEvent e) + { + String command = e.getActionCommand(); + + if(command.equals(ED_INFO)) + { + getController().insertNewEdition(); + + } else if(command.equals(CRIT_TITLE)) + { + getController().insertCritTitle(); + + } else if(command.equals(ED_TITLE)) + { + getController().insertEdTitle(); + + } else if(command.equals(TITLE_DISC)) + { + getController().insertDiscussion(); + } else if(command.equals(INSERT_APP)) + { + getController().insertApp(); + } + } +} diff --git a/source/org/thdl/tib/bibl/IntroSign.java b/source/org/thdl/tib/bibl/IntroSign.java new file mode 100644 index 0000000..05bde69 --- /dev/null +++ b/source/org/thdl/tib/bibl/IntroSign.java @@ -0,0 +1,134 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridLayout; +import java.awt.Toolkit; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.border.Border; +import javax.swing.border.BevelBorder; + +/** +* This class displays the initial splash screen upon opening the program. +*/ + +public class IntroSign extends JFrame implements Runnable +{ + // Attributes + JPanel cp, outPanel; + String topline, title, org, byline; + Toolkit xKit; + Dimension wndSize, signSize, frameSize; + Color bgColor = Color.getColor("silver"); + Color fgColor = Color.getColor("purple"); + Font headFont = new Font("Times",Font.BOLD,14); + Font labelFont = new Font("Times",Font.PLAIN,12); + String HOME = System.getProperties().getProperty("user.dir"); + String imageURL = new String("bin//knot.gif"); + + private void init() + { + xKit = getToolkit(); + wndSize = xKit.getScreenSize(); + frameSize = new Dimension(300,250); + setSize(frameSize); + setLocation((wndSize.width-300)/2, (wndSize.height-250)/2); + + setBackground(bgColor); + setUndecorated(true); + + ImageIcon knot = new ImageIcon(imageURL); + title = "TiblEdit: XML Editor for Tibbibl Mark Up"; + byline = "Written by Than Garson, UVa"; + org = "©2002, Tibetan & Himalayan Digital Library"; + + cp = new JPanel(); + cp.setPreferredSize(frameSize); + cp.setBackground(bgColor); + cp.setForeground(fgColor); + Border outside = BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black,1), + BorderFactory.createBevelBorder(BevelBorder.RAISED)); + cp.setBorder(BorderFactory.createCompoundBorder(outside,BorderFactory.createEmptyBorder(10,5,5,5))); + cp.setLayout(new GridLayout(0,1)); + cp.add(doLabel(knot)); + cp.add(doLabel(title)); + cp.add(doLabel(byline)); + cp.add(doLabel(org)); + getContentPane().add(cp,BorderLayout.CENTER); + pack(); + } + + private JLabel doLabel(String in) + { + JLabel lab = new JLabel(in, JLabel.CENTER); + lab.setForeground(fgColor); + if(in.equals(title)) { + lab.setFont(headFont); + } else { + lab.setFont(labelFont); + } + return lab; + } + + private JLabel doLabel(ImageIcon im) + { + JLabel lab = new JLabel(" ",im,JLabel.CENTER); + return lab; + } + + public void close() + { + setVisible(false); + dispose(); + } + + public IntroSign() { + init(); + //addMouseListener(new IntroMouseListener(this)); + } + + public void run() + { + setVisible(true); + for(int s=0;s<2000;s++) + { + toFront(); + try { + Thread.sleep(1); + } catch (InterruptedException e){setVisible(false); dispose();} + } + setVisible(false); + close(); + dispose(); + } + + public static void main(String[] args) + { + + } + +} diff --git a/source/org/thdl/tib/bibl/TTFileView.java b/source/org/thdl/tib/bibl/TTFileView.java new file mode 100644 index 0000000..b814b09 --- /dev/null +++ b/source/org/thdl/tib/bibl/TTFileView.java @@ -0,0 +1,103 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.filechooser.*; +import org.jdom.*; +import org.jdom.input.*; +import org.jdom.output.*; +//import org.thdl.tib.bibl.shared.*; + +/** +*

+* TTFileView test to see if a file is an .xml file and if so, assumes it's a Tibbibl +* and searches for the first <title> element and sets the file's description to that. +* It then uses this description for the name of the text by overriding the {@link #getName} function. +* This is used in for the {@link javax.swing.JFileChooser} in FileAction so that +* when the open-file window appears it lists the text names instead of the file names. +*

+* +* @author Than Garson, Tibetan and Himalayan Digital Library +* @version 1.0 +*/ + +public class TTFileView extends FileView implements TibConstants +{ + private Hashtable fileDescs = new Hashtable(5); + private XMLReader docHandler = new XMLReader(); + + + /** + *

+ * Overrides the ancestor's--{@link javax.swing.JFileChooser.FileView}--getName() function + * so that it returns the text title as the name, if it is an XML file. This has the + * effect of presenting a list of text names in the open dialog rather than their less + * comprehensible file names. + *

+ * + * @param fl File whose name is requested. + * @return String the description of the file which has been set to + * the text title if it is an XML file. + * + */ + public String getName(File fl) { + if(getDescription(fl) == null && fl.getName().indexOf(".xml")>-1) + putDescription(fl); + return getDescription(fl); + } + + /** + *

+ * Adds a description to the file, if the file is an XML file and the docHandler, + * that is an {@link XMLReader}, successfully processes the document and returns a {@link TibDoc}. + * Furthermore, it must find a <title> element (the first in the document) with some text. + * If all these conditions are met, the description of the file is set to the text of the title + * element. Otherwise, the description is set to null. + *

+ */ + public void putDescription(File fl) { + String fileDescription; + if(docHandler.setDoc(fl)) + { + try { + org.jdom.Element td = docHandler.getRoot(); + org.jdom.Element th = td.getChild(HEAD).getChild(TITLE); + fileDescription = th.getText(); + } catch (NullPointerException npe) { + fileDescription = null;} + } else { + fileDescription = null; + } + if(fileDescription != null) + fileDescs.put(fl,fileDescription.trim()); + } + + /** + * Returns a human readable description of the file. + * + * @see FileView#getDescription + */ + public String getDescription(File f) { + return (String) fileDescs.get(f); + }; + +} diff --git a/source/org/thdl/tib/bibl/TextPane.java b/source/org/thdl/tib/bibl/TextPane.java new file mode 100644 index 0000000..e24e235 --- /dev/null +++ b/source/org/thdl/tib/bibl/TextPane.java @@ -0,0 +1,283 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import java.awt.Color; +import java.awt.Insets; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.text.*; +import org.jdom.*; +import org.jdom.output.*; + +//import org.thdl.tib.bibl.shared.*; + + +/** +* An extension of Swing's JPanel that is used to create the display for a +* text's bibliographic information. The panel is created using the text's information +* contained in a {@link TibDoc} and then is added or set to the content pane +* of the main frame which is an {@link TibFrame}. +*/ + +public class TextPane extends JTextPane implements TibConstants +{ + TiblEdit controller; + + /** + *

+ * This is the TibDoc that is the XML document from which the information for + * the JTextPane's document comes. It needs to be here so we can use it functionality + * to navigate the XML hierarchy and extract certain information. + *

+ */ + TibDoc tibDoc; + + /** + *

+ * This is a two-dimensional array of {@link org.jdom.Element}s that holds the titles displayed in + * this text pane, with the strings starting position, and length. It is used to reference the + * element for editing when the cursor is positioned on a specific title. + *

+ */ + Object[][] titleRefs; + + int caretPos; + + /** + *

+ * This and the following are static, style constants, i.e. names of the styles + *

+ */ + public static String REG = "regular"; + public static String HEAD = "header"; + public static String HEAD_ITALIC = "headitalic"; + public static String TEXT_HEAD = "textheader"; + public static String TEXT_HEAD_ITALIC = "textheaderItalic"; + public static String ITALIC = "italic"; + public static String BOLD = "bold"; + public static String ADD = "addition"; + public static String VARIANT = "variant"; + public static String RED = "red"; + public static String SMALL = "small"; + public static String LARGE = "large"; + + public void setController(TiblEdit tt) + { + controller = tt; + } + + public TiblEdit getController() + { + return controller; + } + + /** + *

+ * This method takes a string array of phrases and a string array of associated style names + * iterates through them and inserts the strings with their styles one by one into + * this TextPane's document. + *

+ * + * @param String[] - The array of text phrases to be added to the document + * @param String[] - The array of styles associated with the respective text phrases. + */ + public void setTextPane(String[] phrases, String[] styles) + { + javax.swing.text.StyledDocument doc = new DefaultStyledDocument(); + setDocument(doc); + caretPos = 0; + try { + for (int i=0; i < phrases.length; i++) { + int lng = doc.getLength(); + doc.insertString(lng, phrases[i], + this.getStyle(styles[i])); + if(phrases[i].indexOf(ENTER_TRANS_PHRASE)>-1 || phrases[i].indexOf(ENTER_NORM_TRANS_PHRASE)>-1) { + caretPos = doc.getLength(); + } + } + } catch (BadLocationException ble) { + System.err.println("Couldn't insert initial text."); + } + if(caretPos > -1) { + try { + setCaretPosition(caretPos); + getCaret().setVisible(true); + } catch (IllegalArgumentException ia) {System.out.println("Illegal argument in setting caret pos: " + caretPos);} + } else { + getCaret().setVisible(false); + } + } + + // Document this: it overrides the above, adding a list of elements that are associated with + // the text runs and returns and {@link ElementList} for referencing. + public ElementList setTextPane(Vector styleElements) + { + javax.swing.text.Document doc = this.getDocument(); + ElementList elemList = new ElementList(); + caretPos=0; + int len = styleElements.size(); + String phrase = new String(); + String style = new String(); + Iterator it = styleElements.iterator(); + int n = 0; + while(it.hasNext()) + { + ElementStyle es = (ElementStyle)it.next(); + phrase = es.getText(); + style = es.getStyle(); + + try { + int lng = doc.getLength(); + int end = lng + phrase.length(); + doc.insertString(lng, phrase, this.getStyle(style)); + elemList.addEntry(lng,end,es); + if(phrase.indexOf(ENTER_TRANS_PHRASE)>-1 || phrase.indexOf(ENTER_NORM_TRANS_PHRASE)>-1) { + caretPos = doc.getLength(); + } + + } catch (BadLocationException ble) { + System.err.println("Couldn't insert initial text."); + } + } + if(caretPos > -1) { + try { + setCaretPosition(caretPos); + getCaret().setVisible(true); + } catch (IllegalArgumentException ia) {System.out.println("Illegal argument in setting caret pos: " + caretPos);} + } else { + getCaret().setVisible(false); + } + + return elemList; + } + + /* + *

+ * This method serves to reset the text + * pane with a blank document with initialized styles ready to open another + * tibbibl. + *

+ */ + public void reset() + { + setDocument(new DefaultStyledDocument()); + initStyles(); + } + + // Helper Methods + /** + *

+ * This method initializes the styles used for the given {@link JTextPane}. + * It adds a regular, italic, bold, small, and large styles, plus styles that + * change the background color to green, yellow, or red to indicate different + * types of annotations. Green = addition; yellow = alternative reading or variant; + * red = omission/deletion. + *

+ * + * @param JTextPane to which the new styles are added. + * + */ + protected void initStyles() { + + Style def = StyleContext.getDefaultStyleContext(). + getStyle(StyleContext.DEFAULT_STYLE); + StyleConstants.setFontFamily(def, BASE_FONT_NAME); + StyleConstants.setFontSize(def,BASE_FONT_SIZE); + + Style regular = this.addStyle(REG, def); + + Style header = this.addStyle(HEAD, regular); + StyleConstants.setBold(header, true); + StyleConstants.setUnderline(header, true); + StyleConstants.setFontSize(header,HEAD_FONT_SIZE); + + Style s = this.addStyle(HEAD_ITALIC, header); + StyleConstants.setItalic(s, true); + + Style textHeader= this.addStyle(TEXT_HEAD,regular); + StyleConstants.setBold(textHeader, true); + StyleConstants.setFontSize(textHeader,TEXT_HEAD_SIZE); + + s = this.addStyle(TEXT_HEAD_ITALIC,textHeader); + StyleConstants.setItalic(s,true); + + s = this.addStyle(ITALIC, regular); + StyleConstants.setItalic(s, true); + + s = this.addStyle(BOLD, regular); + StyleConstants.setBold(s, true); + + s = this.addStyle(ADD,regular); + StyleConstants.setBackground(s,Color.green); + + s = this.addStyle(VARIANT,regular); + StyleConstants.setBackground(s,Color.yellow); + + s = this.addStyle(RED,regular); + StyleConstants.setForeground(s,Color.red); + + s = this.addStyle(SMALL, regular); + StyleConstants.setFontSize(s, 10); + + s = this.addStyle(LARGE, regular); + StyleConstants.setFontSize(s, 16); + + } + + public int getOffset() + { + return caretPos; + } + + public int getPreviousParagraphIndex() + { + int start = getSelectionStart(); + if(start>-1) { + String fulltxt = getText(); + int lastP = fulltxt.lastIndexOf("\n",start); + return lastP; + } + return start; + } + + public JScrollPane getScrollPane() + { + JScrollPane jsp = new JScrollPane(this, + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + return jsp; + } + + // Constructors + + public TextPane(TiblEdit tt) + { + super(); + setController(tt); + initStyles(); + addMouseListener(controller); + setEditable(false); + setCaretPosition(0); + caretPos = 0; + setMargin(new Insets(10,10,10,10)); + } +} + diff --git a/source/org/thdl/tib/bibl/TibAction.java b/source/org/thdl/tib/bibl/TibAction.java new file mode 100644 index 0000000..433175d --- /dev/null +++ b/source/org/thdl/tib/bibl/TibAction.java @@ -0,0 +1,55 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import javax.swing.AbstractAction; +import java.io.File; + +/** +* This extension of javax.swing.AbstractAction is used for the various menus in {@link TibFrame}. It assigns two +* special key/value pairs: the frame, which points to the TibFrame, and the controller which is the main program, +* TiblEdit. +*/ + +abstract class TibAction extends AbstractAction implements TibConstants +{ + // Accessors + public void setKeys(TibFrame f) + { + putValue(FRAME,f); + putValue(CONTROLLER,f.getController()); + } + + public TibFrame getFrame() + { + return (TibFrame)getValue(FRAME); + } + + public TiblEdit getController() + { + return (TiblEdit)getValue(CONTROLLER); + } + + // Constructor + TibAction(String name, TibFrame f) + { + super(name); + setKeys(f); + } +} diff --git a/source/org/thdl/tib/bibl/TibConstants.java b/source/org/thdl/tib/bibl/TibConstants.java new file mode 100644 index 0000000..1333791 --- /dev/null +++ b/source/org/thdl/tib/bibl/TibConstants.java @@ -0,0 +1,499 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.io.*; +import java.awt.*; +import javax.swing.*; +import java.util.Hashtable; + +/** +* This interface contains all the constants used throughout the TiblEdit program. They are roughly organized +* according to type, but the organization could definitely be cleaned up some. +*/ + +public interface TibConstants +{ + + // File Constants + final String DEFAULT_DIRECTORY = System.getProperties().getProperty("user.dir"); + final String BIN = "\\bin\\"; + final String DATA_DIRECTORY = "\\data\\"; + final String OUT_DIRECTORY = "\\data\\"; + final String BIN_LOGIN = "\\bin\\logs\\"; + final String DIA_DATA = "\\bin\\dia.dat"; + final String TEMP_DIR = "\\bin\\temp\\"; + final String PREFS = "ttprefs.ini"; + + final String PREFS_DELIM = "="; + + // Frame Constants + final String PROG_NAME = "TiblEdit: "; + final String DEFAULT_HEADER = PROG_NAME + "An XML Editor for Tibetan Bibliographic Records"; + + // Menu Constants + // File Menu + final String FILE = "File"; + final String OPENFILE = "Open"; + final String TITLEOPENFILE = "Open by Title"; + final String CLOSEFILE = "Close"; + final String SAVE = "Save"; + final String SAVEAS = "Save As"; + final String EXPORT = "Export"; + final String EXIT = "Exit"; + + // Edit Menu + final String EDIT = "Edit"; + final String TRANS_EDIT = "Translation"; + final String NORM_EDIT = "Normalized Title"; + final String REMOVE_APP = "Remove Variants"; + final String REMOVE_TITLE = "Remove Title"; + final String REMOVE_EDITION = "Remove Edition"; + + // Insert Menu + final String INSERT = "Insert"; + final String ED_INFO = "New Edition Info"; + final String CRIT_TITLE = "Critical Title"; + final String ED_TITLE = "Edition Title"; + final String TITLE_DISC = "Insert Discussion"; + final String INSERT_APP = "Variant Reading"; + + // View Menu + final String VIEW = "View"; + final String TITLES_VIEW = "View Titles"; + final String MASTER_ID_VIEW = "Master ID/Doxography"; + final String USER_ID_VIEW = "Editor's Info"; + + final String EDCON = "Editions Consulted"; + final String DIAC = "Diacritics"; + final String ABOUT = "About TiblEdit"; + + // TibAction Constants (should these go in TibAction? + final String CONTROLLER = "controller"; + final String FRAME = "frame"; + final String CURR_DIR = "current directory"; + + final String[] NGDIVS = { "Atiyoga", "Anuyoga", "Mah\u0101yoga", "Unclassified" }; + final String[] NGSIGS = { "Ng1", "Ng2", "Ng3", "Ng4" }; + final String OTHER = "Other Edition"; + final String EDS_CORR = "Editor's Correction"; + final String[] OTHER_EDS = { "Tk","Dg","Kg","Wa","Bg",OTHER}; + final int SELDIV = 0; + final String GEN = "General"; + + + // Button labels + final String SUBMIT = "Submit Translations"; + final String ENTER = "Enter"; + final String CANCEL = "Cancel"; + final String ADD_DOX = "Add Doxographical Sub-category"; + + // Labels & Headers + final String LABEL_SPACE = " "; + final String CROSSREF = "Cross-references:"; + final String NORM_TITLE_HEAD = "Normalized Title\n"; + final String NORM_TIB_LABEL = "Normalized Title (Tib): "; + final String NORM_ENG_LABEL = "Normalized Title (Eng): "; + final String TITLE_LINE_HEAD = "\nTitle Line\n"; + final String EOC_TITLES_HEAD = "\nEnd of Chapter Titles\n"; + final String NON_TIB_TITLE_HEAD = "\nNon-Tibetan Title\n"; + final String CHAP_TITLES_HEAD = "\nChapter Titles\n"; + final String CLOSE_TITLE_HEAD = "Back Titles"; + final String NON_TIB_HEAD = "\nNon-Tibetan Title\n"; + final String SRCS_LABEL = "Sources: "; + final String ENTER_PLACE = " \n"; + final String ENTER_TRANS_PHRASE = "\nEnter Translation: "; + final String ENTER_TITLE_PHRASE = "\nEnter Title: "; + final String ENTER_NORMALIZED_PHRASE= "Normalized title: "; + final String ENTER_NORM_TRANS_PHRASE= "Translation: "; + final String DOX_WINDOW_TITLE = "Doxographic Classification/Master ID Number"; + final String DISC_DIA_TITLE = "Discussion Entry Form"; + final String SEPARATOR = "------------------------------------\n"; + + // Fonts + final String BASE_FONT_NAME = "Arial Unicode MS"; + int BASE_FONT_SIZE = 14; + int HEAD_FONT_SIZE = 16; + int TEXT_HEAD_SIZE = 18; + final Font DEFAULT_FONT = new Font(BASE_FONT_NAME,Font.PLAIN,BASE_FONT_SIZE); + final Font TITLE_FONT = new Font(BASE_FONT_NAME,Font.ITALIC,BASE_FONT_SIZE); + final Font MENU_FONT = new Font(BASE_FONT_NAME,Font.PLAIN,12); + final Font BOLD_FONT = new Font(BASE_FONT_NAME,Font.BOLD,BASE_FONT_SIZE); + final Font HEAD_FONT = new Font(BASE_FONT_NAME,Font.BOLD,HEAD_FONT_SIZE); + + // Styles (names) + final String BOLD = "bold"; + final String ITALIC = "italics"; + + // Sizes + final Dimension TIBPANEL_SIZE = new Dimension(10,10); + final Dimension BUTTON_SIZE = new Dimension(100,30); + final Dimension SHORT_LABEL_SIZE = new Dimension(100,75); + final Dimension LABEL_SIZE = new Dimension(500,75); + final Dimension ED_SCROLL_SIZE = new Dimension(400,400); + final Dimension BUTT_PANEL_SIZE = new Dimension(500,500); + final Dimension DEFAULT_PANEL_SIZE = new Dimension(550,600); + + final int TTFCOLS = 30; + final int TEXT_FIELD_SIZE = 15; + + // Colors + final Color DEFAULT_BGCOLOR = new Color(250,250,250);// 250,235,215); // antique white + final Color DEFAULT_BUTTON_COLOR = new Color(200,180,200); + final Color LIST_COLOR = Color.blue; + final Color TEXT_COLOR = Color.black; + + // Insets & Borders + final Insets DEFAULT_INSETS = new Insets(10,0,10,10); + final Insets LIST_INSETS = new Insets(10,10,10,1000); + final Insets MAIN_MARGINS = new Insets(10,10,10,10); + final Insets BUT_MARGINS = new Insets(25,25,25,25); + + // Integer Constants (choices) + final int NORM = 1; // Normalized title choice & normal display mode choice + final int TITLELINE = 2; // Title line choice + final int EOC = 3; // End of chapter titles choice. + final int CLOSING = 4; // Closing section titles. + final int NONTIBET = 5; // Non-Tibetan title choice. + final int CHAPS = 6; // Chapter titles. + + // Display Modes + final int ENTER_TRANS = 2; // for entering a translation + final int NEW_TITLE = 3; // for entering a new title + final int NEW_AP = 4; // for entering a new app + final int CANCEL_NEW_APP = 5; // When a new app entry is cancelled. + final int SHOW_AP = 6; // when showing an old app + final int ENTER_NORMALIZED = 7; // when entering a normalized title. + final int CANC = 8; // for cancelling + final int DO_TRANS = 9; // for editing a translation + + final String YES = "yes"; + final String NO = "no"; + final String IS_FILE_LIST = "filelist"; + final String AP_CHECK = "Checking app!"; + final String ED_TITLE_REM = "Removing Edition Title"; + // Observer types and hashkeys + final String TABLE = "table"; + final String APP_SUBMIT = "Submit App"; + final String REDISPLAY = "Redisplay"; + // also uses AP for app and TYPE for type keys. + final String RECENT = "recent_file"; + final int RECENT_FILE_SIZE = 8; + // XML Constants + // sigla constants + final String NG = "Ng"; + final String TB = "Tb"; + final String TK = "Tk"; + final String DG = "Dg"; + final String BG = "Bg"; + final String KG = "Kg"; + + final String[] EDNAMES = {"Master","mTshams brag","gTing skyes","sDe dge","Bai ro'i rgyud 'bum","sKyid grong"}; + + // Element and Attribute Constants + final String TIBL = "tibbibl"; // Element/root name + final String ID = "id"; // Attribute name + final String LVL = "level"; // Attribute name on Tibbibls (either, volume, text, chapter) + final String ED = "edition"; // Attribute value + final String SIG = "sigla"; // Attribute value + final String CLASS = "class"; // Attribute value + final String LET = "letter"; // Attribute value + final String TXT = "text"; // Attribute value + final String CHAPTER = "Chapter"; // Attribute value + final String DIV = "div1"; // Element name part + final String TYPE = "type"; // Attribute name + final String SUBTYPE = "subtype"; // Attribute name + final String TEXT = "text"; // Attribute value for DIVs 3 or 4. + final String TIBBIBL = "tibbibl"; // Element name for text's root element. + final String TITLE = "title"; // Element name + final String NORM_TITLE = "Normalized title"; // Attribute value (TYPE) + final String FOREIGN = "foreign"; // Element name + final String LANG = "lang"; // Attribute name + final String TIB = "tib"; // Attribute value + final String ENG = "eng"; // Attribute value + final String N = "n"; // Attribute name + final String P = "p"; // Element name + final String TITLEGRP = "titlegrp"; // Element that holds all the titles + final String TDECL = "titledecl"; // Element name + final String TLIST = "titlelist"; // Element name + final String HEAD = "head"; // Element name + final String CONTROL = "controlinfo";// ELement name + final String SID = "sysid"; // Element name + final String RESPDECL = "respdecl"; // Element name + final String RESPSTM = "respStmt"; // Element name + final String RESP = "resp"; // Element name + final String PERSNAME = "persname"; // Element name + final String NAME = "name"; // Element name + final String DATE = "date"; // Element name + final String REVDESC = "revisiondesc";// Element name + final String TRANS = "Translator"; // Element content + final String TRANS_JOB = "Translated and Edited titles."; // Element content + final String CHANGE = "change"; // Element name + final String LIST = "list"; // Element name + final String ITEM = "item"; // Element name + final String TIDDECL = "tibiddecl"; // Element name + final String TID = "tibid"; // Element name + final String ALT = "altid"; // Element name + final String PHYSDEC = "physdecl"; // Element name + final String PAGIN = "pagination"; // Element name + final String AP = "app"; // Element name + final String LM = "lem"; // Element name + final String EXPAN = "expan"; // Element name + final String ABBR = "abbr"; // Element name + final String INTDECL = "intelldecl"; // Element name + final String DOX = "doxography"; // Element name + final String DOXTYPE = "Doxography"; // Attribute value for doxogrpahy name elements + final String CATEG = "category"; // Attribute value for Type of Doxography + final String RELAT = "relation"; // Attribute value for Type of Doxography + final String SRC = "source"; // Element name + final String SYS = "system"; // Attribute name + final String NUMB = "number"; // Attribute value on TIBID + final String TXTHEAD = "text header";// Attribute value for TITLE type + final String TITLELN = "title line"; // Attribute value for Title subtype + final String WIT = "wit"; // Attribute name + final String RDG = "rdg"; // Element name + final String TINFO = "titleinfo"; // Element name + final String TDIV = "titlediv"; // Element name + final String TITEM = "titleitem"; + final String DESIG = "designation"; + final String CORRESP = "corresp"; // Attribute name + final String FRONT = "front"; + final String BODY = "body"; + final String BACK = "back"; + final String NONTIB = "nontibet"; + final String ORIG_LANG = "Original language"; // Attribute value + final String TEXT_HEAD = "text header";// Attribute value for type of title + final String RS = "rs"; // Element name + final String DISC = "discussion"; // Element name + final String SUMMARY = "summary"; // Disc Element Type attribute + final String SECTIONS = "sections"; // Element name + final String TIBANAL = "tibanal"; // Element name + final String NUM = "num"; // Element name + final String VOL = "volume"; // Attribute value; + final String NOTE = "note"; // Element name + final String HI = "hi"; // Element name + final String CIT = "cit"; // Element name (changed to QUOTE) + final String QUOTE = "quote"; // Element name + final String REND = "rend"; // Attribute name; + final String INFO = "info"; // Attribute (rend) value; + final String CREATOR = "creator"; // attribute value in control info + final String CONTROL_SOURCE = "source"; // attribute value in control info + final String CRIT_ED_LABEL = "crited"; // Attribute value in control info + final String CRIT_ED_DESC = "Critical Editing"; // element text phrase for control info + + final String EDCONS = "Editions consulted"; // Rend value of Source for editions consulted. + final String MASTER_SIGLA = "Ng"; // Sigla for the Master edition + final String ATIYOGA = "a ti yo ga ";// Tibetan spelling + final String ANUYOGA = "a nu yo ga "; + final String MAHAYOGA = "ma h\u0101 yo ga "; + final String MISC = "Miscellaneous"; + final String UNCLASSED = "Unclassified"; + final String NOTFOUND = "not found"; // Attribute value for type on RDG elements + // The following three use partial strings that are unique but allow to do indexOf to ignore capitalization and punctuation. + final String NOT_SPEC = "specified"; // Contents of a title element when title missing. + final String NO_TITLE = "title given"; // Contents of a title element when none is given.1z + final String UNTITLED = "ntitled"; // Contents of untitled chapter. U not included to match all cases (Don't know why I didn't use equalsIgnoreCase()? Check it out!) + final String BRIEF = "Brief"; // Type attribute value for discussion, brief means no paragraphs. + final String FULL = "Full"; // Type attribute value for discussion, full means with paragraphs (changed value to long, more descriptive). + final String SIGLA_DELIM = " "; // delimits between sigla in a wit attribute + final String DATE_DELIM = "-"; + final String DOX_DELIM = "."; // delimits between dox numbers in ID + final String DOX_CAT_DELIM = ":"; // delimits between names of dox categories. + final org.jdom.Element NO_ELEM = new org.jdom.Element("null"); + // To take up a place in vector when there is no element associated with a string/style run in TextPanel + + // Constants for Edition Attributes + + final String ED_NAME = "EDITION_LETTER"; + final String ED_SIGLA = "EDITION_SIGLA"; + final String VOL_NUM = "VOLUME_NUMBER"; + final String VOL_LET = "TIB_LETTER"; + final String TEXT_NUM = "TEXT_NUMBER"; + final String VOL_TEXT = "VOL_TEXT_NUMBER"; + final String PAGE_RANGE = "PAGINATION"; + + final org.jdom.Attribute TYPE_ED = new org.jdom.Attribute(TYPE,ED); + final org.jdom.Attribute TYPE_VOL = new org.jdom.Attribute(TYPE,VOL); + final org.jdom.Attribute TYPE_TEXT = new org.jdom.Attribute(TYPE,TXT); + final org.jdom.Attribute TYPE_CLASS = new org.jdom.Attribute(TYPE,CLASS); + final org.jdom.Attribute SYS_LET = new org.jdom.Attribute(SYS,LET); + final org.jdom.Attribute SYS_SIG = new org.jdom.Attribute(SYS,SIG); + final org.jdom.Attribute SYS_NUM = new org.jdom.Attribute(SYS,NUM); + final org.jdom.Attribute LANG_TIB = new org.jdom.Attribute(LANG,TIB); + final org.jdom.Attribute LANG_ENG = new org.jdom.Attribute(LANG,ENG); + final org.jdom.Attribute CORRESP_NG = new org.jdom.Attribute(CORRESP,NG); + + final org.jdom.Attribute TYPE_DOX = new org.jdom.Attribute(TYPE,DOX); + + // Char Constants + final char BAD_PARA = ((char)(10)); // Para mark in data file is not understood. + final char SPACE = ' '; // A space to replace it with. + + // Messages + final String TTITLE_TITLE = "Java Title Translation Program"; + final String RUNTIME_ERROR = "A runtime error has occurred in "; + final String EDITOR_NAME_MESSAGE = "Please your initials for identification."; + final String EDITOR_NAME_TITLE = "Editor Identification"; + final String DATE_MESSAGE = "Is today's date: "; + final String DATE_TITLE = "Confirm Date"; + final String INPUT_DATE_MESSAGE = "Please enter the date (YYYY-MM-DD):"; + final String INPUT_DATE_TITLE = "Enter Today's Date"; + final String OPEN_TITLE = "Open XML Tibbibl Record"; + final String TEXT_LIST_HEAD = "List of Texts in Tb Volume "; + final String EX1 = "\"1"+DOX_DELIM + "3" +DOX_DELIM+"6\""; + final String EX2 = "\"sems sde " + DOX_CAT_DELIM + " sna tshogs\""; + + // JOptionPane Messages + final String JOP_ERROR = Integer.toString(JOptionPane.ERROR_MESSAGE); + final String JOP_INFO = Integer.toString(JOptionPane.INFORMATION_MESSAGE); + final String JOP_WARN = Integer.toString(JOptionPane.WARNING_MESSAGE); + final String JOP_QUEST = Integer.toString(JOptionPane.QUESTION_MESSAGE); + final String JOP_YESNOCANCEL = Integer.toString(JOptionPane.YES_NO_CANCEL_OPTION); + + final String[] OPEN_ERROR = {"Could not open the XML file:\n", + "Unable to open file!", + JOP_ERROR}; + final String[] DO_ALL_TITLES = {"Add this translation for all identical titles " + + "in this text?", + "Use Translation for Identical Titles?", + JOP_QUEST}; + final String[] ED_EXISTS_MESSAGE = {"The sigla you have entered has " + + "already been added to the list of sources.", + "Duplicate Sigla Error", + JOP_ERROR}; + + final String NEW_ED_INFO = "New Edition Information"; + final String ED_STRING = "Edition's name"; + final String ED_SIG = "Edition Sigla"; + final String ED_TEXT_NUM = "Edition Text Number"; + final String ED_VOL_NUM = "Edition Volume Number"; + final String ED_VOL_LET = "Edition Volume Letter"; + final String VOL_TEXT_NUM = "Text Number in Volume"; + final String FULL_TEXT_PAGE = "Full Pagination of Text"; + final String TITLE_PAGE = "New Title's Pagination"; + final String[] NEW_ED_INFO_SPECS = {ED_STRING,ED_SIG,ED_TEXT_NUM,ED_VOL_NUM, ED_VOL_LET, + VOL_TEXT_NUM, FULL_TEXT_PAGE, TITLE_PAGE}; + + final String NEW_ED_TITLE_INFO = "New Edition Title Information"; + final String[] NEW_ED_TITLE_INFO_SPECS = {ED_SIG,TITLE_PAGE}; + final String GET_DESIG = "Chapter Designation of Title Source"; + final String GET_DESIG_QUESTION = "Enter the chapter number for the source of this title: "; + final String[] GET_DESIG_SPECS = {GET_DESIG_QUESTION,GET_DESIG,JOP_QUEST}; + + final String TLIST_WARN_TITLE = "Insertion Not Allowed!"; + final String TLIST_WARN = "An edition title cannot be inserted into a list of End-of-Chapter titles." + + "\nUse Insert Title List under the insertion menu instead."; + final String[] TLIST_WARNING = {TLIST_WARN,TLIST_WARN_TITLE,JOP_WARN}; + + final String EDITORS_INFO = "Editor's Information"; + final String EDITORS_NAME = "Your name"; + final String EDITORS_INITIALS = "Your full initials"; + final String[] EDITORS_INFO_SPECS = {EDITORS_NAME,EDITORS_INITIALS}; + + final String NOT_SPEC_TITLE = "Not Specified Title"; + final String NOT_SPEC_MESSAGE = "The title you have chosen as the base for a critical title\n" + + "is \"Not specified.\" If you wish to enter a title from another source, \n"+ + "use 'Insert Edition Title' from the Insert Menu. Then, use that as the \n" + + "basis of a critical title and translation."; + final String[] NOT_SPEC_SPECS = {NOT_SPEC_MESSAGE,NOT_SPEC_TITLE,JOP_ERROR}; + + final String NO_TITLE_TITLE = "No Title Given"; + final String NO_TITLE_MESSAGE = "The title you have chosen as the base for a critical title\n" + + "informs us there was \"No title given.\" If you wish to enter a title from another source, \n"+ + "use 'Insert Edition Title' from the Insert Menu. Then, use that as the \n" + + "basis of a critical title and translation."; + final String[] NO_TITLE_SPECS = {NO_TITLE_MESSAGE,NO_TITLE_TITLE,JOP_ERROR}; + + final String NOT_SAVED_TITLE = "Not Saved!"; + final String NOT_SAVED_MESSAGE = "Do wish to save changes you have made to this file?"; + final String[] SAVE_SPECS = {NOT_SAVED_MESSAGE,NOT_SAVED_TITLE,JOP_YESNOCANCEL}; + + final String INV_TRANS_TITLE = "Cannot Edit Translation"; + final String INV_TRANS = "The cursor is not placed in a valid title or translation for editing.\n" + + "The cursor must be positioned in a master version of a title (Ng) or in\n" + + "its translation for the Edit Translation option."; + final String[] INVALID_TRANS_SPECS = {INV_TRANS,INV_TRANS_TITLE,JOP_ERROR}; + + final String RENAME_FILE_TITLE = "Tibbibl File Renamed!"; + final String RENAME_FILE = "The Tibbibl file has been renamed to match the change in its Master ID. \n" + + "The new file name is: "; + final String[] RENAMING_FILE_SPECS = {RENAME_FILE,RENAME_FILE_TITLE,JOP_INFO}; + + final String SAVED_FILE_TITLE = "Tibbibl File Saved!"; + final String SAVED_FILE = "The Tibbibl file has been saved under a name that matches its Master ID. \n" + + "The file name is: "; + final String[] SAVED_FILE_SPECS = {SAVED_FILE,SAVED_FILE_TITLE,JOP_INFO}; + + final String FILE_EXISTS_TITLE = "File Already Exists!"; + final String FILE_EXISTS = "The file name generated for this text already exists.\n" + + "Do you wish to replace the existing file?\n" + + "(If you choose, 'no' another name will be automatically generated for this text.)\n"+ + "File name: "; + final String[] FILE_EXISTS_SPECS = {FILE_EXISTS,FILE_EXISTS_TITLE,JOP_YESNOCANCEL}; + + final String ED_EXISTS_TITLE = "Rewrite Edition Info?"; + final String ED_EXISTS = "The edition you entered is already found in this texts identification information.\n" + + "Do you wish to replace this information?"; + final String[] ED_EXISTS_SPECS = {ED_EXISTS,ED_EXISTS_TITLE,JOP_YESNOCANCEL}; + + final String REMOVE_APP_TITLE = "Remove Variants at Cursor?"; + final String REMOVE_APP_MESS = "Do you want to remove the variant readings at the cursor position?\n" + + "They will be replaced by the main reading now showing."; + final String[] REMOVE_APP_SPECS = {REMOVE_APP_MESS,REMOVE_APP_TITLE,JOP_YESNOCANCEL}; + + final String NO_SELECT_TITLE = "No Text Selected for Variant Readings"; + final String NO_SELECTION = "You have not selected any text. You must select a range of text \n"+ + "to which the variant readings will apply."; + final String[] NO_SELECTION_SPECS = {NO_SELECTION,NO_SELECT_TITLE,JOP_ERROR}; + + final String CREATE_FILE_LIST_TITLE = "No File List!"; + final String CREATE_FILE_LIST = "No file list has been created.\nWould you like to build the file list?\n" + + "This may take some time..."; + final String[] CREATE_FILE_LIST_SPECS = {CREATE_FILE_LIST,CREATE_FILE_LIST_TITLE,JOP_YESNOCANCEL}; + + final String REMOVE_ED_TITLE_TITLE = "Remove Added Title?"; + final String REMOVE_ED_TITLE_MESS = "Do you wish to remove this title which you have added?"; + final String[] REMOVE_ED_TITLE_SPECS = {REMOVE_ED_TITLE_MESS,REMOVE_ED_TITLE_TITLE,JOP_YESNOCANCEL}; + + final String REMOVE_ED_ERROR_TITLE = "Cannot Remove Title!"; + final String REMOVE_ED_ERROR_MESS = "The title selected was not entered by you and so cannot be removed by you."; + final String[] REMOVE_ED_TITLE_ERROR = {REMOVE_ED_ERROR_MESS,REMOVE_ED_ERROR_TITLE,JOP_INFO}; + + final String DEL_EDS_TITLE = "Delete Inserted Edition!"; + final String DEL_EDS_MESS = "In the table below, double click on the row\nfor the edition you wish to remove.\n" + + "(You can only remove editions that you have added.)"; + + final String TLIST_ADD_TITLE = "Cannot Add Edition Title"; + final String TLIST_ADD_MESS = "A new edition title cannot be added to end of chapter titles.\n" + + "You can still create a master version of this title and provide alternate readings\n" + + "By double clicking on the existing title and using the \"Insert Variant Reading\" option."; + final String[] TLIST_ADD_ERROR = {TLIST_ADD_MESS,TLIST_ADD_TITLE,JOP_ERROR}; + + final String NORM_AP_TITLE = "Cannot Add Reading to Normalized Title"; + final String NORM_AP_MESS = "You cannot add a reading to the normalized title.\n" + + "The normalized title is an assigned normative title not necessarily\n" + + "Found in the text itself. Thus, variant readings cannot be added to it."; + final String[] NORM_AP_ERROR = {NORM_AP_MESS,NORM_AP_TITLE,JOP_ERROR}; + + final String ED_ID_TITLE = "Editor's Identification Information Required!"; + final String ED_ID_MESS = "This program cannot function properly unless the user properly identifies him or herself.\n" + + "Please enter your full name and your 2 or 3-letter editor initials/ID in the following window.\n" + + "(To quit the program without entering your information, press cancel in the next window.)"; + final String[] ED_ID_REQUIRED = {ED_ID_MESS,ED_ID_TITLE,JOP_ERROR}; +} diff --git a/source/org/thdl/tib/bibl/TibDTDResolver.java b/source/org/thdl/tib/bibl/TibDTDResolver.java new file mode 100644 index 0000000..5ebbec9 --- /dev/null +++ b/source/org/thdl/tib/bibl/TibDTDResolver.java @@ -0,0 +1,40 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + + import org.xml.sax.EntityResolver; + import org.xml.sax.InputSource; + + public class TibDTDResolver implements EntityResolver, TibConstants { + public InputSource resolveEntity (String publicId, String systemId) + { + if (systemId.indexOf("dtd")>-1) { + // return a special input source + + int lastSlash = systemId.lastIndexOf("/"); + String fname = "file:/" + DEFAULT_DIRECTORY + BIN + systemId.substring(lastSlash+1); + fname = fname.replace('\\','/'); + InputSource inSrc = new InputSource(fname); + return inSrc; + } else { + // use the default behaviour + return null; + } + } + } diff --git a/source/org/thdl/tib/bibl/TibDialog.java b/source/org/thdl/tib/bibl/TibDialog.java new file mode 100644 index 0000000..bf82ca9 --- /dev/null +++ b/source/org/thdl/tib/bibl/TibDialog.java @@ -0,0 +1,205 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import javax.swing.*; +import javax.swing.event.*; + + +/** +*

+* This class is a generic class for displaying a dialog in TiblEdit. I'm not sure if it is actually used in +* TiblEdit. It may be a relic. CHECK! +*

+* +*/ + +public class TibDialog extends JDialog implements ActionListener, TibConstants +{ + // Attributes + TiblEdit controller; + TibFrame frame; + String[] specs; + String response; + int num; + Hashtable results; + JLabel[] jl; + JTextField[] jtf; + String type; + boolean isStartUp = false; + + transient protected String value; + public static final String RESPONSE_PROPERTY = "response"; + public static final String NEW_ED = "new edition"; + + private void init() + { + GridLayout gl = new GridLayout(0,2); + gl.setHgap(5); + gl.setVgap(5); + JPanel cpane = new JPanel(gl); + jl = new JLabel[num]; + jtf = new JTextField[num]; + for(int n=0; n -1 && index < jtf.length) { + return jtf[index]; + } + return null; + } + + public void clearTextFields() { + for(int n=0; n + * This class extends {@link XMLDoc} and adds methods specific to the {@link TiblEdit} + * program, primarily by creating a {@link TitleFactory} and an {@link IDFactory} that allow + * easy access and manipulation of those marked up items. It also contains methods for creating + * new apparatus or variant reading mark up and entering in translations within Foreign elements + * contained inside the associated Title element that contains as its text the transliteration + * of the Tibetan title. + *

+ */ + +public class TibDoc extends XMLDoc +{ + // Attributes + /** + *

+ * Generic variables for headers, parents, elements/self, and children. + *

+ */ + private org.jdom.Element head, parent, element, child; + + /** + *

+ * The {@link TitleFactory} associated with this Tibbibl XML document. + *

+ */ + private TitleFactory tf; + /** + *

+ * The {@link IDFactory} associated with this Tibbibl XML document + *

+ */ + private IDFactory idf; + + + // Accessory + /** + *

+ * This method sets the first head element or the text header by searching for the first head element. + *

+ */ + protected void setHead() + { + head = findElement(HEAD); + } + + /** + *

+ * This returns the text's main head element that contains the text header. + *

+ * + * @return org.jdom.Element - the head element that contains the text's header. + */ + public org.jdom.Element getHead() + { + return head; + } + + /** + *

+ * This method sets the {@link #idf IDFactory variable} and the {@link #tf TitleFactory variable} + * for this Tibbibl XML document. + *

+ */ + public void setFactories() + { + tf = new TitleFactory(this); + idf = new IDFactory(this); + } + + /** + *

+ * Returns the {@link TitleFactory} created for this document that allows easy access to and + * manipulation of titles. + *

+ * + * @return TitleFactory - The title factory for this Tibbibl XML document. + */ + public TitleFactory getTitleFactory() + { + return tf; + } + + /** + *

+ * Returns the {@link IDFactory} created for this document that allows easy access to and + * manipulation of ID information, that is the Tibids contained within the text's TibidDecl. + *

+ * + * @return IDFactory - The ID factory for this Tibbibl XML document. + */ + public IDFactory getIDFactory() + { + return idf; + } + + // Helper methods + + /** + *

+ * This method sets the information for the current user (=editor) of the program who is + * entering in translations and adding critical titles to the text. This information is added + * in the ControlInfo metadata section of the Tibbibl document. A Resp/Name pair is added with the + * Name element containing the full name and having an ID of the initials, and a Name element is + * added to the Source list, that has an ID of "Ng" and whose corresp attribute is set to the initials. + * Thus, all uses of the corresp="Ng" are linked to the tag under the list of sources with corresp = to + * the editor's initials and content of the full name. This in turn is linked to the Resp that contains + * the editor's full name and his/her responsibility regarding the document. + *

+ * + * @param String - the editor's (preferrably) three initials, such as snw or dfg. + * @param String - the editor's full name to be recorded in the metadata. + * @param String - the present date. + */ + public void addEditor(String initials, String fullName, String today) + { + initials = initials.trim(); + fullName = fullName.trim(); + setEditorInfo(initials,fullName); + org.jdom.Element parent = findElement(CONTROL); + java.util.List children = parent.getChildren(RESPSTM); + Iterator it = children.iterator(); + int listIndex = -1; + org.jdom.Element respstm, contrlSrc; + contrlSrc = null; + boolean found = false; + + while(it.hasNext()) { + // find the RespStmts in the control info section + respstm = (org.jdom.Element)it.next(); + String nValue = respstm.getAttributeValue(N); + if(nValue == null) {continue;} + if(nValue.equals(CONTROL_SOURCE)) { + // if need to modify the sources + contrlSrc = respstm; + } else if(nValue.equals(CRIT_ED_LABEL)) { + // of if it's already there + found = true; + } + } + + if(!found) { + org.jdom.Element resp, name, date; + respstm = new org.jdom.Element(RESPSTM); + respstm.setAttribute(N,CRIT_ED_LABEL); + resp = new org.jdom.Element(RESP); + resp.setText(CRIT_ED_DESC); + respstm.addContent(resp); + name = new org.jdom.Element(NAME); + name.setText(fullName); + name.setAttribute(ID,initials); + resp.addContent(name); + date = new org.jdom.Element(DATE); + date.setText(today); + resp.addContent(date); + parent.addContent(respstm); + + name = new org.jdom.Element(NAME); + name.setAttribute(ID,NG); + name.setAttribute(CORRESP,initials); + name.setText(fullName); + contrlSrc.addContent(name); + + } else { + System.out.println(" Need to deal with 2nd time use.\n"+ + "Check to see if same editor & same date.\n" + + "Create new editor or date-range."); + } + + } + + /** + *

+ * This method returns an array of strings that contains 1. the opening string of the header, such as + * "Bibliographic Record for", and 2. the text contain within each of its children elements, usually + * there are two of these a lang="tib" and a lang="eng", each one entered separately. The strings + * are stripped of extraneous paragraph markers and spaces using the {@link #cleanString} method. + * If it's an English title then it is enclosed in parentheses. + *

+ * + * @return String[] an array containing the different strings that are the parts + * of this header element. They are kept separate so that different styles can be + * applied to the opening text (bold) and the title contents (bold-italic). + */ + public String[] getHeadStrings() + { + Vector strs = new Vector(); + Iterator children = head.getContent().iterator(); + while(children.hasNext()) { + Object child = children.next(); + + if(child instanceof org.jdom.Text) + { + String t = ((org.jdom.Text)child).getText(); + + if(t != null) + { + t = cleanString(t); + if(t.length()>0 && !t.equals(" ")) strs.add(t); + } + + } else if(child instanceof org.jdom.Element) + { + org.jdom.Element e = (org.jdom.Element)child; + if(e.getAttributeValue(LANG).equalsIgnoreCase(ENG)) { + strs.add("(" + cleanString(e.getText()) + ")"); + } else { + strs.add(cleanString(e.getText())); + } + } + } + return TiblEdit.toStringArray(strs); + } + + /** + *

+ * This method returns a string array of the sources used in creating this master document. + * These sources (for now -- this may change) are included within the controlInfo metadata for the + * text in a respStmt with n="source". It contains a Resp element with Source Records as the label and then + * a series of Name elements with their ID attribute set to their sigla and their content set to the full + * name of the source xml document (no path name). In the case of the master editor, the ID is set to Ng and + * the corresp attribute is set to the editor's initials. This serves to connect all the various pieces of information to + * a particular source by using their corresp attribute. The corresp attribute is an IDREF, which means its + * value must match the value for another element's ID. Thus, all uses of the corresp="Tk" not only identify + * the piece of information as belonging to the gTing skyes edition but also link each use with the name + * of the actual source file or the Tk Tibbibl record. In the case of the editor, their is a double IDREF + * occuring. Each use of the Ng sigla refers to the Name element in the sources that has the ID "Ng" and + * the corresp = to the editor's initials. This refers to the Resp element above that has an ID of the editor's + * intials and contains his or her full name. + *

+ */ + public String[] getSources() + { + org.jdom.Element respSt = findElement(RESPSTM,N,"source"); + Iterator children = respSt.getChildren().iterator(); + Vector sources = new Vector(); + while(children.hasNext()) + { + org.jdom.Element child = (org.jdom.Element)children.next(); + if(child.getName().equals(NAME)) + { + String childText = child.getText(); + int xmlind = childText.indexOf(".bib.xml"); + if(xmlind > -1) { + sources.add(childText.substring(0,xmlind)); + } else { + sources.add(childText); + } + } + } + return TiblEdit.toStringArray(sources); + } + + /** + *

+ * This creates a critical version of any title within a TitleDecl by adding a title element + * as its first child with a Corresp=Ng. It does this by cloning one of the existing title elements + * to get one with identical attribute values but changes the corresp attribute to Ng. It adds + * a Foreign element with Lang = "eng as part of this title's content for the translation. It + * also "cleans" the title of an Expan element, which were used to add editor's interpretations of + * standard abbreviations such as thaMd for thams cad. These are replaced with the original abbreviated form. + * Finally, it adds a Num element within the pagination that has an ID = Ng and contains the initals of the + * editor who is the source of this critical title. + *

+ * + * @param org.jdom.Element - the Title element that is to serve as the basis of the critical title. This is + * the element that is cloned to create the critical version. + * + * @param initials - the initials of the editor creating the critical title. + */ + public org.jdom.Element createCriticalTitle(org.jdom.Element el, String initials) + { + + org.jdom.Element app, contItem; + Object item; + parent = el.getParent(); // the tdecl + child =((org.jdom.Element)el.clone()).detach(); + String base = child.getAttributeValue(CORRESP); + if(base == null) { + base = findTitleListEd(parent); + el.setAttribute(CORRESP,base); + } + + child.setAttribute(CORRESP,NG); + child.setAttribute(TYPE,base); + if(child.getChild(FOREIGN) == null) { + child.addContent(new org.jdom.Element(FOREIGN)); + } + java.util.List children = child.getContent(); + Iterator it = children.iterator(); + contItem = null; + app = null; + while(it.hasNext()) { + item = it.next(); + if(item instanceof org.jdom.Element) { + contItem = (org.jdom.Element)item; + if(contItem.getName().equals(EXPAN)) { + String resp = contItem.getAttributeValue(RESP); + String abbr = contItem.getAttributeValue(ABBR); + if(resp == null) { resp = new String();} + String expanText = contItem.getText(); + app = newApp(resp,expanText); + app.getChild(RDG).setAttribute(WIT,base); + app.getChild(RDG).setText(abbr); + break; + } + } + } + if(contItem != null && app != null) { + children.set(children.indexOf(contItem),app); + } + if(parent != null) { + parent.getChildren().add(0,child); + } + + org.jdom.Element grandparent = parent.getParent(); + org.jdom.Element pagination = grandparent.getChild(PAGIN); // the normal way for a titleDiv other than titlelists + + if(pagination == null) { + if(grandparent.getName().equals(TIBL)) // then it's a chapter + { + pagination = parent.getChild(SRC); + } + } + + if(pagination != null) { + org.jdom.Element newSource = new org.jdom.Element(NUM); + newSource.setAttribute(CORRESP,NG); + newSource.setText(initials); + pagination.getContent().add(0,newSource); + } else { + System.out.println("No pagination element found in creating critical title of " + TiblEdit.outputString(parent)); + } + + return child; + } + + + /** + *

+ * This method sets the master doxogrpahy elements within the IntellDecl section of the Tibbibl. + * It takes two strings the Tibetan doxographical statement the English version of that. These + * list the categories separated by colons and are supplied by the {@link DoxWindow}. The master + * doxography element with type = "category" and n = "0" is located or else inserted and its + * text is set to the Tibetan doxographical statement and a Foreign element is included within that + * containing the English translation of it. + *

+ * + * @param String - the Tibetan doxographical statement + * + * @param String - the English doxographical statement. + */ + public void setDoxography(String tibDox, String engDox) + { + org.jdom.Element masterDox, edDox; + masterDox = null; + edDox = null; + org.jdom.Element[] doxs = findElements(DOX); + for(int n=0;n + * This method takes a string ID where the subcategories are delimited by a period (".") and + * invokes the Tibbibl's {@link IDFactory#setMasterID(String)} method to parse the ID and create + * the nested Tibid mark-up. + *

+ * + * @param String - the new ID string delimited by periods. + */ + public void setMasterID(String idString) + { + idf.setMasterID(idString); + } + + /** + *

+ * This method returns the normalized title of the text using the tibbibl's {@link TitleFactory}. + *

+ * + * @return String - the normalized title of this text. + */ + public String getNormalizedTitle() + { + // the title factory returns the title element, not the text.. + element = tf.getNormalizedTitle(); + if(element == null) {return new String();} + return cleanString(element.getText()); + } + + /** + *

+ * This method takes a titledecl from a title list and finds the edition listed in the first titleitem element. + * Because the same version of a title could span many chapters in different editions, the Corresp attribute is + * not set for the title itself in a title list but is set on the individual titleItems. This method finds the first + * title item and returns the sigla contained in its corresp element so this can be assigned as the type attribute + * of the critical version of the title. (The type attribute of a critical title indicates its original source title.) + * + *

+ * + * @param org.jdom.Element - the title list's titledecl. + * + * @return String - the sigla of the edition that is the source for the title, derrived from the first titleitem element. + */ + public String findTitleListEd(org.jdom.Element tdecl) + { + org.jdom.Element tlist,titem; + String edSig; + tlist = tdecl.getParent(); + if(!tlist.getName().equals(TLIST)) {return null;} + titem = tlist.getChild(TITEM); + edSig = titem.getAttributeValue(CORRESP); + return edSig; + } + + /** + *

+ * This method takes a text string and a title element and uses it to insert an + * English translation for a title, by adding a Foreign element to the title element, setting + * its Lang=eng, and putting the text in its content. + *

+ * + * @param String - the text of the translation + * @param org.jdom.Element - the Title element (lang=tib) that contains the title being translated. + */ + public void addTranslation(String text, org.jdom.Element el) + { + if(el == null || el.getName().equals(NO_ELEM)) {return;} + org.jdom.Element foreign = el.getChild(FOREIGN); + if(foreign == null) { + System.out.println("Foreign is null: \n" + TiblEdit.outputString(el)); + foreign = new org.jdom.Element(FOREIGN); + foreign.setAttribute((org.jdom.Attribute)LANG_ENG.clone()); + el.addContent(foreign); + } + foreign.setText(text); + } + + /** + *

+ * This method takes a Title element, a sigla, and a pagination and creates a new + * edition title within a particular TitleDecl. The element is one of the future siblings of the + * new edition title and is cloned to create one with identical attributes. The corresp value of the + * clone is then changed to the new sigla, children and text are removed, and the element is added + * to the active list of the TitleDecl's children. The pagination is located and a corresponding + * Num element is added with the corresp=sigla set and the text set to the given pagination. The + * resulting title element is then returned. + * + * THIS IS A TEMPORARY ADHOC FIX SO EDITORS CAN DEAL WITH EOC TITLES JUST LIKE OTHER TITLES + * One exception is if the new edition title is an EOC title + * to be added to a title list. In this case, the title is added to the titledecl as usual, but the + * pagination is included in a separate titleItem with a blank designation. This is a questionable practice + * because the notion of critically editing EOC titles is a contradition. The way we mark up EOC titles + * they are by nature variants, differences between them are catalogued by creating a new TitleList. But + * some of the title lists could be collapsed by considering them as variants on a critical title... + * The approach for this needs to be contemplated and fixed. Until then, they are treated like all other + * titles, and new edition titles added record their pagination in a separate title item element. + * + *

+ * + * @param org.jdom.Element - the title element to be cloned. + * @param String - the sigla of the new title element. + * @param String - the pagination of the new title. + * + * @return org.jdom.Element - the new edition title with corresp=sigla that is a sibling of the originally given title element. + */ + public org.jdom.Element addTitle(org.jdom.Element elem, String sigla, String pagination) + { + org.jdom.Element parent, grandparent, pagin, returnElem; + parent = elem; + if(elem.getName().equals(TITLE)) { + parent = elem.getParent(); + } else { + elem = parent.getChild(TITLE); + } + java.util.List children = parent.getChildren(TITLE); + java.util.List allChildren = parent.getChildren(); + elem = ((org.jdom.Element)elem.clone()).detach(); + elem.setAttribute(CORRESP,sigla); + elem.removeAttribute(TYPE); + elem.removeChildren(); + elem.setText(" "); + int tIndex = (children.size()>0?allChildren.indexOf(children.get(children.size()-1)):allChildren.size()-1); + allChildren.add(tIndex+1,elem); + returnElem = elem; + + grandparent = parent.getParent(); + if(grandparent != null) + { + if(grandparent.getName().equals(TDIV)) { // either its a title div + + pagin = grandparent.getChild(PAGIN); + if(pagin == null) { + System.out.println("Can't find pagination while inserting title element for:\n" + + TiblEdit.outputString(grandparent) +"\n Adding directly to this element"); + pagin = grandparent; + } else { + elem = new org.jdom.Element(NUM); + elem.setAttribute(CORRESP,sigla); + elem.setText(pagination); + pagin.addContent(elem); + } + + } else if(grandparent.getName().equals(TLIST)) { // or a title list + + parent = new org.jdom.Element(TITEM); + parent.setAttribute(CORRESP,sigla); + child = new org.jdom.Element(DESIG); + String[] specs = {"Which chapter in the " + sigla + " edition of the text is the source for this title?", + "Enter Chapter Number",JOP_INFO}; + String sectionNum = TiblEdit.promptInput(specs); + child.setText(sectionNum); + parent.addContent(child); + child = new org.jdom.Element(PAGIN); + child.setText(pagination); + parent.addContent(child); + grandparent.addContent(parent); + + } else if(grandparent.getName().equals(TIBL)) { // or else it's a chapter TIBBIBL + + children = parent.getChildren(); + pagin = parent.getChild(SRC); + int srcIndex = children.indexOf(pagin); + if(srcIndex > -1) { + parent.removeContent(elem); + parent.getChildren().add(srcIndex,elem); + } else { + System.out.println("Could not find source in chapter title decl: " + TiblEdit.outputString(parent)); + pagin = new org.jdom.Element(SRC); + parent.addContent(pagin); + } + child = new org.jdom.Element(NUM); + child.setAttribute(CORRESP,sigla); + child.setText(pagination); + pagin.addContent(child); + } + } + return returnElem; + } + + /** + *

+ * This returns the text of a title element as it is displayed in the {@link TextPane}. It gets this in the + * same way the text pane does by using a {@link TitleParser} that finds the constituent parts of a title and + * determines which are to be displayed. For instance, if there is an app element, it displays only the text of + * the Lem child (i.e., the main reading). + *

+ * + * @param org.jdom.Element - the title whose text is desired. + * + * @return String - the display text for that title element. + */ + public String getTitleText(org.jdom.Element title) + { + TitleParser tparse = new TitleParser(title); + return tparse.getTitleText(); + } + + /** + *

+ * This method takes a title element, a string of selected text, and an integer indicating the offset from + * the start of the text's title where the apparatus element is to be inserted. It then uses a + * {@link TitleParser} to figure out the display text of the title, and with the offset integer determines + * where in the title the apparatus element is to be inserted. It receives that part from the TitleParser, splits it, + * and adds the app element. If all succeeds, the app element is then returned. + *

+ * + * @param org.jdom.Element - the title in which the app is to be inserted. + * @param String - the text selected in the {@link TextPane} that indicates where the app is to be inserted. + * @param int - the offset from the beginning of the text's display title, where the insertion point is. + * + * @return org.jdom.Element - the app element that has been successfully inserted or null if unsuccessfull. + */ + public org.jdom.Element insertApp(org.jdom.Element title, String selText, int offset) + { + // if title does not have corresp == to NG then return + // can only add aps to critical versions of the title + if(!title.getAttributeValue(CORRESP).equals(NG)) { + System.out.println("The Title's corresp attribute does not equal Ng!\n" + + TiblEdit.outputString(title)); + return null; + } + + TitleParser tparser = new TitleParser(title); + if(tparser.isAppInsertable(offset, selText)) + { +System.out.println("selected text is: " + selText); + java.util.List children = title.getContent(); + Vector newContents = new Vector(); + Object child = tparser.getItemAt(offset); + String text = tparser.getTextAt(offset); +System.out.println("TExt at title offset is: " + text); + int index = text.indexOf(selText); + + String sigla = title.getAttributeValue(TYPE); + if(sigla == null) { sigla = title.getAttributeValue(CORRESP);} + if(sigla == null) { sigla = NG;} + + if(child != null && index > -1 && (index + selText.length())<=text.length()) { + int childIndex = children.indexOf(child); + if(childIndex > -1) { + newContents.add(new org.jdom.Text(text.substring(0,index-1)+" ")); + org.jdom.Element app = newApp(sigla,selText); + newContents.add(app); + newContents.add(new org.jdom.Text(text.substring(index+selText.length()))); + children.remove(child); + children.addAll(childIndex,newContents); + return app; + } else { + System.out.println("Couldn't locate child in content list of element!"); + System.out.println("Title: " + TiblEdit.outputString(title)); + System.out.println("Child: " + child.toString()); + } + + } else { + System.out.println("Could not split up text run properly! in Tib Doc insertApp! Or child was null"); + System.out.println("Title: " + TiblEdit.outputString(title)); + System.out.println("Text run: " + text); + System.out.println("Sel text: " + selText); + System.out.println("Index of: " + index); + System.out.println("Child: " + child); + } + } else { + System.out.println("Tparser rejected insert App!"); + } + + return null; + } + + /** + *

+ * This method removes an existing App element, replacing it with the text of its lemma or main reading child. + *

+ * + * @param org.jdom.Element - the app to be removed. + */ + public void removeApp(org.jdom.Element appToRemove) + { + parent = appToRemove.getParent(); + if(parent == null) {return;} + int index = parent.getContent().indexOf(appToRemove); + element = appToRemove.getChild(LM); + String text = new String(" "); + if(element != null) {text = element.getText();} + System.out.println("Replacing app with " + text); + parent.getContent().set(index,new org.jdom.Text(text)); + } + + /** + *

+ * This method is called when the Normalized title and/or translation is changed. It locates the text's + * main Head element, which contains the text's header with its title, and changes the content of the + * two title elements (tib and eng) in the header to accurately reflect the modified normalized title + * and translation. + *

+ */ + public void updateTextHeader() + { + org.jdom.Element head, normTitle, foreign; + org.jdom.Element[] heads; + + normTitle = tf.getNormalizedTitle(); + foreign = normTitle.getChild(FOREIGN); + heads = tf.getHeaderTitles(); + if(heads != null) { + heads[0].setText(normTitle.getText()); + if(heads.length>1) { + heads[1].setText(foreign.getText()); + } else { + element = new org.jdom.Element(TITLE); + element.setAttribute(TYPE,TEXT_HEAD); + element.setAttribute(LANG,ENG); + element.setText(foreign.getText()); + heads[1].getParent().addContent(element); + } + } else { + head = findElement(HEAD); + element = new org.jdom.Element(TITLE); + element.setAttribute(TYPE,TEXT_HEAD); + element.setAttribute(LANG,TIB); + element.setText(normTitle.getText()); + head.addContent(element); + element = new org.jdom.Element(TITLE); + element.setAttribute(TYPE,TEXT_HEAD); + element.setAttribute(LANG,ENG); + element.setText(foreign.getText()); + head.addContent(element); + } + + } + + // Static Methods + + /** + *

+ * This static method is used to clean up an string derrived from XML content that may have paragraph returns + * in the middle of it and preceding or trailing spaces, etc. It replaces all the "\n" with spaces and then + * reduces all double spaces to single spaces as well as trimming the string of preceding or following spaces. If null, + * is sent to this method, it returns an empty String. + *

+ * + * @param String - the text to be cleaned. + * + * @return String - the clean text. + */ + public static String cleanString(String text) + { + if(text != null) { + text = text.replace('\n',' '); + StringTokenizer parts = new StringTokenizer(text," "); + text = new String(); + while(parts.hasMoreTokens()) { + String word = parts.nextToken(); + if(word != null && !word.equals(" ")) { + text += word; + if(parts.hasMoreTokens()) { text += " "; } + } + } + } else { + text = ""; + } + return text; + } + + /** + *

+ * This static method is used to convert standard lists, such as Vectors, into arrays of org.jdom.Elements. This + * is useful because the getContent method of Element returns a List and in iteration each item must be cast + * back to an Element. This method returns a fixed array of Elements that do not require such casting. + *

+ * + * @param java.util.List - the list of content or children of an element. + * + * @return org.jdom.Element[] - the array of element children derrived from the list. + */ + public static org.jdom.Element[] toElementArray(java.util.List childs) + { + Object[] objs = childs.toArray(); + org.jdom.Element[] out = new org.jdom.Element[objs.length]; + for(int n=0; n +* This generic static method simply creates an unattached version of an app element with the main reading set. +* It takes to parameters: the sigla of the main reading (lemma), and the text of the lemma. It returns an app +* element with the first child being this lem element and one empty rdg (reading) element for non-main-readings. +*

+* +* @param String - the sigla of the lemma's witness. +* @param String - the text of the lemma's reading. +* +* @return org.jdom.Element - the app element created. +*/ + public static org.jdom.Element newApp(String mainWit, String lemma) + { + org.jdom.Element app, lem, rdg; + app = new org.jdom.Element(AP); + lem = new org.jdom.Element(LM); + rdg = new org.jdom.Element(RDG); + lem.setAttribute(WIT,mainWit); + lem.setText(lemma); + app.addContent(lem); + app.addContent(rdg); + return app; + } + + public static org.jdom.Element makeDiscussion(DiscDialog dd, String inits) + { + org.jdom.Element disc = dd.getDiscussion(inits); + disc.setAttribute(TYPE,dd.getDiscussionType()); + disc.setAttribute(RESP,inits); + return disc; + } + + + public org.jdom.Element makeHI(String rend) + { + org.jdom.Element hi = new Element(HI); + return hi.setAttribute(REND,rend); + } + + // Constructor + +/** +*

+* TibDoc has a single constructor that takes a root element for the document. +*

+* +* @param org.jdom.Element - the new TibDoc's root element. +*/ + public TibDoc(org.jdom.Element rootElement) + { + super(rootElement); + setHead(); + setFactories(); + setDocType(new DocType(TIBL,"..\\bin\\xtibbibl2.dtd")); + org.jdom.Attribute idAt = getRootElement().getAttribute(ID); + if(idAt != null && (idAt.getValue() == null || idAt.getValue().equals(""))) { + idAt.detach(); + } + } +} diff --git a/source/org/thdl/tib/bibl/TibFrame.java b/source/org/thdl/tib/bibl/TibFrame.java new file mode 100644 index 0000000..0ac7412 --- /dev/null +++ b/source/org/thdl/tib/bibl/TibFrame.java @@ -0,0 +1,876 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.Event; +import java.awt.event.*; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Toolkit; +import java.io.File; +import java.util.Vector; +import java.util.Iterator; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.event.*; + + /** + *

+ * TibFrame is the view for the {@link TiblEdit} program. TiblEdit is the controller. + * {@link TibDoc}, or {@link TiblEdit#tibbibl} in its instantiation, is the data model. + * TibFrame mainly utilizes a {@link TextPane} (an extension of JTextPane) as its main + * view window, but also allows split screens with a {@link DiacriticPanel} on the left and/or + * a {@link TibTable} at the bottom. + *

+ */ + +public class TibFrame extends JFrame implements CaretListener, TibConstants +{ + // Attributes + private TiblEdit controller; + + // Frame Attributes + private JMenu fileMenu, editMenu, insertMenu, provMenu, viewMenu; + // File Menu items + private JMenuItem openItem, closeItem, saveItem, saveAsItem, exportItem, exitItem; + + // Edit Menu items + protected JMenuItem cutItem, copyItem, pasteItem, editTransItem, editNormItem, + removeAppItem, removeTitleItem, removeEditionItem; + + // Insert menu items + private JMenuItem critTitleItem, edTitleItem, variantItem, insertEdItem, insertDiscItem; + + // View Menu items + private JCheckBoxMenuItem diacItem, edConsultItem; + private JMenuItem masterIDItem, userIDItem, aboutItem; + private JMenuItem[] recentFileItems; + //private JMenuItem authorItem, audienceItem, redactorItem, translatorItem, concealerItem, revealerItem; + + private JPanel contentPanel; + private JComponent rightSp, leftSp, bottomSp, topSp; + private JSplitPane horizontalSplit, verticalSplit; + private TextPane tp; + private DiacriticPanel dp; + private TibTable tibTable; + Vector styleElements; + + // Initialization + /** + *

+ * This is the initialization method for the TibFrame. The TibFrame is the view for + * this program, for which a {@link TiblEdit} object is the controller and + * a {@link TibDoc} is the data model. This method establishes a file menu, + * an edit menu, an view menu, and an insert menu. Its content pane is set to a + * JScrollPane with a {@link TextPane} as its view. + *

+ */ + protected void init() + { + Toolkit xKit = getToolkit(); + Dimension wndSize = xKit.getScreenSize(); + setBounds(wndSize.width/16, wndSize.height/16, + 7*wndSize.width/8, 7*wndSize.height/8); + addWindowListener(new XWindowHandler()); + addComponentListener(new XComponentHandler()); + + // TextPane content pane + tp = new TextPane(controller); + EditorKit ekit = tp.getEditorKit(); + Action[] actions = ekit.getActions(); + + // MenuBar + JMenuBar menuBar = new JMenuBar(); + setJMenuBar(menuBar); + + // File Menu + fileMenu = new JMenu(FILE); + openItem = fileMenu.add(new FileAction(OPENFILE,this)); + openItem.setAccelerator(KeyStroke.getKeyStroke('O',Event.CTRL_MASK)); + openItem.setFont(MENU_FONT); + openItem.setEnabled(true); + + closeItem = fileMenu.add(new FileAction(CLOSEFILE,this)); + closeItem.setAccelerator(KeyStroke.getKeyStroke('W',Event.CTRL_MASK)); + closeItem.setFont(MENU_FONT); + closeItem.setEnabled(false); + + saveItem = fileMenu.add(new FileAction(SAVE,this)); + saveItem.setAccelerator(KeyStroke.getKeyStroke('S',Event.CTRL_MASK)); + saveItem.setFont(MENU_FONT); + saveItem.setEnabled(false); + + fileMenu.addSeparator(); + + recentFileItems = new JMenuItem[RECENT_FILE_SIZE]; + for(int n=0;n + * This sets the {@link #controller} variable to the controller which is the + * instantiation of the main {@link TiblEdit} program. + *

+ * + * @param TiblEdit - the controller of the program. + */ + public void setController (TiblEdit jt) + { + controller = jt; + } + + /** + *

+ * This method returns the controller for this view. + *

+ * + * @return TiblEdit - the controller. + */ + public TiblEdit getController() + { + return controller; + } + + /** + *

+ * This method sets the list of recent files in the file menu + *

+ * + * @param recent - A Vector of the recent files from the controller. + */ + public void setRecentFiles(Vector recent) + { + int n = 0; + for(Iterator it=recent.iterator();it.hasNext();) + { + final File file = (File)it.next(); + if(n == RECENT_FILE_SIZE) {break;} + JMenuItem fileItem = recentFileItems[n++]; + fileItem.setText(file.getName()); + ActionListener al[] = fileItem.getActionListeners(); + if(al != null && al.length >0) {fileItem.removeActionListener(al[0]);} + fileItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent ae) + { + controller.openFile(file); + } + }); + fileItem.setVisible(true); + fileItem.setEnabled(true); + } + + for(;n + * This returns the {@link TextPane} that is the main view for tibbibl text information. + * The TextPane is set in this objects {@link #init} method and is set within a + * JScrollPane. + *

+ * + * @return TextPane the text pane that is the main content view of the program. + */ + public TextPane getTextPane() + { + return tp; + } + + /** + *

+ * This returns the position of the caret within the {@link TextPane} that is + * the main text view for the program. + *

+ * + * @return int - the position of the caret. + */ + public int getCaretPosition() + { + return tp.getCaret().getDot(); + } + + // Helper methods + /** + *

+ * This method is called by the controller when a file is opened. It serves to + * enable or disable the appropriate menu commands. Open is disabled, and + * close, save, view titles, add crit title, add ed title, and view editions consulted + * are turned on. + *

+ */ + public void fileOpened() + { + setTitle(PROG_NAME+controller.getCurrentFile().getName()); + openItem.setEnabled(false); + closeItem.setEnabled(true); + saveItem.setEnabled(true); + critTitleItem.setEnabled(true); + edTitleItem.setEnabled(true); + edConsultItem.setEnabled(true); + copyItem.setEnabled(true); + cutItem.setEnabled(true); + pasteItem.setEnabled(true); + editTransItem.setEnabled(true); + editNormItem.setEnabled(true); + masterIDItem.setEnabled(true); + insertEdItem.setEnabled(true); + removeEditionItem.setEnabled(true); + insertDiscItem.setEnabled(true); + for(int n=0;n + * This method is called by the controller when a file is closed. It serves to + * enable or disable the appropriate menu commands. Open is enabled and + * close, save, insert crit title, insert ed title, view titles, and view editions + * consulted are all disabled. It also calls {@link TextPane#reset}, which resets + * the styled document for the textpane view, calls {@link #hideEditions} to hide + * any table that is displaying at the bottom of the screen, and then redisplays itself + * with {@link #show}. + *

+ */ + public void fileClosed() + { + setTitle(DEFAULT_HEADER); + openItem.setEnabled(true); + closeItem.setEnabled(false); + saveItem.setEnabled(false); + critTitleItem.setEnabled(false); + edTitleItem.setEnabled(false); + edConsultItem.setEnabled(false); + copyItem.setEnabled(false); + cutItem.setEnabled(false); + pasteItem.setEnabled(false); + editTransItem.setEnabled(false); + editNormItem.setEnabled(false); + masterIDItem.setEnabled(false); + insertEdItem.setEnabled(false); + removeEditionItem.setEnabled(false); + insertDiscItem.setEnabled(false); + + tp.reset(); + hideEditions(); + setRecentFiles(controller.getRecent()); + setTitle(DEFAULT_HEADER); + show(); + } + + /** + *

+ * This method is called (maybe?) when the cursor is on a title. It enables the add + * critical title menu option. (May be deprecated?) + *

+ */ + public void titleSelected() + { + critTitleItem.setEnabled(true); + } + + /** + *

+ * This method is called (maybe?) when cursor is on something other than a title. It disnables the add + * critical title menu option. (May be deprecated?) + *

+ */ + public void titleNotSelected() + { + critTitleItem.setEnabled(false); + } + + /** + *

+ * This method displays a {@link TibTable} as the bottom half of a split screen with the {@link TextPane} + * This particular table displays the editions consulted for the formation of the master record + * by displaying the information in the text's tibiddecl element. To do so it uses {@link TibTable(IDFactory) TibTable constructor} + * that takes an {@link IDFactory} retrieved from the {@link TibDoc}. It then calls {@link #showTable(TibTable) TibTable} + * method. + *

+ */ + public void showEditions() + { + if(controller.getTibDoc() == null) {return;} + tibTable = new TibTable(controller.getTibDoc().getIDFactory()); + showTable(tibTable); + } + /** + *

+ * This method hides any table that is displaying at the bottom of the {@link TextPane}. The first + * table that used this was the edition's consulted table, but it will close any table including an apparatus + * table that is displaying at the bottom of the screen. + *

+ */ + + public void hideEditions() + { + topSp = new JScrollPane(tp); + if(horizontalSplit == null) { + setContentPane(topSp); + show(); + + } else { + int horizLoc = horizontalSplit.getDividerLocation(); + horizontalSplit.setRightComponent(topSp); + show(); + horizontalSplit.setDividerLocation(horizLoc); + } + show(); + verticalSplit = null; + } + + /** + *

+ * This method creates a split screen with a {@link DiacriticPanel(TibFrame) DiacriticPanel} + * on the left and the main {@link TextPane} on the right. + *

+ */ + public void showDiacritics() + { + dp = new DiacriticPanel(this); + rightSp = new JScrollPane(dp); + JComponent comp; + if(verticalSplit == null) { + leftSp = new JScrollPane(tp); + comp = leftSp; + } else { + comp = verticalSplit; + } + horizontalSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,rightSp,comp); + setContentPane(horizontalSplit); + show(); + double loc = 0.1D; + horizontalSplit.setDividerLocation(loc); + } + + /** + *

+ * This method hides the {@link DiacriticPanel} that is displayed on the left of + * the split screen. + *

+ */ + public void hideDiacritics() + { + JComponent comp; + if(verticalSplit == null) { + comp = tp; + } else { + comp = verticalSplit; + } + rightSp = new JScrollPane(comp); + setContentPane(rightSp); + show(); + horizontalSplit = null; + } + + /** + *

+ * This method displays a {@link TibTable} underneath the {@link TextPane}. It takes a + * {@link TibTable} as its parameter and depending on the value of its {@link TibTable#getType() type} + * inserts either an JTable with the editions consulted or it retrieves an {@link TibTable#getAppPanel() specific + * JPanel} that has a table with an apparatus' info and control buttons. + *

+ * + * @param TibTable the TibTable object that contains the tabular information to be displayed. + */ + public void showTable(TibTable tt) + { + JSplitPane tableSplit = new JSplitPane(); + if(tt.getType() == TibTable.APP) { + edConsultItem.setSelected(false); + tt.addObserver(controller); + tableSplit = tt.getAppPanel(); + bottomSp = tableSplit; + } else { + bottomSp = new JScrollPane(tt.getTable()); + } + topSp = new JScrollPane(tp); + verticalSplit = new JSplitPane(JSplitPane.VERTICAL_SPLIT,topSp,bottomSp); + if(horizontalSplit == null) { + setContentPane(verticalSplit); + show(); + } else { + int horizLoc = horizontalSplit.getDividerLocation(); + horizontalSplit.setRightComponent(verticalSplit); + show(); + horizontalSplit.setDividerLocation(horizLoc); + } + double loc = 0.80D; + verticalSplit.setDividerLocation(loc); + tableSplit.setDividerLocation(loc); + } + + /** + *

+ * This method is called if the insert variant option is chosen from the insert menu. Variant readings + * are displayed in the {@link TextPane} with a yellow background and are determined by being marked up + * within an app element. When inserting a new variant, the app element was not originally there so the + * selected area does not have a yellow background. This method sets the background of the selected area + * to yellow until the insertion is complete and the TextPane can be redisplayed. + *

+ */ + public void displayNewApp() + { + int start = tp.getSelectionStart(); + int len = tp.getSelectedText().length(); + Style variant = tp.getStyle(TextPane.VARIANT); + tp.getStyledDocument().setCharacterAttributes(start,len,variant,false); + } + + /** + *

+ * This method displays all the variations of text titles found in a {@link TibDoc}. It takes the + * TibDoc's {@link TitleFactory} and uses its {@link TitleFactory#getAllTitles() getAllTitles} method + * to retrive a vector of {@link ElementStyle ElementStyles}. It also adds a text header at the top + * and depending on the {@link TiblEdit#mode mode} of the controller (i.e., whether it is inserting a + * new title or translation, etc.) adds appropriate prompts. It then calls the {@link TextPane#setTextPane(Vector) TextPane's setTextPane(Vector)} + * method with the vector of StyleElements and this displays the information. That setTextPane method + * returns an {@link ElementList} which is a list of org.jdom.Elements with their associated positions in + * the TextPane (start and end) so that when the caret is positioned somewhere in the TextPane the controller + * can find the associated element and make the appropriate options available. + *

+ * + * @param TitleFactory - The TibDocs TitleFactory object for retrieving title information + * + * @return ElementList - The ElementList returned by the TextPane once its document is set. + * + */ + public ElementList showTitles(TitleFactory tf) + { + int presCaretPos = tp.getCaretPosition(); + if(presCaretPos < 0) {presCaretPos = 0;} + + styleElements = new Vector(); + + // Do the Text's Header Element as the documents general header + String[] headStrings = tf.getHeadStrings(); + + if(headStrings == null) { + + styleElements.add(new ElementStyle("No Head Element Found\n\n",TextPane.TEXT_HEAD,NO_ELEM)); + + } else { + styleElements.add(new ElementStyle(headStrings[0]+" ",TextPane.TEXT_HEAD,NO_ELEM)); + + if(headStrings.length>1) { + for(int n=1;n + * This method is used by {@link #showTitles(TitleFactory)} to insert prompts for information + * at the correct location. The showTitles method creates a vector of {@link ElementStyles}. Once + * this is created, if the {@link TiblEdit#mode} is to insert a title or translation. This method + * is called with the selected element. It searches the vector for that element and returns its + * index in the vector. + *

+ * + * @param org.jdom.Element - the selected element. + * + * @return int - that element's index in the ElementStyle Vector. + */ + private int findElementStyleIndex(org.jdom.Element el) + { + if(styleElements == null) { + System.out.println("No styleElements list to search in findElementStyleIndex of TibFrame"); + return -1; + } + int index = -1; + Iterator it = styleElements.iterator(); + while(it.hasNext()) + { + Object item = it.next(); + //System.out.println("It is: " + item.getClass().getName()); + ElementStyle es = (ElementStyle)item; + if(es.getElement().equals(el)) { index = styleElements.indexOf(es);} + } + if(index == -1) { + //System.out.println("Element was not found: " + TiblEdit.outputString(el)); + } + return index; + } + + public DiscDialog getDiscussionDialog(TibDoc tibl) + { + DiscDialog dd = new DiscDialog(this, tibl); + return dd; + } + + // Constructor + /** + *

+ * This constructor simply takes a title as the corresponding JFrame contructor. + *

+ * + * @param String - the frame's title. + */ + public TibFrame(String title) + { + super(title); + init(); + } + + /** + *

+ * This constructor takes both a title and a {@link TiblEdit} object that is its controller. + * It first calls JFrame's title constructor, then {@link #setController(TiblEdit) the setController} method + * and then the {@link #init()} method. + *

+ */ + public TibFrame(String title, TiblEdit app) + { + super(title); + setController(app); + init(); + } + + // Main for testing + + public static void main(String[] args) + { + } + + // Listeners + /** + *

+ * This implementation of the CaretListener interface calls the controller's + * {@link TiblEdit#checkCaretPosition(String) checkCaretPosition} method with the type of {@link TibConstants#AP AP} + * to see if an appartatus element is insertable. If so, then it turns on the insert variant reading + * menu item. If not, that item is turned off. + *

+ * + * @param CaretEvent - the required parameter of this abstract method. It is not used here. + */ + public void caretUpdate(CaretEvent ce) + { + boolean canInsertAp = controller.checkCaretPosition(AP_CHECK); + if(canInsertAp) { + variantItem.setEnabled(true); + } else { + variantItem.setEnabled(false); + } + + if(controller.checkCaretPosition(ED_TITLE_REM)) { + removeTitleItem.setEnabled(true); + } else { + removeTitleItem.setEnabled(false); + } + } + + // SubClasses Event Handlers + /** + *

+ * The inner class, XWindowHandler, extends the WindowAdapter and is used for the closing of the frame. + * It is added to the TibFrame in its {@link #init} method. + *

+ */ + + /** + *

+ * When the TibFrame is closed, the program ends. The window is disposed. The controller's + * {@link TiblEdit#writePrefs() writePrefs()} method is called, and the system is exited. + *

+ * + * @param WindowEvent - the required parameter for this abstract method. + */ + public class XWindowHandler extends WindowAdapter + implements TibConstants + { + + public void windowClosing(WindowEvent e) + { + e.getWindow().dispose(); + controller.exit(); + } + } + public class XComponentHandler extends ComponentAdapter + { + + public void ComponentResized(ComponentEvent ce) + { + show(); + } + } + + +} diff --git a/source/org/thdl/tib/bibl/TibTable.java b/source/org/thdl/tib/bibl/TibTable.java new file mode 100644 index 0000000..ee8a9e7 --- /dev/null +++ b/source/org/thdl/tib/bibl/TibTable.java @@ -0,0 +1,632 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.awt.*; +import java.awt.event.*; +import java.util.Hashtable; +import java.util.Vector; +import java.util.Iterator; +import java.util.Observable; +import java.util.Observer; +import javax.swing.*; +import javax.swing.text.*; +import javax.swing.table.*; +import org.jdom.*; + +/** +* This element is a wrapper element for a JTable that sets up two kinds of tables for editing a Tibbibl--one for +* displaying various editions and one for displaying alternative readings. +*/ + +public class TibTable extends Observable implements TibConstants, ActionListener +{ + // Attributes + private JTable theTable; + private TibTableModel ttm; + private org.jdom.Element app, pagination; + private IDFactory idf; + private Hashtable pageHash; + private int type; + private boolean editable; + private int mainrow; + private TibTableCellRenderer ttcr; + + + // Constants + public static int EDS_CONSULTED = 0; + public static int APP = 1; + + // Header Constants + private static String ED_NAME_HEAD = "Edition Name"; + private static String ED_HEAD = "Edition"; + private static String VOL_HEAD = "Volume"; + private static String TEXT_HEAD = "Text No."; + private static String PAGE_HEAD = "Pagination"; + private static String READING = "Reading"; + private static String ID_HEAD = "Id. No."; + private static String IS_MAIN = "Main Reading"; + + public static String MAINED = "Set Main Edition"; + public static String REMOVE_RDG = "Remove Reading"; + public static String SUB = "Done"; + public static String CANC = "Cancel"; + + private static String[] DEFAULT_HEADS = {ED_NAME_HEAD, ID_HEAD,VOL_HEAD,PAGE_HEAD}; + private static String[] ED_CON_HEADS = {ED_HEAD,TEXT_HEAD,VOL_HEAD,PAGE_HEAD}; + private static String[] APP_HEADS = {ED_HEAD,VOL_HEAD,PAGE_HEAD,READING,IS_MAIN}; + + // Accessor methods + public void setTable(JTable jt) + { + theTable = jt; + ttcr = new TibTableCellRenderer(); + ttcr.setMainRow(getMainRow()); + String st = new String(); + jt.setDefaultRenderer(st.getClass(),ttcr); + } + + public JTable getTable() + { + return theTable; + } + + public void setTibTableModel(TibTableModel ttm) + { + this.ttm = ttm; + } + + public TibTableModel getTibTableModel() + { + return ttm; + } + + public void setApp(org.jdom.Element ap) + { + app = ap; + } + + public org.jdom.Element getApp() + { + return app; + } + + public void setIDFactory(IDFactory idf) + { + if(idf == null) {System.out.println("IDF is null in TibTable!");} + this.idf = idf; + } + + public IDFactory getIDFactory() + { + return idf; + } + + public void setPagination(org.jdom.Element page) + { + pagination = page; + pageHash = new Hashtable(); + Iterator it = page.getChildren(NUM).iterator(); + while(it.hasNext()) + { + org.jdom.Element numChild = (org.jdom.Element)it.next(); + String ed = numChild.getAttributeValue(CORRESP); + String pageNums = TibDoc.cleanString(numChild.getText()); + pageHash.put(ed,pageNums); + } + } + + public org.jdom.Element getPagination() + { + return pagination; + } + + public Hashtable getPageHash() + { + return pageHash; + } + + public void setType(int type) + { + this.type = type; + } + + public int getType() + { + return type; + } + + public void setMainRow() + { + int oldrow = getMainRow(); + int row = theTable.getSelectedRow(); + String firstCell = (String)theTable.getValueAt(row,0); + if(firstCell == null || firstCell.equals("")) {return;} + setMainRow(row); + ttcr.setMainRow(row); + ttm.setValueAt(new Boolean(false),oldrow,4); + ttm.setValueAt(new Boolean(true),row,4); + theTable.repaint(); + } + + public void setMainRow(int mr) + { + mainrow = mr; + } + + public int getMainRow() + { + return mainrow; + } + + public String[] getHeaders() + { + if(type == EDS_CONSULTED) { + return ED_CON_HEADS; + } else if(type == APP) { + return APP_HEADS; + } + return DEFAULT_HEADS; + } + + // Helper methods + /** + *

+ * This is an "overriding" of the setTable(JTable jt) accessor, which simply sets the table variable + * to the given parameter. This method on the other hand sets the table + * depending on the {@link #type} of TibTable this is. If this TibTable is constructed + * solely with an {@link IDFactory}, then it is an {@link #EDS_CONSULTED} type. If it is + * constructed with an Apparatus element, IDFactory, and a Pagination element, then it + * is an {@link #APP}, or apparatus, type. This method will construct the table model + * accordingly. + *

+ */ + public void setTable() + { + if(type == EDS_CONSULTED) { + + Vector eds = idf.getEditionsConsulted(); + Object[][] tdata = new Object[eds.size()][ED_CON_HEADS.length]; + int e = 0; + Iterator it = eds.iterator(); + while(it.hasNext()) { + String ed = (String)it.next(); + if(ed.equals(NG)) {continue;} + tdata[e][0] = ed; + tdata[e][1] = idf.getTextNum(ed); + tdata[e][2] = idf.getVolNum(ed); + tdata[e][3] = idf.getPagination(ed); + for(int n=0; n<4; n++) { + if(tdata[e][n] == null) {tdata[e][n] = new String("");} + } + e++; + } + setTibTableModel(new TibTableModel(tdata,ED_CON_HEADS)); + setTable(new JTable(getTibTableModel())); + + } else if (type == APP) { + doAppTable(); + } + + } + + public void doAppTable() + { + Vector eds = new Vector(idf.getEditionsConsulted()); + java.util.List readings = getApp().getChildren(); + Object[][] tdata = new Object[eds.size()+1][APP_HEADS.length]; + for(int r=0;r-1) {continue;} + volNum = idf.getVolNum(ed); + pageNum = (String)pageHash.get(ed); + } else { + volNum = new String(); + pageNum = new String(); + } + tdata[c][0] = ed; + tdata[c][1] = volNum; + tdata[c++][2] = pageNum; + } + + setTibTableModel(new TibTableModel(tdata,APP_HEADS)); + setTable(new JTable(getTibTableModel())); + } + + public JSplitPane getAppPanel() + { + JScrollPane tablePane; + JPanel buttonPanel; + JButton mainEdButton, removeButton, submitButton, cancelButton; + + JSplitPane fullPane; + + tablePane = new JScrollPane(getTable()); + + buttonPanel = new JPanel(new GridLayout(4,1)); + buttonPanel.setSize(new Dimension(200,250)); + + mainEdButton = new JButton(MAINED); + buttonPanel.add(getButtonPanel(mainEdButton)); + mainEdButton.addActionListener(this); + + removeButton = new JButton(REMOVE_RDG); + buttonPanel.add(getButtonPanel(removeButton)); + removeButton.addActionListener(this); + + submitButton = new JButton(SUB); + buttonPanel.add(getButtonPanel(submitButton)); + submitButton.addActionListener(this); + + cancelButton = new JButton(CANC); + buttonPanel.add(getButtonPanel(cancelButton)); + cancelButton.addActionListener(this); + + buttonPanel.setBackground(Color.white); + fullPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,tablePane,buttonPanel); + + return fullPane; + } + + public JPanel getButtonPanel(JButton jb) + { + jb.setPreferredSize(new Dimension(150,20)); + JPanel butPanel = new JPanel(); + butPanel.setBackground(Color.white); + butPanel.add(jb); + return butPanel; + } + + public void setEditable(boolean torf) + { + editable = torf; + ttm.setEditable(torf); + } + + public boolean isEditable() + { + return editable; + } + + public void doSubmit() + { + Hashtable args = new Hashtable(); + args.put(AP,app); + args.put(PAGIN,pagination); + args.put(TABLE,ttm); + args.put(TYPE,APP_SUBMIT); + setChanged(); + notifyObservers(args); + } + + public void doRemove() + { + int row = theTable.getSelectedRow(); + String sigla = theTable.getValueAt(row,0).toString(); + boolean isMain = false; + try { + isMain = ((Boolean)theTable.getValueAt(row,4)).booleanValue(); + } catch (ClassCastException cce) { + System.out.println("Fifth column is not a boolean! (" + row + ":" + sigla +")"); + } + if(isMain) { + JOptionPane.showMessageDialog(null,"You cannot remove the main reading!", + "Unable to Remove Reading", + JOptionPane.ERROR_MESSAGE); + } else { + deleteRow(row); + } + } + + public void doCancel() + { + Hashtable args = new Hashtable(); + args.put(TYPE,CANCEL); + setChanged(); + notifyObservers(args); + } + + public void deleteRow(int row) + { + Object[][] data = ttm.getData(); + Object[] colHeads = ttm.getColumnNames(); + + if(row>=data.length) {return;} + + Object[][] newData = new Object[data.length-1][colHeads.length]; + int n = -1; + + for(int r=0; rrow) { + setMainRow(getMainRow()-1); + ttcr.setMainRow(getMainRow()); + } + + theTable.repaint(); + } + + // Constructors + + public TibTable() + { + setType(-1); + } + + public TibTable(Object[][] in_data, int type) + { + setType(type); + TibTableModel ttm = new TibTableModel(in_data, getHeaders()); + setTibTableModel(ttm); + setTable(new JTable(ttm)); + } + + public TibTable(IDFactory idf) + { + setType(EDS_CONSULTED); + setIDFactory(idf); + setTable(); + } + + public TibTable(org.jdom.Element app, IDFactory idf, org.jdom.Element page) + { + setType(APP); + setApp(app); + setIDFactory(idf); + setPagination(page); + setTable(); + setEditable(true); + } + // Listener Methods + public void actionPerformed(ActionEvent ae) + { + String actionType = ae.getActionCommand(); + if(actionType.equals(MAINED)) { + setMainRow(); + } else if (actionType.equals(REMOVE_RDG)) { + doRemove(); + } else if (actionType.equals(SUB)) { + doSubmit(); + } else if (actionType.equals(CANC)) { + doCancel(); + } + } + + + // Table model as inner class + public class TibTableModel extends AbstractTableModel + { + Object[] columnNames; + Object[][] data; + + boolean editable; + boolean isEditions; + + public void setEditable(boolean torf) + { + editable = torf; + } + + public String getColumnName(int col) + { + if(col<0 || col>=getColumnCount()) {return new String();} + return columnNames[col].toString(); + } + + public Object[] getColumnNames() + { + return columnNames; + } + + public Object[][] getData() + { + return data; + } + + public int getRowCount() { return data.length; } + + public int getMainRow() { + for(int r=0;rgetColumnCount()) {return null;} + Object val = getValueAt(0, col); + if(val == null) {val = new String();} + return val.getClass();} + + public Object getValueAt(int row, int col) + { + int rowCount = getRowCount(); + int colCount = getColumnCount(); + if(row<0 || row>rowCount || col<0 || col>colCount) {return "";} + return data[row][col]; + } + + public boolean isCellEditable(int row, int col) + { + if(getColumnName(col).equals(IS_MAIN)) {return false;} + return editable; + } + + public void setValueAt(Object value, int row, int col) + { + data[row][col] = value; + } + + public void setValueAt(int row, int col, String value) + { + value = TibDoc.cleanString(value); + data[row][col] = value; + } + + public String getStringAt(int row, int col) + { + Object datum = getValueAt(row,col); + if(datum instanceof String) { + return (String)datum; + } + return null; + } + + // Helper methods + public int findColumn(String colName) + { + for(int c=0; c +* TiblEdit is a editor for the master catalog records of the +* rNying ma rgyud 'bum. These XML records are displayed in an editor window +* so that the user can enter certain information into them. It is primarily geared +* toward allowing the user to critically edit and translate titles. Hence, the name. +* However, it also at the same time provides the option to assign doxographical +* genres and other critical information that are then stored in the XML file with +* valid mark-up. +*

+* +* @author Than Garson, Tibetan and Himalayan Digital Library +* @version 1.0 +*/ + +public class TiblEdit implements MouseListener, KeyListener, Observer, TibConstants +{ + // Attributes + /** + *

+ * This is the main window or the view for the TiblEdit class, which acts + * as the controller. + *

+ */ + TibFrame tibFrame; + + /** + *

+ * This is a reader for XML files that returns a {@link TibDoc}. + *

+ */ + XMLReader xreader = new XMLReader(); + + /** + *

+ * This instantiation of XMLOutputter is used for writing the XML files. It is different + * from the static instantiation of the same class, the variable {@link #xop}, that is used + * for debugging purposes to print out string versions of elements. + *

+ */ + XMLOutputter XMLOut = new XMLOutputter(""); + + /** + *

+ * This is the folder where the data, or unprocessed master catalog records, are held. + *

+ */ + String dataDirectory; + + /** + *

+ * This is the folder where the files are written to. + *

+ */ + File outDirectory; + + /** + *

+ * This is the directory currently being worked in, is updated as user navigates to different + * folders with the JFileChooser. + *

+ */ + File currentDirectory; + + /** + *

+ * This is the presently open file that is being worked on. + *

+ */ + File currentFile; + + + /** + *

+ * This is the list of recently opened files. + *

+ */ + Vector recent; + + /** + *

+ * This is the name of the file which is changed when the master ID is changes + *

+ */ + String fileName; + + /** + *

+ * This is the {@link TibDoc} that serves as the data model for the open file/text. + * It contains the XML tibbibl record that is presently being worked on. + *

+ */ + TibDoc tibbibl; + +/** +* The name of the editor using TiblEdit. This is entered +* the first time the program is run and thereafter stored in a preferences file. +* Once entered, it can be changed through the options menu. +*/ + private String editorsName; + +/** +* The initials of the editor using TiblEdit. This is entered +* the first time the program is run and thereafter stored in a preferences file. +* Once entered, it can be changed through the options menu. +*/ + private String editorsInitials; + +/** +* The present date formatted as yyyy-mm-dd, obtained from the operating system and stored +* as metadata in each XML file written. +*/ + private String todaysDate; +/** +*

+* This is the file chooser object that will be modified in {@link #setFileChoose} so +* that it displays the text names instead of the file names when opening a file. +*

+*/ + private JFileChooser fc; + + /** + * These need to be documented. + */ + private boolean is_file_list; +/** +*

+* This ElementList contains a list of elements that are displayed in +* the {@link TextPane}. It connects the elements with the starting and ending position +* of their displayed text so that when a selection of text is made the program can look +* up the associated element in the element list. It is used to set the {@link #selected_element} +* variable. +*

+*/ + ElementList elemList; +/** +*

+* This is the element that is found at the caret position or the selected text within +* the {@link TextPane}. It is then processed in various methods depending on the +* choice selected. It is set by this object's {@link #mouseClicked} method or else by +* the TextPane itself when a menu option is chosen. +*

+*/ + private org.jdom.Element selected_element; +/** +*

+* These variables are generic JDOM Elements for parent, grandparent, element (or self), +* and child. They are used throughout the program. +*

+*/ + org.jdom.Element parent, grandparent, element, child; + +/** +*

+* This is a {@link TextPane} that is gotten from {@link TibFrame} and is used in methods for inserting elements. +*

+*/ + TextPane tp; +/** +*

+* This is the current display/functioning mode of the program. It has four settings: +*

  1. {@link TibConstants#NORM} - normal +*
  2. {@link TibConstants#ENTER_TRANS} - for entering translations +*
  3. {@link TibConstants#NEW_TITLE} - for entering new versions of a title +*
  4. {@link TibConstants#NEW_AP} - for entering variant readings within a title. +*

+*/ + int mode; +/** +*

+* This is a variable that counts how many files have been outputted that have no +* file name. This is just in case something goes wrong and the file needs a name. +* Each time such a file is written, this is appended to the generic name and augmented one +* so the next file will have a unique name. It appears below, but the situation for its +* use never occurs. FIX! +*

+*/ + int outCount; + +/** +*

This is the Thread used to run the splash screen while the program +* loads. +*

+*/ + protected static Thread t; + + +/** +*

+* This variable tells whether a text has been saved or not +*

+*/ + boolean hasBeenSaved; + + Hashtable edNames; + + Hashtable fileHash; + + TibDialog editorsDialog; + + // For testing and debugging purposes. + /** + *

+ * This static instanciation of an {@link org.jdom.output.XMLOutputter} is used by + * the static method {@link #outputString}, to print XML mark-up for debugging + * purposes. + *

+ */ + public static XMLOutputter xop = new XMLOutputter(); + + + //init method + /** + *

+ * The init method sets the {@link #dataDirectory}, {@link #currentDirectory}, + * and the {@link tibFrame} variables. It reads in preferences from {@link #readPrefData}, + * performs {@link #setDate} and {@link #setFileChooser}, and sets the {@link #mode} + * to {@link TibConstants@NORM}. + *

+ */ + public void init() + { + showSplash(); + for(int fxc=0; fxc<100000; fxc++) { int nfx = fxc; } + + setDate(); + // set up log output stream + File logDirectory = new File(DEFAULT_DIRECTORY + BIN_LOGIN); + if(!logDirectory.exists()) { + //System.out.println("Making log directory!"); + logDirectory.mkdir(); + } + int n = 1; + String logFileName = "Session_" + getDate() + "_" + n + ".txt"; + File logFile = new File(logDirectory, logFileName); + while(logFile.exists()) { + n++; + logFileName = "Session_" + getDate() + "_" + n + ".txt"; + logFile = new File(logDirectory, logFileName); + if(n>1000) {break;} + } + try { + FileOutputStream logFos = new FileOutputStream(logFile); + PrintStream logPs = new PrintStream(logFos, true); + System.out.println("Resetting System and Error out to: \n\t" + logFile.getPath()); + System.setOut(logPs); + System.setErr(logPs); + } catch (FileNotFoundException fnfe) { + System.out.println("File not found exception is opening log output stream: " + logFile.getName()); + } catch (SecurityException se) { + System.out.println("Security exception in assigning log output stream!"); + } + + dataDirectory = DEFAULT_DIRECTORY + DATA_DIRECTORY; + currentDirectory = new File(dataDirectory); + outDirectory = new File(DEFAULT_DIRECTORY + OUT_DIRECTORY); + tibFrame = new TibFrame(DEFAULT_HEADER, this); + + mode = NORM; + hasBeenSaved = false; + + editorsDialog = new TibDialog(tibFrame,EDITORS_INFO,EDITORS_INFO_SPECS); + editorsDialog.setSize(new Dimension(450,100)); + readPrefData(); + + tibFrame.setRecentFiles(recent); + + edNames = new Hashtable(); + edNames.put(NG,EDNAMES[0]); + edNames.put(TB,EDNAMES[1]); + edNames.put(TK,EDNAMES[2]); + edNames.put(DG,EDNAMES[3]); + edNames.put(BG,EDNAMES[4]); + edNames.put(KG,EDNAMES[5]); + + } + + /** + * This reads in the preferences from the preference file that is located in + * {@link TibConstants#DEFAULT_DIRECTORY} + {@link TibConstants#BIN} + + * {@link TibConstants#PREFS}. The main preferences that are stored in this file + * are: the {@link editorsInitials} and {@link editorsName}. + *

+ */ + public void readPrefData() + { + is_file_list = false; + recent = new Vector(); + File prefFile = new File((DEFAULT_DIRECTORY + BIN + PREFS)); + if(prefFile.exists()) + { + try + { + BufferedReader br = new BufferedReader(new FileReader(prefFile)); + String line = new String(); + while(br.ready()) { + line = br.readLine(); + int ind = line.lastIndexOf(PREFS_DELIM); + System.out.println("Init line read: {"+line+"} = " + + (line!=null?Integer.toString(line.length()):"null")); + if(line == null || line.indexOf("null")>-1 + || ind == -1 || ind>line.length()-2) + { + getEditorInfo(); + } else { + + if(line.indexOf(EDITORS_NAME)>-1) { + editorsName = line.substring(ind+1); + } else if (line.indexOf(EDITORS_INITIALS)>-1) { + editorsInitials = line.substring(ind+1); + } else if(line.indexOf(IS_FILE_LIST)>-1) { + String is_there = line.substring(ind+1); + if(is_there.equals(YES)) {is_file_list = true;} + } else if(line.indexOf(RECENT)>-1) { + String recentName = line.substring(ind+1); + recent.add(new File(recentName)); + if(recent.size()>RECENT_FILE_SIZE) {recent.remove(0);} + } + } + } + br.close(); + } + catch(IOException ioe) { + System.out.println("An io exception occurred while reading in data from the text list."); + System.out.println("The error was: " + ioe.getMessage() + " " + ioe.getClass().getName()); + } + } else { + getEditorInfo(); + } + + } + + /** + * This method is called if there is no editor information in the preference file. + * It uses a {@link TibDialog} with {@link TibConstants#EDITORS_INFO} title and + * {@link TibConstants#EDITORS_INFO_SPECS}. When the TibDialog closes, + * it calls {@link #setEditor}. + *

+ */ + public void getEditorInfo() + { + stopSplash(); + +System.out.println("in getEditorINfo!"); + + if(editorsInitials != null) { + editorsDialog.setValue(1,editorsInitials); + } + if(editorsName != null) { + editorsDialog.setValue(0,editorsName); + } + editorsDialog.show(); + } + + /** + *

+ * This method is called when the {@link TibDialog} for getting editor information + * closes. The information is extracted from the TibDialog and + * the variables {@link #editorsName} and {@link #editorsInitials} are set. + *

+ * + * @param tdia - the {@link TibDialog} which has gathered the information. + * + */ + public void setEditor() + { + editorsName = editorsDialog.getValue(EDITORS_NAME); + editorsInitials = editorsDialog.getValue(EDITORS_INITIALS); +System.out.println("EdName given: " + editorsName); +System.out.println("EdInits given: " + editorsInitials); + + if(editorsName == null || editorsName.length()<5 || editorsName.equals("null") + || editorsInitials == null || editorsInitials.length()<2 || editorsInitials.equals("null")) + { + doMessage(ED_ID_REQUIRED); + editorsName = ""; + editorsInitials = ""; + + getEditorInfo(); + } else { + editorsDialog.hide(); + editorsDialog = null; + } + } + + /** + *

+ * This sets the {@link #todaysDate} variable to the current date in the form: + * YYYY-MM-DD. + *

+ */ + public void setDate() + { + Calendar cal = new GregorianCalendar(); + int year, month, day; + year = cal.get(Calendar.YEAR); + month = cal.get(Calendar.MONTH)+1; + day = cal.get(Calendar.DAY_OF_MONTH); + + todaysDate = year + DATE_DELIM + (month<10?"0":"") + month + DATE_DELIM + + (day<10?"0":"") + day; + } + + /** + *

+ * This method returns the value of the today's date variable. + *

+ * + * @return String the present day's date in the form yyyy-mm-dd + */ + public String getDate() + { + return todaysDate; + } + + /** + *

+ * Writes the preference data. This is read in and stored upon initialization of TiblEdit, when the + * program is restarted. + *

+ */ + public void exit() + { + //System.out.print("Exiting ..."); + if(currentFile != null) {closeFile();} + String outFile = DEFAULT_DIRECTORY + BIN + PREFS; + File prefsFile = new File(outFile); + try + { + PrintWriter out1 = + new PrintWriter( + new BufferedWriter( + new FileWriter(prefsFile))); + out1.println(EDITORS_NAME+PREFS_DELIM+editorsName); + out1.println(EDITORS_INITIALS+PREFS_DELIM+editorsInitials); + for(Iterator it = recent.iterator(); it.hasNext();) + { + File recentFile = (File)it.next(); + if(recentFile != null) { + out1.println(RECENT+PREFS_DELIM+recentFile.getPath()); + } + } + out1.close(); + } + + catch(IOException ioe) + { + System.out.println("An I/O Exception occurred in writing the prefs file."); + System.out.println("Message: " + ioe.getMessage()); + ioe.printStackTrace(); + } + + getFrame().dispose(); + System.exit(0); + } + // Accessors + /** + *

+ * Sets the current directory to the given path. + *

+ * + * @param A File object that represents the path of the current directory. + */ + public void setCurrentDirectory(File cd) + { + currentDirectory = cd; + } + + /** + *

+ * Returns the path for the current working directory. + *

+ * + * @return File - The current working directory as a File object. + */ + public File getCurrentDirectory() + { + return currentDirectory; + } + + /** + *

+ * Returns the file that is currently being worked on. + *

+ * + * @return File - The currently open File object. + */ + public File getCurrentFile() + { + return currentFile; + } + + /** + *

+ * This sets the current display mode of the program. The values are: + *

  1. {@link TibConstants#NORM} - normal + *
  2. {@link TibConstants#ENTER_TRANS} - for entering translations + *
  3. {@link TibConstants#NEW_TITLE} - for entering new versions of a title + *
  4. {@link TibConstants#NEW_AP} - for entering variant readings within a title. + *
+ *

+ * + * @param int m - the value that sets the mode as above. + */ + public void setMode(int m) + { + mode = m; + } + + /** + *

+ * This returns the current display mode for the program. + *

+ * + * @return int - the current display mode + * + * @see setMode + */ + public int getMode() + { + return mode; + } + + /** + *

+ * Returns the view or {@link TibFrame} that is the GUI of this program. + *

+ * + * @return TibFrame - The frame which displays the text information. + */ + public TibFrame getFrame() + { + return tibFrame; + } + + /** + *

+ * This returns the {@link TibDoc} presently being worked on. + *

+ * + * @return The TibDoc that is open. + */ + public TibDoc getTibDoc() + { + return tibbibl; + } + + /** + *

+ * Sets the {@link #selected_element} variable to the presently selected element. + *

+ * + * @param org.jdom.Element - the selected element. + */ + public void setSelectedElement(org.jdom.Element e) + { + selected_element = e; + } + + /** + *

+ * Returns the presently selected element. + *

+ * + * @return org.jdom.Element - the selected element. + */ + public org.jdom.Element getSelectedElement() + { + return selected_element; + } + + /** + *

+ * Returns the editors initials. + *

+ * + * @return String - the initials. + */ + public String getEditorsInitials() + { + return editorsInitials; + } + + /** + *

+ * Returns the editors name + *

+ * + * @return String - the editor's name. + */ + public String getEditorsName() + { + return editorsName; + } + + /** + *

+ * Recturns the vector containing the recent files opened. + *

+ * + * @return Vector the list of recent files + */ + public Vector getRecent() + { + return recent; + } + + /** + *

+ * This sets the {@link #fc} variable to a JFileChooser and modifies + * it by adding an {@link XMLFilter} and a {@link TTFileView}. The latter serves + * to change the getName function in the file chooser so that it + * displays the Tibbibl's text name rather than the actual file name. The file name + * is still used when the text is saved. + *

+ */ + public void setFileChooser() + { + fc = new JFileChooser(getCurrentDirectory()); + fc.setFileFilter(new XMLFilter()); + /*TTFileView ttfv = new TTFileView(); + fc.setFileView(ttfv);*/ + fc.setDialogTitle(OPEN_TITLE); + } + + + /** + *

+ * This method sets the name of the file to be saved for a certain Tibbibl. It is invoked + * when the Master ID is set so that the name of the file reflects the master ID. + *

+ * + * @param String - the Master ID string that serves as the base of the file name + * + * + */ + public void setFileName(String masterID) + { + if(currentFile == null || masterID == null || masterID.trim().equals("")) {return;} + removeFromRecent(currentFile); + String currentFileName = currentFile.getName(); + File presDirectory = currentFile.getParentFile(); + + StringTokenizer toker = new StringTokenizer(tibbibl.getNormalizedTitle()," "); + String suffix = new String(); + for(int n=0;n<3;n++) { + if(toker.hasMoreTokens()) {suffix += "_" + toker.nextToken();} + } + + String masterName = masterID + suffix; + tibbibl.setID(masterName); + + if(presDirectory.equals(outDirectory)) { + File newFile = getNewFile(outDirectory, masterName); + System.out.println("Current file deleted in 1: " + currentFile.delete()); + tibbibl.setSysid(newFile.getName()); + save(newFile); + doMessage(RENAMING_FILE_SPECS, newFile.getName()); + } else { + File newFile = getNewFile(outDirectory, masterName); + System.out.println("Current file deleted in 2: " + currentFile.delete()); + tibbibl.setSysid(newFile.getName()); + save(newFile); + doMessage(SAVED_FILE_SPECS, newFile.getName()); + } + + } + +/** +*

+* This method returns the new File created from renaming a file according to its master doxographical +* classification. It is called once an entry has been made through the {@link DoxWindow} and the ID and +* Sysid have been changed. It takes the folder that new files are written to and the master ID name and +* returns the new file. It first checks to make sure the name is unique since it is build from the doxographical +* classification number and the first 3 words of the title. If there is a conflict, it begins to add numbers to +* the end of the name until a unique name is arrived at. +*

+* +* @param File outDirectory - this is the directory to which processed files are written. +* +* @param String masterName - the is the master name for the file, e.g. Ng3.1.5.gsang_ba_'dus +* +* @return File - the uniquely named file created by combining the two above and checking for conflicts. +*/ + public File getNewFile(File outDirectory, String masterName) + { + File renamedFile = new File(outDirectory, masterName + ".xml"); + int n = 2; + if(renamedFile.exists()) { + /*int response = doConfirm(FILE_EXISTS_SPECS,renamedFile.getName()); + if(response == JOptionPane.YES_OPTION) {return renamedFile;}*/ + masterName += "_" + n; + renamedFile = new File(outDirectory, masterName + ".xml"); + } + while(renamedFile.exists()) { + /*int response = doConfirm(FILE_EXISTS_SPECS,renamedFile.getName()); + if(response == JOptionPane.YES_OPTION) {return renamedFile;}*/ + n++; + masterName = masterName.substring(0,masterName.length()-2) + n; + renamedFile = new File(outDirectory, masterName + ".xml"); + if(n==25) { break;} + } + if(renamedFile.exists()) {System.out.println("Warning checkFile has returned a file name that already exists!");} + System.out.println("File name from check file: " + renamedFile.getName()); + return renamedFile; + } + + // Helper methods + + + /** + *

+ * This method uses a JFileChooser to get the user to choose a file and then + * calls {@link #openFile(File)} to open the selected file. + *

+ * + */ + public void openFile() + { + stopSplash(); + setFileChooser(); + + int returnVal = fc.showOpenDialog(getFrame()); + if(returnVal == JFileChooser.APPROVE_OPTION) + { + openFile(fc.getSelectedFile()); + } + } + + /** + *

+ * With the File sent to it, this method uses + * an instance of an {@link XMLReader} to read the file. It sets the tibbibl + * variable to the TibDoc extracted by the reader. It then creates a {@link TextPane}, and + * sends it to the internal method {@link #showTitles}, which displays titles from the TibDoc + * in the TextPane. The text pane is then put in a JScrollPane and this is sent + * to the {@link TibFrame} using its {@link TibFrame#fileOpened} method. + *

+ * + * @param File the file to be opened, sent by the file chooser. + */ + + public void openFile(File file) + { + stopSplash(); + if(xreader.setDoc(file)) + { + System.out.println("Opening file: " + file.getName()); + currentFile = file; + tibFrame.fileOpened(); + tibbibl = xreader.getDoc(); + tibbibl.addEditor(editorsInitials, editorsName,todaysDate); + String temp = tibbibl.getNormalizedTitle(); + if(temp.length()>100) { + int ind = temp.indexOf(' ',100); + if(ind < 50) { ind = 100;} + temp = temp.substring(0,ind) + " ..."; + } + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + hasBeenSaved = false; + tibFrame.getTextPane().setCaretPosition(0); + addToRecent(file); + + } else { + doMessage(OPEN_ERROR); + removeFromRecent(file); + } + } + + /** + *

+ * This method takes a file and checks the recent file list to see if it is not already there. + * If it is not, then it adds it to the list. + *

+ * + * @param File - the file to be added to the recent list. + * + */ + public void addToRecent(File newFile) + { + String nfName = newFile.getName(); + int listIndex = -1; + for(Iterator it=recent.iterator();it.hasNext();) + { + File listFile = (File)it.next(); + if(listFile.equals(newFile) || listFile.getName().equals(nfName)) { + listIndex = recent.indexOf(listFile); + break; + } + } + if(listIndex == -1) { + recent.add(newFile); + if(recent.size()>RECENT_FILE_SIZE) {recent.remove(0);} + } else { + if(recent.remove(recent.get(listIndex))) {recent.add(0,newFile);} + } + + } + + /** + * This method removes a file from the recent list if the controller (TiblEdit) + * cannot open it. + */ + public void removeFromRecent(File badFile) + { + int index = recent.indexOf(badFile); + if(index > -1) {recent.remove(index); tibFrame.setRecentFiles(recent);} + } + + /** + *

+ * Checks to make sure the file has first been saved. If not, then it prompts to save. + * If it has then, it calls {@link TibFrame#fileClosed} and sets {@link #currentFile} to null. + *

+ */ + public void closeFile() + { + if(!hasBeenSaved) { + int response = doConfirm(SAVE_SPECS); + if(response == JOptionPane.YES_OPTION) { + if(!saveTibbibl()) {return;} + } else if(response == JOptionPane.CANCEL_OPTION) { + return; + } + } + tibFrame.fileClosed(); + currentFile = null; + } + + /** + *

+ * This method saves the edited {@link TibDoc} which is {@link #tibbibl} as a new + * document to the {@link TibConstants#OUT_DIRECTORY}, checking first to make sure + * it does not already exist. If it does, it prompts to overwrite. + *

+ */ + protected boolean saveTibbibl() + { + if(tibbibl == null) {return false;} + String outPath = DEFAULT_DIRECTORY + OUT_DIRECTORY; + if(currentFile != null) + { + outPath += currentFile.getName(); + } else { + outPath += "Ng.undef" + (outCount++) + ".xml"; + } + + File outFile = new File(outPath); + /*if(outFile.exists()) + { + String mess = "A file by the name of " + outFile.getName() + " already exists!\n" + + "Do you wish to write over it?"; + String messTitle = "File Exists! Overwrite?"; + int response = JOptionPane.showConfirmDialog(getFrame(), mess, messTitle, + JOptionPane.YES_NO_OPTION, + JOptionPane.INFORMATION_MESSAGE); + if(response == JOptionPane.NO_OPTION) { + return saveAs(outFile); + } + }*/ + save(outFile); + return true; + } + + /** + *

+ * This method actually writes the given file to disk. It is called from the {@link #saveTibbibl} method and + * from the {@link #saveAs} method. + *

+ * + * @param File - the file to be saved + */ + public void save(File outFile) + { + try + { + FileOutputStream fos = new FileOutputStream(outFile); + DataOutputStream dos = new DataOutputStream(fos); + XMLOut.output(tibbibl,fos); + hasBeenSaved = true; + currentFile = outFile; + dos.close(); + fos.close(); + System.out.println("File, " + outFile.getName() + ", saved!"); + addToRecent(outFile); + } + catch (IOException ioe) + { + String mess = "An IO Exception occurred, while trying to save file (" + + outFile.getAbsolutePath() + "). File did not write! "; + String emess = ioe.getMessage(); + if(emess != null & emess.length()>1) {mess += emess;} + System.out.println("Error: " + ioe.toString()); + System.out.println(mess); + ioe.printStackTrace(); + return; + } + } + + + /** + *

+ * This method displays a Save As window through a JFileChooser. It is invoked from {@link #saveTibbibl} when + * the user attempts to save a file that exists but choses not to write over it. If the save option is chosen, + * it then calls {@link #saveTibbibl} which returns the success, creating a loop until either a unique file name is given, + * the overwrite option is chosen, or it is cancelled. + *

+ * + * @param File - the file + * + * @return boolean - whether the save operation was successful. + */ + public boolean saveAs(File outFile) + { + try + { + fc.setCurrentDirectory(outFile); + int response = fc.showSaveDialog(tibFrame); + if(response == JFileChooser.APPROVE_OPTION) + { + currentFile = fc.getSelectedFile(); + return saveTibbibl(); + } + } catch (HeadlessException he) {return false;} + return false; + + } + + /** + *

+ * This method causes the {@link TibFrame} to display a table with the + * information on variant readings at the bottom of its text pane. It is + * invoked by double clicking on section of the {@link TextPane} that displays + * in yellow background, indicating there is an app element there. The clicking + * sets the selected element to that app element. If the area is not associated with + * an app, nothing happens. If it is, this method first locates the associated + * pagination and then calls the {@link TibFrame#showTable} method that takes + * a {@link TibTable}. The TibTable is constructed using the selected element or app, + * the {@link IDFactory} of the Tibbibl, and the pagination element. + *

+ */ + public void showApp() + { + if(selected_element == null) { + // return if there is no selected element + return; + } + + // find the associated pagination element + org.jdom.Element page = null; + parent = selected_element.getParent().getParent().getParent(); + if(parent.getName().equals(TDIV)) { + page = parent.getChild(PAGIN); + } else if(parent.getName().equals(TIBBIBL)) { + page = parent.getChild(PHYSDEC).getChild(PAGIN); + } + // if the pagination is found + if(page != null) { + // If it's a new app call the appropriate method to insert the yellow backgroun + if(mode == NEW_AP) {tibFrame.displayNewApp();} + // + tibFrame.showTable(new TibTable(selected_element,tibbibl.getIDFactory(),page)); + } + } + + public void insertNewEdition() + { + if(tibbibl != null) + { + + TibDialog tdialog = new TibDialog(this,NEW_ED_INFO,NEW_ED_INFO_SPECS); + tdialog.showDialog(); + } + } + + public void submitNewEditionInfo(TibDialog tdia) + { + IDFactory idf = tibbibl.getIDFactory(); + String sigla = tdia.getValue(ED_SIG); + if(idf.hasEdition(sigla)) { + int response = doConfirm(ED_EXISTS_SPECS); + if(response == JOptionPane.YES_OPTION) + { + idf.removeEd(sigla); + } + } + idf.addEditionConsulted(tdia.getResults()); + idf.addSourceConsulted(sigla,editorsInitials,editorsName); + } + + /** + *

+ * This method inserts a title to be critically edited that is based on a particular + * edition title. It is called when an edition title is double clicked or when + * the corresponding insert command is chosen from the menu. It first locates the + * element at the caret, makes sure it is a title and then calls {@link #enterTranslation}. + * (Should it check for the title's type here?) + *

+ */ + public void insertCritTitle() + { + if(elemList == null) {return;} + element = elemList.getElementAt(tibFrame.getCaretPosition()); + if(element != null && element.getName().equals(TITLE)) { + selected_element = element; + enterTranslation(); + } + } + + /** + *

+ * This method is for inserting a new edition title. Edition titles cannot be + * critically edited. They represent titles as they appear in particular editions. + * One choses a particular edition title as the basis for a critical title which + * then can have app elements collating the various readings. This method uses + * a {@link TibDialog} with {@link TibConstants@NEW_ED_TITLE_INFO} and + * {@link TibConstants#NEW_ED_TITLE_INFO_SPECS} to get the title and its pagination. + * When the TibDialog is submitted, the {@link #insertNewEdTitle} method + * is called with that TibDialog. + *

+ */ + public void insertEdTitle() + { + if(tibbibl != null && checkCaretPosition(ED_TITLE)) + { + TibDialog tdialog = new TibDialog(getFrame(),NEW_ED_TITLE_INFO,NEW_ED_TITLE_INFO_SPECS); + tdialog.showDialog(); + } + } + + /** + *

+ * This is called when a {@link TibDialog} is submitted with new edition title information. + * It checks to see if the sigla of the new title (i.e., the edition it is from) already + * exists in the texts TibidDecl, using the tibbibl's {@link IDFactory}. If it does not, + * exist, another {@link TibDialog} is called with {@link TibConstants#NEW_ED_INFO} and + * {@link TibConstants#NEW_ED_INFO_SPECS} to get all the relevant information. When that + * second TibDialog is closed, the {@link #insertNewEdAndTitle} method + * is invoked. Otherwise, if the edition is known, it calls {@link TibFrame#showTitles} + * with an {@link TitleFactory} and a {@link #mode} equal to {@link TibConstants#NEW_TITLE} + * to display a place to enter the new title. + *

+ * + * @param TibDialog - The TibDialog with the information of the new title's sigla and pagination. + */ + public void insertNewEdTitle(TibDialog tdia) + { + String sigla = tdia.getValue(ED_SIG); + IDFactory idf = tibbibl.getIDFactory(); + if(idf.hasEdition(sigla)) { + setSelectedElement(tibbibl.addTitle(selected_element,sigla,tdia.getValue(TITLE_PAGE))); + mode = NEW_TITLE; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + setCaretPosition(); + } else { + String page = tdia.getValue(TITLE_PAGE); + tdia = new TibDialog(getFrame(),NEW_ED_INFO,NEW_ED_INFO_SPECS); + String edName = (String)edNames.get(sigla); + if(edName != null) {tdia.setValue(0,edName);} + tdia.setValue(1,sigla); + tdia.setValue(7,page); + tdia.showDialog(); + } + } + + /** + *

+ * This enters the information from the {@link TibDialog} called by {@link #insertNewEdTitle} + * into the TibidDecl of the Tibbibl and then calls {@link TibFrame#showTitles} with + * the {@link TitleFactory} of the Tibbibl and a {@link #mode} set to {@link TibConstants#NEW_TITLE}. + * This displays an entry place for the new title in the {@link TextPane}. + *

+ * + * @param TibDialog - the TibDialog with the information concerning the new edition. + */ + public void insertNewEdAndTitle(TibDialog tdia) + { + IDFactory idf = tibbibl.getIDFactory(); + idf.addEditionConsulted(tdia.getResults()); + idf.addSourceConsulted(tdia.getValue(ED_SIG),editorsInitials,editorsName); + tdia.dispose(); + setSelectedElement(tibbibl.addTitle(selected_element,tdia.getValue(ED_SIG),tdia.getValue(TITLE_PAGE))); + mode = NEW_TITLE; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + setCaretPosition(); + } + + /** + *

+ * This method is called when one either double clicks on a title or chooses enter a translation + * from the menu. It first determines if the selected element is the normalized title, in which case + * it sets the {@link #mode} to {@link TibConstants.ENTER_NORMALIZED ENTER_NORMALIZED} and redisplays with the appropriate prompts. + * Otherwise, it makes sure there is a Tibetan title there and not "No title given" or "Not specified" and + * if it's a valid title, asks the user if they want to create a critical title with the selected title + * as its base. If so, it redisplays with the appropriate prompts. + * + *

+ */ + + public void enterTranslation() { + if(selected_element.getName().equals(TITLE)) { + String type = selected_element.getAttributeValue(TYPE); + if(type != null && type.indexOf("Normalized")>-1) { + mode = ENTER_NORMALIZED; + } else { + parent = selected_element.getParent(); + child = parent.getChild(TITLE); + if(child != null) { + // If there are a list of Title elements in this titleDecl, the first + // one will always be the critical edition of the title with corresp=Ng + // if it is not there, then it needs to be added. + String corresp = child.getAttributeValue(CORRESP); + if(corresp != null && corresp.equals(NG)) { + selected_element = child; + } else { + if(corresp == null) { + System.out.println("No corresp element: \n" + outputString(child)); + } + + String text = selected_element.getText(); + if(text.indexOf(NOT_SPEC)>-1) { + doMessage(NOT_SPEC_SPECS); + mode = CANC; + tibFrame.getTextPane().addCaretListener(tibFrame); + return; + } + if(text.indexOf(NO_TITLE)>-1) { + doMessage(NO_TITLE_SPECS); + mode = CANC; + tibFrame.getTextPane().addCaretListener(tibFrame); + return; + } + + String mess = "Do you wish to create a critical edition for this title, \n" + + "using the following title as the base: \n"; + String title = TibDoc.cleanString(selected_element.getText()); + if(title.length()>50) { + int half = title.length()/2; + int index = title.indexOf(" ",half); + if(index == -1) {mess += title;} else { + mess += title.substring(0,index) + "\n" + title.substring(index+1); + } + } else { + mess += title; + } + mess += "\nEdition: " + selected_element.getAttributeValue(CORRESP); + String[] specs = {mess,"Create Critical Title", + Integer.toString(JOptionPane.YES_NO_OPTION)}; + int resp = doConfirm(specs); + if(resp == JOptionPane.YES_OPTION) { + mode = ENTER_TRANS; + selected_element = tibbibl.createCriticalTitle(selected_element,editorsInitials); + } + } + } + } + + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + //setCaretPosition(); + } + } + + + /** + *

+ * This method is called when a new translation has been entered into the + * {@link TextPane} and Enter has been pressed. It locates the text of the new + * translation in the TextPane from the {@link TibConstants#ENTER_TRANS_PHRASE} + * prompt to the next paragraph mark "/n", and then calls the {@link TibDoc#addTranslation} + * method with this translation String and the {@link #selected_element}. + * The display mode ({@link #mode}) is then set to {@link TibConstants#NORM} and + * the text is redisplayed using {@link TibFrame@showTitles} which returns + * an {@link ElementList} that is assigned to {@link #elemList}. + *

+ */ + private void insertTranslation() + { + tp = tibFrame.getTextPane(); + String trans = tp.getText(); + + try { + trans = trans.substring(trans.indexOf(ENTER_TRANS_PHRASE) + ENTER_TRANS_PHRASE.length()); + trans = trans.substring(0,trans.indexOf("\n")); + if(trans != null) {trans = trans.trim();} + tibbibl.addTranslation(trans,selected_element); + } catch (IndexOutOfBoundsException ibe) + { + System.out.println("Index out of bounds setting translation:\n" + trans + "\n" + + ibe.getMessage()); + ibe.printStackTrace(); + } + + mode = NORM; + selected_element = null; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + //setCaretPosition(); + } + + /** + *

+ * This method is called when inserting an Edition title within a title decl. This is a title + * that belongs to a particular edition and is to be used as a source for a critical title. + * The infromation is received from a {@link TibDialog} and then a prompt for the title in the + * textpane, which is then read and placed in the title element. + *

+ */ + private void insertNewTitleAndTranslation() + { + + String title_text, trans, full_text; + tp = tibFrame.getTextPane(); + full_text = tp.getText(); + trans = new String(); + try { + int enterPhraseindex = full_text.indexOf(ENTER_TITLE_PHRASE); + if(enterPhraseindex == -1) { + enterPhraseindex = full_text.indexOf(ENTER_TITLE_PHRASE.substring(0,ENTER_TITLE_PHRASE.length()-2)); + } + if(enterPhraseindex>-1) { + + title_text = full_text.substring(enterPhraseindex+ENTER_TITLE_PHRASE.length()-2); + title_text = title_text.substring(0,title_text.indexOf("\n")); + if(title_text.substring(0,1).equals(":")) {title_text = title_text.substring(1);} + if(title_text != null) { + selected_element.setText(title_text.trim()); + } + } + + } catch (IndexOutOfBoundsException ibe) + { + System.out.println("Index out of bounds setting translation:\n" + trans + "\n" + + ibe.getMessage()); + ibe.printStackTrace(); + } + + mode = NORM; + selected_element = null; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + //setCaretPosition(); + } + +/** +*

+* This method updates the information for the normalized title after it has been entered into +* the {@link TextPane} by the editor and Enter has been pressed. It replaces the text within +* the Title tag for the Tibetan and its child Foreign tag for the english translation. It then +* calls {@link TibDoc#updateTextHeader() the updateTextHeader} method in {@link TibDoc} and +* redisplays. +*

+*/ + private void updateNormalizedTitle() + { + String title_text, trans, full_text; + tp = tibFrame.getTextPane(); + full_text = tp.getText(); + trans = new String(); + try { + title_text = full_text.substring(full_text.indexOf(ENTER_NORMALIZED_PHRASE)); + title_text = title_text.substring(ENTER_NORMALIZED_PHRASE.length()); + title_text = title_text.substring(0,title_text.indexOf("\n")); + if(title_text.substring(0,1).equals(":")) {title_text = title_text.substring(1);} + if(title_text != null) { + selected_element.setText(title_text.trim()); + } + org.jdom.Element foreign = selected_element.getChild(FOREIGN); + if(foreign == null) { + foreign = new org.jdom.Element(FOREIGN); + foreign.setAttribute(LANG,ENG); + selected_element.addContent(foreign); + } + trans = full_text.substring(full_text.indexOf(ENTER_NORM_TRANS_PHRASE)); + trans = trans.substring(ENTER_NORM_TRANS_PHRASE.length()); + trans = trans.substring(0,trans.indexOf("\n")); + if(trans.substring(0,1).equals(":")) {trans = trans.substring(1);} + if(trans != null) { + foreign.setText(trans.trim()); + } + + + } catch (IndexOutOfBoundsException ibe) + { + System.out.println("Index out of bounds setting translation:\n" + trans + "\n" + + ibe.getMessage()); + ibe.printStackTrace(); + } + + mode = NORM; + selected_element = null; + tibbibl.updateTextHeader(); + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + //setCaretPosition(); + + } + + /** + *

+ * This method is called when a selection of title text is made and the insert + * variant reading choice is taken from the Insert menu. It first checks to make + * sure the caret is in the appropriate place using {@link #checkCaretPosition} with + * the param {@link TibConstants#AP}. If it is a viable insertion point, it calculates + * the offset of the selection from the previous paragraph mark and calls + * {@link TibDoc#insertApp} using the {@link #selected_element}, the selected text, + * and this offset from the last paragraph integer. The {@link #mode} is then set + * to {@link TibConstants#NEW_AP} and the {@link #showApp} method is called. + *

+ */ + public void insertApp() + { + if(checkCaretPosition(AP)) { + if(selected_element == null) { + System.out.println("Selected element is null in insertApp!"); + return; + } + TextPane tp = tibFrame.getTextPane(); + String docText = ""; + try { + docText = tp.getDocument().getText(0,tp.getDocument().getLength()); + } catch (BadLocationException ble) { + docText = tp.getText(); + System.out.println("Can't get documents text!"); + } + String selText = tibFrame.getTextPane().getSelectedText(); + if(selText == null || selText.length()==0) { + System.out.println("Nothing selected!"); + doMessage(NO_SELECTION_SPECS); + } else { + + int selStart = tp.getSelectionStart(); + int prevPara = docText.lastIndexOf("\n",selStart); // had a +1 + int postPara = docText.indexOf("\n",selStart); + int offset = selStart - prevPara; + selected_element = tibbibl.insertApp(selected_element,selText,offset); + setMode(NEW_AP); + tibFrame.hideEditions(); + showApp(); + } + } + } + + /** + *

+ * This method inserts a particular type of discussion depending on the setting of the + * type parameter. When type equals {@link TibConstants.TITLE TITLE}, a discussion will be inserted + * for the title at the cursor position of the {@link TextPane}. When type equals {@link TibConstants.GEN GEN} + * the user will be prompted with a list of options to choose from. + *

+ * + * @param type - the string indicating which typeof discussion to insert. + */ + public void insertDiscussion() + { + DiscDialog discDia = tibFrame.getDiscussionDialog(tibbibl); + discDia.showDiscussionDialog(); + } + + /** + * This method takes a TitleDecl or any grouping element that might contain a discussion element and + * checks to see if it has a prose discussion within it. If so, this prose discussion element (i.e., + * one that has type=brief or type=full) is returned. Otherwise, null is return. It is used also by {@link DiscDialog} + * and so needs to be static. + */ + + public static org.jdom.Element locateDisc(org.jdom.Element parent) + { + org.jdom.Element outDisc = null; + List discEls = parent.getChildren(DISC); + for(Iterator it = discEls.iterator(); it.hasNext();) { + outDisc = (org.jdom.Element)it.next(); + String discType = outDisc.getAttributeValue(TYPE); + if(discType.equalsIgnoreCase(BRIEF) || discType.equalsIgnoreCase(FULL)) { + return outDisc; + } + } + return null; + } + + /** + *

+ * This method is used to display a text's variant titles. It first calls + * {@link TibFrame#hideEditions} to hide any table displaying at the bottom. + * It then sets the mode to {@link TibConstants#NORM} and calls {@link TibFrame#showTitles} + *

+ */ + public void showTitles() + { + tibFrame.hideEditions(); + if(tibbibl == null) {return;} + if(mode == CANCEL_NEW_APP) { + tibbibl.removeApp(selected_element); + } + mode = NORM; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + //setCaretPosition(); + } + + /** + *

+ * This method is called from the {@link TibTable} which is observed by this + * controller. When it is submitted, it notifies this observer and this method is run. + * It takes a hashtable of arguments, as follows: + *

  • Key: {@link TibConstants#AP} -- the App that is being modified + *
  • Key: {@link TibConstants#TABLE} -- the {@link TibTable.TibTableModel} that contains the data. + *
  • Key: {@link TibConstants#PAGIN} -- the hashtable of paginations keyed on edition sigla, used to create table + *
+ * First, it sets the information for the main reading found in the {@link TibConstants#LEM} or lemma element. + * Then, it correlates the reading witnesses already in the app element with the siglas + * for the lines of data in the table and replaces the information in existing reading elements + * or adds new ones where necessary. + *

+ **/ + public void doAppSubmission(Hashtable args) + { + org.jdom.Element app, rdg, pagination, numEl; + TibTable.TibTableModel ttm; + Hashtable pageNums = new Hashtable(); + java.util.List readings; + org.jdom.Element lemma, reading, newElem; + String sigla, page; + + // Get info from hash table + app = (org.jdom.Element)args.get(AP); + ttm = (TibTable.TibTableModel)args.get(TABLE); + pagination = (org.jdom.Element)args.get(PAGIN); + if(app == null || ttm == null || pagination == null) { + System.out.println("Not enough arguments sent to doAppSubmission in Trans Title. Returning with nothing done!"); + return; + } + + app.removeChildren(); + + for(Iterator it=pagination.getChildren(NUM).iterator();it.hasNext();) { + numEl = (org.jdom.Element)it.next(); + sigla = numEl.getAttributeValue(CORRESP); + if(sigla == null || sigla.equals("")) { + System.out.println("Pagination with no sigla while trying to write APP!"); + continue; + } + pageNums.put(sigla,numEl); + } + + newElem = new org.jdom.Element(RDG); + + for(int r=0;r0) { + System.out.println("There are apps left over in Appread in TiblEdit\n" + + "While doing table submission!\nThe Readings are: "); + int c=1; + for(Enumeration keys = appReads.elements();keys.hasMoreElements(); ) + { + String item = (String)appReads.get(keys.nextElement()); + System.out.println(c + ": " + item); + } + }*/ + showTitles(); + } + + /** + *

+ * This method is invoked from the Edit menu and allows the user to edit an already + * existing translation for a title by inserting the Enter translation prompt prior to + * the text of the translation and allowing the {@link TextPane} to be editable. + *

+ */ + public void editTranslation() + { + if(checkCaretPosition(TRANS_EDIT)) + { + int caretPos = tibFrame.getTextPane().getCaretPosition(); + mode = DO_TRANS; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + //tibFrame.getTextPane().setCaretPosition(caretPos); + } else { + doMessage(INVALID_TRANS_SPECS); + } + } + + /** + *

+ * This method is invoked after a translation has been edited and the Enter key + * has been pressed. It replaces the text of the Foreign element containing the + * translation with the next text between the Enter translation prompt and the + * subsequent paragraph return. + *

+ * + * @see #keyPressed - the implementation of the KeyListener that invokes this method. + */ + public void updateTranslation() + { + String trans, full_text; + org.jdom.Element foreign; + if(selected_element == null) {return;} + tp = tibFrame.getTextPane(); + full_text = tp.getText(); + trans = new String(); + try { + if(selected_element.getName().equals(TITLE)) { + foreign = selected_element.getChild(FOREIGN); + } else if(selected_element.getName().equals(FOREIGN)) { + foreign = selected_element; + } else { + return; + } + + trans = full_text.substring(full_text.indexOf(ENTER_TRANS_PHRASE)); + trans = trans.substring(ENTER_TRANS_PHRASE.length()); + trans = trans.substring(0,trans.indexOf("\n")); + if(trans.substring(0,1).equals(":")) {trans = trans.substring(1);} + if(trans != null) { + foreign.setText(trans.trim()); + } + + + } catch (IndexOutOfBoundsException ibe) + { + System.out.println("Index out of bounds setting translation:\n" + trans + "\n" + + ibe.getMessage()); + ibe.printStackTrace(); + } + + mode = NORM; + selected_element = null; + elemList = tibFrame.showTitles(tibbibl.getTitleFactory()); + + } + + public void removeApp() + { + int pos = getFrame().getTextPane().getCaretPosition(); + element = elemList.getElementAt(pos); + if(element != null && element.getName().equals(AP)) + { + int response = doConfirm(REMOVE_APP_SPECS); + if(response == JOptionPane.YES_OPTION) { + tibbibl.removeApp(element); + } + showTitles(); + } + getFrame().getTextPane().setCaretPosition(pos); + } + + public void removeTitle() + { + int pos = getFrame().getTextPane().getCaretPosition(); + element = elemList.getElementAt(pos); + parent = element.getParent(); + if(element != null && element.getName().equals(TITLE)) + { + String corspVal = element.getAttributeValue(CORRESP); + org.jdom.Element sourceListing = tibbibl.findElement(NAME,ID,corspVal); + String srcCorrVal = (sourceListing==null?null:sourceListing.getAttributeValue(CORRESP)); + if((corspVal != null && corspVal.equals(editorsInitials)) || + (srcCorrVal != null && srcCorrVal.equals(editorsInitials))) { + int response = doConfirm(REMOVE_ED_TITLE_SPECS); + if(response == JOptionPane.YES_OPTION) { + element.detach(); + removePageRefs(parent,corspVal); + showTitles(); + } + } else { + doMessage(REMOVE_ED_TITLE_ERROR); + } + } + getFrame().getTextPane().setCaretPosition(pos); + } + + public void removePageRefs(org.jdom.Element parentEl, String corrsp) + { + if(parentEl.getChild(SRC) != null) { + org.jdom.Element src = parentEl.getChild(SRC); + int childIndex = -1; + for(Iterator it=src.getChildren(NUM).iterator();it.hasNext();) { + child = (org.jdom.Element) it.next(); + String crsAtt = child.getAttributeValue(CORRESP); + if(corrsp.equals(crsAtt)) { childIndex = src.getChildren().indexOf(child); break; } + } + if(childIndex > -1) { child.detach(); childIndex = -1;} + grandparent = parent.getParent(); + if(grandparent.getChild(PHYSDEC) != null) { + grandparent = grandparent.getChild(PHYSDEC); + parent = grandparent.getChild(PAGIN); + for(Iterator it=parent.getChildren(NUM).iterator();it.hasNext();) { + child = (org.jdom.Element) it.next(); + String crsAtt = child.getAttributeValue(CORRESP); + if(corrsp.equals(crsAtt)) { childIndex = parent.getChildren().indexOf(child); break; } + } + } + if(childIndex > -1) { child.detach(); childIndex = -1;} + } else { + grandparent = parentEl.getParent(); + int childIndex = -1; + if(grandparent.getChild(PAGIN) != null) { + parent = grandparent.getChild(PAGIN); + for(Iterator it=parent.getChildren(NUM).iterator();it.hasNext();) { + child = (org.jdom.Element) it.next(); + String crsAtt = child.getAttributeValue(CORRESP); + if(corrsp.equals(crsAtt)) { childIndex = parent.getChildren().indexOf(child); break; } + } + if(childIndex > -1) { child.detach(); childIndex = -1;} + } + } + } + + public void deleteEdition(org.jdom.Element edToDie) + { + if(getTibDoc() == null || edToDie == null) { return; } + String corrsp = edToDie.getAttributeValue(CORRESP); + org.jdom.Element edNameEl = tibbibl.findElement(NAME,ID,corrsp); + boolean failure = false; + String mess = new String(); + if(edNameEl != null) + { + String edNameCor = edNameEl.getAttributeValue(CORRESP); + if(corrsp == null || edNameCor.equals(editorsInitials)) { + edToDie.detach(); + edNameEl.detach(); + org.jdom.Element physdecl = tibbibl.findElement(PHYSDEC); + org.jdom.Element numFound = null; + for(Iterator it = physdecl.getChild(PAGIN).getChildren(NUM).iterator();it.hasNext();) { + org.jdom.Element num = (org.jdom.Element)it.next(); + String numCorr = num.getAttributeValue(CORRESP); + if(numCorr != null && numCorr.equals(corrsp)) { + numFound = num; + break; + } + } + if(numFound != null) { + numFound.detach(); + System.out.println("Detaching num in physdecl\n" + outputString(physdecl)); + } + org.jdom.Element[] others = tibbibl.findElements(CORRESP,corrsp); + for(int n=0; n + * This method is invoked when the {@link DoxWindow} is submitted. It calls upon the + * {@link TibDoc} to {@link TibDoc#setDoxography(String, String) setDoxography} and then + * to {@link TibDox#setMasterID(String) setMasterID}. + *

+ * + * @param DoxWindow - the doxography selection window that supplies the users input. + */ + public void enterDox(DoxWindow dw) + { + tibbibl.setDoxography(dw.getDoxString(TIB),dw.getDoxString(ENG)); + tibbibl.setMasterID(dw.getID()); + setFileName(dw.getID()); + } + + // methods for displaying messages and confirms. + /** + *

+ * This is a generic method to display a {@link javax.swing.JOptionPane} message + * dialog it takes a String array with three specs. + *

  1. the message + *
  2. the title + *
  3. the message type as defined in JOptionPane. + *
+ * The latter spec is converted to an integer. + *

+ * + * @param String[] - the specifications for the confirm dialog. + */ + + public void doMessage(String[] specs) + { + String mess, title; + int type; + mess = specs[0]; + title = specs[1]; + type = Integer.parseInt(specs[2]); + try{ + JOptionPane.showMessageDialog(tibFrame,mess,title,type); + } catch(HeadlessException he) {} + } + + public void doMessage(String[] specs, String append) + { + specs[0] += " " + append; + doMessage(specs); + } + + /** + *

+ * This is a generic method to display a {@link javax.swing.JOptionPane} confirm + * dialog it takes a String array with three specs. + *

  1. the message + *
  2. the title + *
  3. the message type as defined in JOptionPane. + *
+ * The latter spec is converted to an integer. + * + * @param String[] specs - the specifications for the confirm dialog. + * + * @return int - the response + *

+ */ + public int doConfirm(String[] specs) + { + + String mess, title; + int type; + mess = specs[0]; + title = specs[1]; + type = Integer.parseInt(specs[2]); + int response = JOptionPane.showConfirmDialog(tibFrame,mess,title,type); + return response; + } + + public int doConfirm(String[] specs, String append) + { + specs[0] += " " + append; + return doConfirm(specs); + } + +/** +*

+* This method sets the caret position to just after the enter information prompt +* depending on the {@link #mode} at the time it is called. The mode gives an indication +* which prompt is being used and should be searched for to determine the corresponding index +* at which to set the caret. This is not working correctly. 11 needs to be added to the index +* for it to come out even approximately correct. Why is this? +*

+*/ + public void setCaretPosition() + { + String searchString = null; + if(mode == NORM) { + return; + } else if(mode == ENTER_TRANS || mode == DO_TRANS) { + searchString = ENTER_TRANS_PHRASE; + } else if(mode == ENTER_NORMALIZED) { + searchString = ENTER_NORMALIZED_PHRASE; + } else if(mode == NEW_TITLE) { + searchString = ENTER_TITLE_PHRASE; + } + if(searchString == null) { System.out.println("Null mode in set Caret Position of TiblEdit!"); return;} + + TextPane tp = tibFrame.getTextPane(); + String text = tp.getText(); + int index = text.indexOf(searchString); + if(index>0) { + tp.setCaretPosition(index); + } + } + + /** + *

+ * This method checks the position of the caret to see if it is an appropriate + * place to perform certain actions depending on the Type parameter supplied. + * The types available are: + *

  • {@link TibConstants#ED_TITLE ED_TITLE} - for adding an edition title. + *
  • {@link TibConstants#AP AP} - for adding variant readings (apparatus). + *
  • {@link TibConstants#TRANS_EDIT TRANS_EDIT} - for editing the translation of a title. + *
+ *

+ */ + public boolean checkCaretPosition(String type) + { + if(elemList == null) {return false;} + element = elemList.getElementAt(tibFrame.getCaretPosition()); + String elemName = new String(); + if(element != null && !element.equals(NO_ELEM)) + { + elemName = element.getName(); + } else { + return false; + } + + + if(type.equals(ED_TITLE)) { + if(elemName.equals(TITLE) + && (element.getAttributeValue(TYPE)==null + || !element.getAttributeValue(TYPE).equalsIgnoreCase(NORM_TITLE))) + { + grandparent = element.getParent().getParent(); + if(grandparent != null) { + if(grandparent.getName().equals(TLIST)) { + doMessage(TLIST_ADD_ERROR); + setSelectedElement(null); + return false; + } + setSelectedElement(element.getParent()); + return true; + } + } else { + setSelectedElement(null); + return false; + } + } else if(type.equals(AP)) { + if(elemName.equals(TITLE)) + { + String titleType = element.getAttributeValue(TYPE); + if(titleType!=null && titleType.equals(NORM_TITLE)) {doMessage(NORM_AP_ERROR);return false;} + String cor = element.getAttributeValue(CORRESP); + if(cor != null && cor.equals(NG)) + { + setSelectedElement(element); + return true; + } + } + } else if(type.equals(AP_CHECK)) { + if(elemName.equals(TITLE)) + { + String cor = element.getAttributeValue(CORRESP); + if(cor != null && cor.equals(NG)) + { + return true; + } + } + } else if(type.equals(TRANS_EDIT)) { + while(elemName != null && (elemName.equals(AP) ||elemName.equals(LM) || elemName.equals(RDG))) { + element = element.getParent(); + elemName = element.getName(); + } + + if(elemName.equals(TITLE)) { + String cor = element.getAttributeValue(CORRESP); + if(cor != null && cor.equals(NG)) + { + child = element.getChild(FOREIGN); + if(child == null) { + child = new org.jdom.Element(FOREIGN); + child.setAttribute(LANG,ENG); + element.addContent(child); + } + setSelectedElement(child); + return true; + } + } else if(elemName.equals(FOREIGN)) { + parent = element.getParent(); + elemName = parent.getName(); + String cor = parent.getAttributeValue(CORRESP); + if(elemName != null && elemName.equals(TITLE) + && cor != null && cor.equals(NG)) + { + setSelectedElement(element); + return true; + } + } + } else if(type.equals(ED_TITLE_REM)) { + if(elemName.equals(TITLE)) { + String cor = element.getAttributeValue(CORRESP); + if(cor != null && !cor.equals(NG)) {return true;} + } + } + + return false; + } + + // Static methods + /** + *

+ * This is a static method to display a {@link javax.swing.JOptionPane} input + * dialog it takes a String array with three specs. + *

  1. the message + *
  2. the title + *
  3. the message type as defined in JOptionPane. + *
+ * The latter spec is converted to an integer. It returns the String + * that was inputed. + *

+ * @param String[] - the specifications for the input dialog + * + * @return String - the string entered by the user. + * + */ + public static String promptInput(String[] specs) + { + return JOptionPane.showInputDialog(null,specs[0],specs[1],Integer.parseInt(specs[2])); + } + + /** + *

+ * A public static method that converts a Vector into an array of Strings. + *

+ * + * @param Vector The vector to be converted. + * + * @return String[] The resulting array of Strings. + */ + public static String[] toStringArray(Vector v) + { + Object[] objs = v.toArray(); + String[] out = new String[objs.length]; + for(int n=0; n + * A public static method that converts an Object array into an array of Strings. + *

+ * + * @param Object[] The object array to be converted. + * + * @return String[] The resulting array of Strings. + */ + public static String[] toStringArray(Object[] objs) + { + String[] out = new String[objs.length]; + for(int n=0; n + * A method for debugging, it takes an {@link org.jdom.Element} and converts it to a + * string, the way it would be viewed in a plain text editor, angle brackets, attributes, and all. + * This is a public, static method that can be called from anywhere with this classes prefix. + *

+ * + * @param org.jdom.Element The element to be turned into a string. + * + * @return String The resulting string version of the element. + */ + public static String outputString(org.jdom.Element e) + { + if(e == null) {return "No element!\n";} + return xop.outputString(e); + } + + + // Constructor + + /** + *

+ * The only constructor takes no arguments and simply calls the {@link #init} method. + *

+ */ + public TiblEdit() + { + init(); + + // this is for the number of the written out file when there is no currentFile defined + // If this is kept (which it probably won't be), it must be recorded upon the + // program closing and read it upon reopening. + outCount = 1; + } + + public static void showSplash() + { + IntroSign is = new IntroSign(); + t = new Thread(is,"intro"); + t.start(); + } + + /** + *

+ * This static method stops the splash screen from displaying by interrupting + * the thread it is on {@link #t} and setting it to null. + *

+ */ + public static void stopSplash() + { + if(t != null) {t.interrupt();t=null;} + } + + public static void main(String[] args) + { + try { + UIManager.setLookAndFeel( + "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Exception e) { + System.err.println("Exception: " + e.getMessage() + "\n" + + e.getClass().getName()); + } + TiblEdit app = new TiblEdit(); + } + + // Listener Methods + + // MouseEvent listener + /** + *

+ * This implementation of the mouse listener checks to make sure the source is + * the {@link TextPane}. Then, it makes sure the {@link #mode} is {@link TibConstants#NORM} + * to make sure action is viable. Thus, it only responds when the TextPane + * is click when nothing else is being inserted etc. It makes sure its a double click + * and there is an {@link ElementList} defined to check. It checks the {@link #elemList} + * for the selected element, if it is a {@link TibConstants#TITLE}, then it calls + * {@link #enterTranslation}. If it is an {@link TibConstants#AP}, then it calls + * {@link #showAp}. + *

+ * + * @param MouseEvent - the required parameter for this abstract method. + */ + public void mouseClicked(MouseEvent me) + { + if(t !=null) stopSplash(); + if(me.getSource() instanceof TextPane) + { + TextPane tp = (TextPane)me.getSource(); + int noc = me.getClickCount(); + int pos = tp.getCaretPosition(); + if(mode == NORM && elemList != null) { + if(noc>1 ) { + setSelectedElement(elemList.getElementAt(pos)); + if(selected_element != null) { + String name = selected_element.getName(); + if(name.equals(TITLE)) { + tp.removeCaretListener(tibFrame); + enterTranslation(); + } else if(name.equals(AP)) { + tp.removeCaretListener(tibFrame); + mode = SHOW_AP; + showApp(); + } + } else { + selected_element = null; + tibFrame.getTextPane().setCaretPosition(pos); + } + } else { + element = elemList.getElementAt(pos); + if(element.getName().equals(AP)) { + getFrame().removeAppItem.setEnabled(true); + } else { + getFrame().removeAppItem.setEnabled(false); + } + } + } else if(mode == CANC) { + mode = NORM; + tibFrame.getTextPane().setCaretPosition(pos); + } + + } + } + + public void mousePressed(MouseEvent me) {} + public void mouseReleased(MouseEvent me) {} + public void mouseEntered(MouseEvent me) {} + public void mouseExited(MouseEvent me) {} + + //Key Event Listner + /** + *

+ * This implementation of the KeyListener interface is used when information + * is being added directly to the {@link TextPane} being displayed. If the + * Enter key is pressed, the it checks the {@link #mode}. If the mode is + * {@link TibConstants#ENTER_TRANS}, then it calls {@link insertTranslation}. + * If the mode is {@link NEW_TITLE}, it calls {@link insertNewTitleAndTranslation}. + *

+ * + * @param KeyEvent - the required parameter for this abstract method. + */ + public void keyPressed(KeyEvent ke) { + if(ke.getKeyCode() == KeyEvent.VK_ENTER) { + int pos = tibFrame.getTextPane().getCaretPosition(); + if(mode == ENTER_TRANS) { + insertTranslation(); + hasBeenSaved = false; + } else if(mode == NEW_TITLE) { + insertNewTitleAndTranslation(); + hasBeenSaved = false; + } else if(mode == ENTER_NORMALIZED) { + updateNormalizedTitle(); + hasBeenSaved = false; + } else if(mode == DO_TRANS) { + updateTranslation(); + hasBeenSaved = false; + } + setMode(NORM); + + tibFrame.getTextPane().setCaretPosition(pos); + } + } + public void keyReleased(KeyEvent ke) {} + public void keyTyped(KeyEvent ke) { + } + + // Observer for TibTable App entries + /** + *

+ * The implementation of the Observer interface is used for listening + * to the {@link TibTable} that displays variant reading information. That table + * is displayed along with a button panel for submitting and canceling. When either + * of those buttons are pressed. The TibTable notifies its observers (the TiblEdit + * controller) with an argument of a Hashtable with keyed specs. + * If the type key equals {@link TibConstants#APP_SUBMIT} then the {@link #doAppSubmission} + * is called with the arguments. If it is {@link TibConstants#CANCEL}, then + * it calls the {@link #showTitles} method with mode {@link TibConstants#CANCEL_NEW_APP}. + *

+ */ + public void update(Observable obs, Object arg) + { + if(obs instanceof TibTable) + { + int pos = tibFrame.getTextPane().getCaretPosition(); + Hashtable args = (Hashtable)arg; + String type = (String)args.get(TYPE); + if(type.equals(APP_SUBMIT)) { + doAppSubmission(args); + hasBeenSaved = false; + } else if(type.equals(CANCEL)) { + if(mode == NEW_AP) {setMode(CANCEL_NEW_APP);} + showTitles(); + } else if(type.equals(REDISPLAY)) { + showApp(); + } + tibFrame.getTextPane().setCaretPosition(pos); + } + } +} + diff --git a/source/org/thdl/tib/bibl/TitleFactory.java b/source/org/thdl/tib/bibl/TitleFactory.java new file mode 100644 index 0000000..9425e16 --- /dev/null +++ b/source/org/thdl/tib/bibl/TitleFactory.java @@ -0,0 +1,406 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import org.jdom.*; +import org.jdom.output.*; + +/** +* The TitleFactory class extends the GenericTibFactory to provide means for locating and manipulating title elements +* within a {@link TibDoc}. +*/ + +public class TitleFactory extends GenericTibFactory implements TibConstants +{ + // Attributes + private org.jdom.Element titlegrp, titleInfo, tdecl, normDecl, normTib, normEng, foreign; + private org.jdom.Element tdiv, pagination, title, element, rs; + private org.jdom.Element sections, num; + private org.jdom.Element[] titles, tdivs, titleLists, titleItems, elements; + private org.jdom.Element[] tibanals, chapters, chapterTitles; + private Hashtable nums; + private String type, subtype, text; + int entryIndex; + private TitleParser titleParser; + + + // Accessors + protected void processDoc() + { + // getting root elements for titles and chapters + titlegrp = tibDoc.findElement(TITLEGRP); + sections = tibDoc.findElement(SECTIONS); + + // setting Normalized title + normDecl = titlegrp.getChild(TDECL); + String normEngText = new String(); + normDecl.removeChildren(FOREIGN); + normTib = normDecl.getChild(TITLE); + if(normTib == null) { + System.out.println("No title element found in normalized title decl!"); + System.out.println("Decl: " + TiblEdit.outputString(normDecl)); + return; + } + String lang = normTib.getAttributeValue(LANG); + if(lang == null || !lang.equals(TIB)) { + System.out.println("The first title element in Normalized title decl is not a Tib title!"); + System.out.println("Lang: " + lang); + System.out.println("Title: " + TiblEdit.outputString(normTib)); + } + foreign = normTib.getChild(FOREIGN); + if(foreign == null) { + foreign = new org.jdom.Element(FOREIGN); + foreign.setAttribute(LANG,ENG); + normTib.addContent(foreign); + } + + children = normDecl.getChildren(TITLE); + if (children.size()>1) { + it = children.iterator(); + while(it.hasNext()) { + element = (org.jdom.Element)it.next(); + if(element.getAttributeValue(LANG).equalsIgnoreCase(ENG)) { + foreign.setText(element.getText()); + element.detach(); + normEng = foreign; + } + } + + } + + normTib.setAttribute(CORRESP,NG); + + element = normTib.getChild(TITLE); + + if(element != null && (foreign.getText() == null || foreign.getText().trim().equals(""))) + { + foreign.setText(element.getText()); + element.detach(); + } + // Setting title info + titleInfo = titlegrp.getChild(TINFO); + tdivs = tibDoc.toElementArray(titleInfo.getChildren(TDIV)); + for(int n=0;n1) + { + outStyles.add(new ElementStyle(tibDoc.cleanString(foreign.getText())+"\n", TextPane.REG, foreign)); + } + List discList = el.getParent().getChildren(DISC); // Get Discussion element if there + org.jdom.Element disc, discItem; + disc = null; + for(Iterator it=discList.iterator();it.hasNext();) { + discItem = (org.jdom.Element)it.next(); + String type = discItem.getAttributeValue(TYPE); + if(type.equals(BRIEF) || type.equals(FULL)) { + disc = discItem; + break; + } + } + + List titleChilds = el.getParent().getChildren(TITLE); // Get all the title children + if(titleChilds != null && titleChilds.size()>0 && + el.equals((org.jdom.Element)titleChilds.get(titleChilds.size()-1))) { + if(disc!=null && disc.getText()!=null && + disc.getText().trim().length()>1) { + outStyles.add(new ElementStyle("Show Discussion\n", TextPane.RED, disc)); + } + } + } + + // Public Helpers + + public java.util.Collection getAllTitles() + { + outStyles = new Vector(); + + doNormalizedTitle(); + doTitleLine(); + doEOCtitles(); + doClosingTitles(); + doNonTibetan(); + doChapters(); + + return ((java.util.Collection)outStyles); + } + + // Constructor + protected TitleFactory(TibDoc td) + { + super(td); + } +} diff --git a/source/org/thdl/tib/bibl/TitleParser.java b/source/org/thdl/tib/bibl/TitleParser.java new file mode 100644 index 0000000..3a76790 --- /dev/null +++ b/source/org/thdl/tib/bibl/TitleParser.java @@ -0,0 +1,352 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import org.jdom.*; +import org.jdom.input.*; +import org.jdom.output.*; + +/** +* +* This class provides the mechanism to "parse" a Tibbibl title tag and understand its contents. Some title tags +* will contain AP children that represent variant readings. TitleParser can among other things supply the text +* of the main readings in the title, weeding out the alternative one. +*/ + +public class TitleParser implements TibConstants +{ + Object item; + String stringItem, outText, titleText; + org.jdom.Element title, foreign, contentItem; + org.jdom.Text textItem; + Vector parts, styleElements, toRemove; + + private void clean() + { + /** + *

+ * This method cleans the title element of consequetive Text elements so + * that the {@link #isAppInsertable} method will not mistakenly think that + * an app cannot be inserted since it crosses a part boundary. The two consequetive + * jdom.org.Text elements will be combined and the second one removed. + *

+ */ + org.jdom.Text lastText, textElement; + Iterator it = title.getContent().iterator(); + Vector toRemove = new Vector(); + lastText = null; + while(it.hasNext()) + { + Object item = it.next(); + if(item instanceof org.jdom.Text) { + if(lastText == null) { + lastText = (org.jdom.Text)item; + } else { + String lastTextString = lastText.getText(); + textElement = (org.jdom.Text)item; + String thisTextString = textElement.getText(); + if(!lastTextString.endsWith(" ") && + !thisTextString.startsWith(" ")) + { + thisTextString += " "; + } + lastText.setText(lastTextString + thisTextString); + toRemove.add(item); + } + } else { + lastText = null; + } + } + for(it = toRemove.iterator(); it.hasNext();) + { + title.getContent().remove(it.next()); + } + } + + private void parse() + { + /** + *

+ * This method parses the title by finding its constituent parts and creating + * a {@link TitleParser.TitlePart} out of them and adding each TitlePart to + * the vector {@link #parts}. The title parts contain the text for display, its + * beginning and end indexes, and the corresponding JDOM part, whether it be + * an element, text, or string. + *

+ */ + parts = new Vector(); + outText = new String(); + Iterator it = title.getContent().iterator(); + TitlePart prevPart = null; + + while(it.hasNext()) + { + boolean isApp = false; + item = it.next(); + String stringItem = new String(); + if(item instanceof org.jdom.Element) { + contentItem = (org.jdom.Element)item; + if(contentItem.getName().equals(AP)) { + stringItem = cleanString(contentItem.getChild(LM).getText()); + isApp = true; + } else if(contentItem.getName().equals(FOREIGN)) { + foreign = contentItem; + continue; + } else { + stringItem = cleanString(contentItem.getText()); + System.out.println("Found an inner element that's not ap or foreign: " + contentItem.toString()); + } + } else if(item instanceof org.jdom.Text) { + textItem = (org.jdom.Text)item; + stringItem = cleanString(textItem.getText()); + } else if(item instanceof String) { + stringItem = cleanString((String)item); + } else { + System.out.println("A kind of title content found that is not recognized!\n" + + item.toString()); + continue; + } + + if(!outText.endsWith(" ") && !stringItem.startsWith(" ")) { + if(isApp) { + TitlePart tpart = (TitlePart)parts.lastElement(); + tpart.addSpace(); + outText += " "; + } else { + stringItem = " " + stringItem; + } + } + int start = outText.length()+1; + outText += stringItem; + parts.add(new TitlePart(stringItem,start,item,isApp)); + prevPart = (TitlePart)parts.lastElement(); + } + + titleText = cleanString(outText); + } + + private void setStyles() + { + ElementStyle es; + styleElements = new Vector(); + + Iterator it = parts.iterator(); + while(it.hasNext()) + { + es = null; + TitlePart tpart = (TitlePart)it.next(); + String text = tpart.text; + if(tpart.isApp) { + org.jdom.Element e = (org.jdom.Element)tpart.associatedItem; + es = new ElementStyle(text,TextPane.VARIANT,e); + } else { + es = new ElementStyle(text,TextPane.REG,title); + } + styleElements.add(es); + } + if(styleElements.size()>0) { + try { + es = (ElementStyle)styleElements.firstElement(); + if(es.getText().equals(" ")) {styleElements.remove(es);} + es = (ElementStyle)styleElements.lastElement(); + if(es.getText().equals(" ")) {styleElements.remove(es);} + } catch (NoSuchElementException nsee) {} + } + } + + public void setTitle(org.jdom.Element ttl) + { + title = ttl; + parse(); + setStyles(); + } + + public org.jdom.Element getTitle() + { + return title; + } + + public String getTitleText() + { + return titleText; + } + + public org.jdom.Element getTranslation() + { + return foreign; + } + + public Vector getStyles() + { + if(styleElements.size()==0) { + styleElements.add(new ElementStyle("",TextPane.REG,title)); + } + return styleElements; + } + +/** +*

+* This method checks the parts of the title to see if an app (or apparatus) element is insertable. The +* main thing it checks for is that the range of text does not span over an already existing app. +*

+* +* @param startInsert the insertion point within the display of the titles text relative to the beginning of the line. +* +* @param txt the selected text which is to be marked up with the app. This is necessary to make sure that +* the text does not fall completely within an already existing app. +* +* @return boolean - whether or not this is an acceptable place to insert an app element. +*/ + public boolean isAppInsertable(int startInsert, String txt) + { + + if(parts == null) {return false;} + Iterator it = parts.iterator(); + while(it.hasNext()) + { + TitlePart tpart = (TitlePart)it.next(); + + int tpStart = tpart.start; + int tpEnd = tpart.end; + if(startInsert>=tpStart && startInsert-1 || tpart.text.equals(txt)) { + return true; + } else { + TitlePart oldtp = tpart; + String backText = tpart.text; + tpart = (TitlePart)it.next(); + if(tpart.isApp) {return false;} + backText += tpart.text; + if(backText.indexOf(txt)>-1) { + System.out.println("Found a text run that crosses boundaries of a non-app elements!\n"); + System.out.println("Firs element: " + oldtp.associatedItem.toString()); + System.out.println("Second element: " + tpart.associatedItem.toString()); + } + } + } + } + return false; + } + + public Object getItemAt(int ind) + { + if(parts == null) {return null;} + Iterator it = parts.iterator(); + while(it.hasNext()) + { + TitlePart tpart = (TitlePart)it.next(); + int tpStart = tpart.start; + int tpEnd = tpart.end; + if(ind>=tpStart && ind=tpStart && ind +* This extension of {@link TibAction} is for View menu actions.Its constructor takes a String name and a TibFrame parent. With these it calls its +* super constructor. The action performed takes the following action commands: +*

+*
    +*
  • {@link TibConstants.MASTER_ID_VIEW MASTER_ID_VIEW} - calls {@link TiblEdit#showMasterDox()} +*
  • {@link TibConstants.USER_ID_VIEW USER_ID_VIEW} - calls {@link TiblEdit#getEditorInfo()} +*
  • {@link TibConstants.ABOUT ABOUT} - calls {@link TiblEdit#showSplash()} +*
+*/ + +public class ViewAction extends TibAction +{ + + public ViewAction(String name, TibFrame f) + { + super(name,f); + } + + public void actionPerformed(ActionEvent e) + { + String command = e.getActionCommand(); + if(command.equals(MASTER_ID_VIEW)) + { + getController().showMasterDox(); + } else if(command.equals(USER_ID_VIEW)) + { + getController().getEditorInfo(); + } else if(command.equals(ABOUT)) + { + getController().showSplash(); + } + } +} diff --git a/source/org/thdl/tib/bibl/XMLDoc.java b/source/org/thdl/tib/bibl/XMLDoc.java new file mode 100644 index 0000000..00ed4d4 --- /dev/null +++ b/source/org/thdl/tib/bibl/XMLDoc.java @@ -0,0 +1,251 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.util.*; +import org.jdom.*; +import org.jdom.input.*; +import org.jdom.output.*; + +/** +* This class extends org.jdom.Document to provide added XML functionality, such as locating specific elements. +* Some of its methods are specific to the TIBBIBL DTD, others are more general in function. XMLDoc is in turn +* extended by {@link TibDoc}, which adds more specific functionality and is the class used in the TiblEdit program. +* This class needs to be cleaned up so that only the most general XML functions remain and the functions that are +* specific to our DTD are relegated to TibDoc. +*/ + +public class XMLDoc extends org.jdom.Document implements TibConstants +{ + // Attributes + private org.jdom.Element root, sysid, temp; + private org.jdom.Attribute id; + private Vector tagList = new Vector(100); + + private String editorId, editorsName; + + private org.jdom.output.XMLOutputter xop = new org.jdom.output.XMLOutputter(); + + // Accessors + + public void setRoot() + { + root = getRootElement(); + id = root.getAttribute(ID); + if(id == null) { + id = new org.jdom.Attribute(ID,""); + root.setAttribute(id); + } + } + + public org.jdom.Element getRoot() + { + return root; + } + + public void setID(String id) + { + this.id.setValue(id); + } + + public String getID() + { + return (String)id.getValue(); + } + + public void setSysid(String sysidString) + { + sysid = getSysid(); + if(sysid == null) { + temp = findElement(CONTROL); + sysid = new org.jdom.Element(SID); + temp.getChildren().add(0,sysid); + } + sysid.setText(sysidString); + } + + public org.jdom.Element getSysid() + { + return findElement(SID); + } + + public org.jdom.Element[] getTagList() + { + refreshTagList(); + Object[] tempList = tagList.toArray(); + org.jdom.Element[] elList = new org.jdom.Element[tempList.length]; + for(int c=0; c +* This returns the id string for the editor currently set for this document. This ID string +* is the same as the editor's initials referred to elsewhere, e.g ndg, gah... +*

+* +* @return String - the editor's id string generally 3 letters long +*/ + public String getEditorID() + { + return editorId; + } + + public String getEditorName() + { + return editorsName; + } + + // Helper + + public void processDoc(org.jdom.Element element) + { + String elemName = element.getName(); + tagList.add(element); + Iterator child = element.getChildren().iterator(); + while(child.hasNext()) + processDoc((Element)child.next()); + } + + public org.jdom.Element findID(String fid) + { + refreshTagList(); + Iterator elList = tagList.iterator(); + org.jdom.Element item; + + while(elList.hasNext()) + { + item = (org.jdom.Element)elList.next(); + String itid = item.getAttributeValue(ID); + if(itid == fid) {return item;} + } + + return null; + } + + static public org.jdom.Element getAncestor(String elName, org.jdom.Element child) + { + org.jdom.Element retElem = child.getParent(); + while(retElem != null) { + if(retElem.getName().equals(elName)) { + return retElem; + } + retElem = retElem.getParent(); + } + return null; + } + + + public org.jdom.Element findElement(String elName) + { + refreshTagList(); + Iterator elList = tagList.iterator(); + org.jdom.Element item; + + while(elList.hasNext()) + { + item = (org.jdom.Element)elList.next(); + if(item.getName().equalsIgnoreCase(elName)) {return item;} + } + + return null; + } + + public org.jdom.Element findElement(String elName, String att, String val) + { + if(elName == null || att == null || val == null) {return null;} + refreshTagList(); + org.jdom.Element[] elList = findElements(elName); + + for(int c=0; c-1) + { + anElement = (org.jdom.Element)item; + String elementName = anElement.getName(); + if(elementName.equals(elName)) + { + finds.add(anElement); + } + } + } + + return TibDoc.toElementArray(finds); + } + + public org.jdom.Element[] findElements(String att, String val) + { + if(att == null) {return null;} + Vector finds = new Vector(20); + refreshTagList(); + for(Iterator it = tagList.iterator();it.hasNext();) + { + org.jdom.Element el = (org.jdom.Element)it.next(); + String attVal = el.getAttributeValue(att); + if((attVal != null && attVal.equals(val)) || (val == null && attVal == null)) { + finds.add(el); + } + } + return TibDoc.toElementArray(finds); + } + + public void refreshTagList() + { + tagList = new Vector(100); + processDoc(getRoot()); + } + + // Constructor + + public XMLDoc(org.jdom.Element rootElement) + { + super(rootElement); + setRoot(); + processDoc(getRoot()); + } +} diff --git a/source/org/thdl/tib/bibl/XMLFilter.java b/source/org/thdl/tib/bibl/XMLFilter.java new file mode 100644 index 0000000..e3a5cba --- /dev/null +++ b/source/org/thdl/tib/bibl/XMLFilter.java @@ -0,0 +1,72 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.io.File; +import javax.swing.*; +import javax.swing.filechooser.*; +//import org.thdl.tib.bibl.shared.*; + +/** +* XMLFilter extends java.io.FileFilter to display only XML files in the open filechooser window. +*/ + +public class XMLFilter extends FileFilter { + + public final static String xml = "xml"; + + // Accept all directories and all xml files. + + public boolean accept(File f) + { + if (f.isDirectory()) { + return true; + } + + String extension = getExtension(f); + if (extension != null && extension.equals(xml)) + { + return true; + } + else + { + return false; + } + } + + public String getDescription() + { + return "XML files only"; + } + + /* + * Get the extension of a file. + */ + + public static String getExtension(File f) { + String ext = null; + String s = f.getName(); + int i = s.lastIndexOf('.'); + + if (i > 0 && i < s.length() - 1) { + ext = s.substring(i+1).toLowerCase(); + } + return ext; + } +} diff --git a/source/org/thdl/tib/bibl/XMLReader.java b/source/org/thdl/tib/bibl/XMLReader.java new file mode 100644 index 0000000..0d12d9e --- /dev/null +++ b/source/org/thdl/tib/bibl/XMLReader.java @@ -0,0 +1,124 @@ +/* +The contents of this file are subject to the THDL Open Community License +Version 1.0 (the "License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License on the THDL web site +(http://www.thdl.org/). + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +License for the specific terms governing rights and limitations under the +License. + +The Initial Developer of this software is the Tibetan and Himalayan Digital +Library (THDL). Portions created by the THDL are Copyright 2001-2003 THDL. +All Rights Reserved. + +Contributor(s): ______________________________________. +*/ + +package org.thdl.tib.bibl; + +import java.io.*; +import java.util.*; +import javax.swing.*; +import javax.swing.filechooser.*; +import org.jdom.*; +import org.jdom.input.*; +import org.jdom.output.*; +import org.xml.sax.*; +//import org.thdl.tib.bibl.shared.*; + +/** +* This class reads in an XML file using the SAXBuilder in org.jdom.input. +*/ + +public class XMLReader extends Observable implements TibConstants +{ + // Attributes + private org.jdom.Element root; + private TibDoc doc; + private String docName; + private String error; + + public boolean setDoc(File file) + { + boolean ok = true; + if(file == null) {return false;} + String fn = file.getName(); + + if(fn.indexOf(".xml")>-1) { + + try { + + SAXBuilder builder = new SAXBuilder(false); + builder.setEntityResolver(new TibDTDResolver()); + root = builder.build(file).getRootElement().detach(); + //System.out.println(xop.outputString(root)); + //setChanged(); + //notifyObservers(); + error = ""; + + } catch (JDOMException e) { + + e.printStackTrace(); + System.out.println("JDOM Exception thrown and caught! " + e.getMessage()); + error = e.getMessage(); + ok = false; + } + + } else { + ok = false; + } + + return ok; + } + + public org.jdom.Element getRoot() + { + return root; + } + + public TibDoc getDoc() + { + doc = new TibDoc(root); + return doc; + } + + public org.jdom.Document getJDOMDoc() + { + org.jdom.Document jdomDoc = new org.jdom.Document(root); + return jdomDoc; + } + + public void setDocName(String name) + { + docName = name; + } + + public String getDocName() + { + return docName; + } + + public String getError() + { + return error; + } + + // Helper Methods + + + + // Constructor + public XMLReader(File f) + { + setDoc(f); + } + + public XMLReader() + { + doc = null; + docName = null; + error = null; + } +}