diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/GUI/newSuggestionForm.form b/src/main/java/org/humanistika/oxygen/tei/completer/GUI/newSuggestionForm.form
new file mode 100644
index 0000000..6eb0d5d
--- /dev/null
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/GUI/newSuggestionForm.form
@@ -0,0 +1,179 @@
+
+
+
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/GUI/newSuggestionForm.java b/src/main/java/org/humanistika/oxygen/tei/completer/GUI/newSuggestionForm.java
new file mode 100644
index 0000000..fef672b
--- /dev/null
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/GUI/newSuggestionForm.java
@@ -0,0 +1,396 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/GUIForms/JDialog.java to edit this template
+ */
+package org.humanistika.oxygen.tei.completer.GUI;
+
+import org.humanistika.oxygen.tei.completer.SuggestedAutocomplete;
+import org.humanistika.oxygen.tei.completer.TeiCompleter;
+import org.humanistika.oxygen.tei.completer.configuration.beans.AutoComplete;
+import org.jetbrains.annotations.Nullable;
+import ro.sync.contentcompletion.xml.CIValue;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.table.DefaultTableModel;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ *
+ * @author younes
+ */
+public class newSuggestionForm extends javax.swing.JDialog {
+ private TeiCompleter teiCompleter;
+ private SuggestedAutocomplete suggestedAutocomplete = null;
+
+ private ArrayList results = new ArrayList<>();
+
+ /**
+ * Creates new form JDialogForm
+ */
+ public newSuggestionForm(java.awt.Frame parent, final TeiCompleter teiCompleter) {
+ super(parent, ModalityType.DOCUMENT_MODAL);
+ this.teiCompleter = teiCompleter;
+ initComponents();
+ customLabels();
+ }
+
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ cancleJButton = new javax.swing.JButton();
+ jLabel1 = new javax.swing.JLabel();
+ dependentJLabel = new javax.swing.JLabel();
+ dependentJTextField = new javax.swing.JTextField();
+ selectionJLabel = new javax.swing.JLabel();
+ selectionJTextField = new javax.swing.JTextField();
+ fetchjButton = new javax.swing.JButton();
+ jScrollPane2 = new javax.swing.JScrollPane();
+ restultsJTable = new javax.swing.JTable();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("Custom lookup");
+ cancleJButton.setText("Cancel");
+ cancleJButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cancleJButtonActionPerformed(evt);
+ }
+ });
+
+ jLabel1.setFont(new java.awt.Font("Segoe UI", 0, 18)); // NOI18N
+ jLabel1.setText("Custom lookup");
+
+ dependentJLabel.setText("Dependent:");
+ dependentJLabel.setToolTipText("");
+
+ dependentJTextField.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ dependentJTextFieldActionPerformed(evt);
+ }
+ });
+
+ selectionJLabel.setText("Selection:");
+
+ fetchjButton.setText("Search...");
+ fetchjButton.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ fetchjButtonActionPerformed(evt);
+ }
+ });
+
+ restultsJTable.setModel(new javax.swing.table.DefaultTableModel(
+ new Object [][] {
+ },
+ new String [] {
+ "Value", "Description"
+ }
+ ) {
+ Class[] types = new Class [] {
+ java.lang.String.class, java.lang.String.class
+ };
+ boolean[] canEdit = new boolean [] {
+ false, false
+ };
+
+ public Class getColumnClass(int columnIndex) {
+ return types [columnIndex];
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return canEdit [columnIndex];
+ }
+ });
+ restultsJTable.setColumnSelectionAllowed(true);
+ restultsJTable.addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mousePressed(java.awt.event.MouseEvent evt) {
+ restultsJTableMousePressed(evt);
+ }
+ });
+ jScrollPane2.setViewportView(restultsJTable);
+ restultsJTable.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
+
+ restultsJTable.setCellSelectionEnabled(false);
+ restultsJTable.setRowSelectionAllowed(true);
+
+ restultsJTable.getColumnModel().getColumn(0).setPreferredWidth(120);
+ restultsJTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGap(0, 0, Short.MAX_VALUE)
+ .addComponent(cancleJButton))
+ .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 460, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(jLabel1)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(6, 6, 6)
+ .addComponent(dependentJLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(dependentJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGroup(layout.createSequentialGroup()
+ .addGap(16, 16, 16)
+ .addComponent(selectionJLabel)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(selectionJTextField))
+ .addComponent(fetchjButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 92, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(0, 0, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(jLabel1)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(dependentJLabel)
+ .addComponent(dependentJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(selectionJLabel)
+ .addComponent(selectionJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addGap(8, 8, 8)
+ .addComponent(fetchjButton)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 307, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cancleJButton)
+ .addContainerGap())
+ );
+
+ selectionJTextField.getDocument().addDocumentListener(new DocumentListener() {
+ public void insertUpdate(DocumentEvent e) {
+ textChanged();
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ textChanged();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+
+ }
+ });
+
+ dependentJTextField.getDocument().addDocumentListener(new DocumentListener() {
+ public void insertUpdate(DocumentEvent e) {
+ textChanged();
+ }
+
+ public void removeUpdate(DocumentEvent e) {
+ textChanged();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+
+ }
+ });
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void cancleJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancleJButtonActionPerformed
+ // TODO add your handling code here:
+ this.suggestedAutocomplete = null;
+ dispose();
+ }//GEN-LAST:event_cancleJButtonActionPerformed
+
+ private void dependentJTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dependentJTextFieldActionPerformed
+ // TODO add your handling code here:
+ }//GEN-LAST:event_dependentJTextFieldActionPerformed
+
+ private void fetchjButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fetchjButtonActionPerformed
+ // TODO add your handling code here:
+
+ String selection = selectionJTextField.getText();
+ String dependent = dependentJTextField.getText();
+
+ // get the auto complete suggestions based on the user input
+ final List suggestions = new ArrayList<>();
+
+ for (final AutoComplete autoComplete : teiCompleter.getConfiguration().getAutoCompletes()) {
+ suggestions.addAll(teiCompleter.requestAutoComplete(autoComplete, selection, dependent));
+ }
+
+ //get the model to populate the table
+ DefaultTableModel model = (DefaultTableModel) restultsJTable.getModel();
+
+ for(int i= 0;i< suggestions.size();i++) {
+ results.add(new SuggestedAutocomplete(suggestions.get(i).getValue(), suggestions.get(i).getAnnotation(), new ArrayList<>()));
+ model.addRow(new Object[]{suggestions.get(i).getValue(), suggestions.get(i).getAnnotation()});
+ }
+
+ }//GEN-LAST:event_fetchjButtonActionPerformed
+
+ private void restultsJTableMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_restultsJTableMousePressed
+ // TODO add your handling code here:
+ JTable table =(JTable) evt.getSource();
+ Point point = evt.getPoint();
+ int row = table.rowAtPoint(point);
+ if (evt.getClickCount() == 2 && table.getSelectedRow() != -1) {
+ // your valueChanged overridden method
+ suggestedAutocomplete = results.get(row);
+ dispose();
+ }
+
+ }//GEN-LAST:event_restultsJTableMousePressed
+
+// /**
+// * @param args the command line arguments
+// */
+// public static void main(String args[]) {
+// /* Set the Nimbus look and feel */
+// //
+// /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
+// * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
+// */
+// try {
+// for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
+// if ("Nimbus".equals(info.getName())) {
+// javax.swing.UIManager.setLookAndFeel(info.getClassName());
+// break;
+// }
+// }
+// } catch (ClassNotFoundException ex) {
+// java.util.logging.Logger.getLogger(JDialogForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+// } catch (InstantiationException ex) {
+// java.util.logging.Logger.getLogger(JDialogForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+// } catch (IllegalAccessException ex) {
+// java.util.logging.Logger.getLogger(JDialogForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+// } catch (javax.swing.UnsupportedLookAndFeelException ex) {
+// java.util.logging.Logger.getLogger(JDialogForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+// }
+// //
+//
+// /* Create and display the dialog */
+// java.awt.EventQueue.invokeLater(new Runnable() {
+// public void run() {
+// newSuggestionForm dialog = new newSuggestionForm(new javax.swing.JFrame(), true);
+// dialog.addWindowListener(new java.awt.event.WindowAdapter() {
+// @Override
+// public void windowClosing(java.awt.event.WindowEvent e) {
+// System.exit(0);
+// }
+// });
+// dialog.setVisible(true);
+// }
+// });
+// }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton cancleJButton;
+ private javax.swing.JTextField dependentJTextField;
+ private javax.swing.JButton fetchjButton;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JScrollPane jScrollPane2;
+ private javax.swing.JTable restultsJTable;
+ private javax.swing.JLabel selectionJLabel;
+ private javax.swing.JLabel dependentJLabel;
+ private javax.swing.JTextField selectionJTextField;
+ // End of variables declaration//GEN-END:variables
+
+ private AtomicBoolean runningState = new AtomicBoolean(false);
+
+ private void textChanged() {
+
+ // GATE Keeper
+ // reject if either fields have less than 4 chars
+ // this correspond to requestAutoComplete function as well
+ //TODO USE a constant for this value
+ if(selectionJTextField.getText().length() < 4) return;
+ if(dependentJTextField.getText().length() < 4) return;
+
+ // if we are already fetching results no need to do it again
+ if(runningState.compareAndSet(false, true)) {
+ //No SwingWorker is running.
+ //Create and start swing worker.
+ LiveAutoComplete live = new LiveAutoComplete();
+ live.execute();
+ }
+ }
+
+ @Nullable
+ public SuggestedAutocomplete getSuggestedAutocomplete() {
+ return suggestedAutocomplete;
+ }
+
+ private void customLabels() {
+ dependentJLabel.setText(this.teiCompleter.getConfiguration().getAutoCompletes().get(0).getDependent().getLabel() + ":");
+ selectionJLabel.setText(this.teiCompleter.getConfiguration().getAutoCompletes().get(0).getSelection().getLabel() + ":");
+ }
+
+ public class LiveAutoComplete extends SwingWorker {
+ List suggestions = new ArrayList<>();
+ String selection;
+ String dependent;
+ @Override
+ protected Object doInBackground() throws Exception {
+
+ DefaultTableModel model = (DefaultTableModel) restultsJTable.getModel();
+ // clear the old results
+ for(int i =0; i < model.getRowCount(); i++) {
+ model.removeRow(i);
+ }
+
+ // Introduce a delay of 300 milliseconds
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ // Handle interruption if necessary
+ }
+
+ // get the text field values after the cooldown
+ selection = selectionJTextField.getText();
+ dependent = dependentJTextField.getText();
+
+ // get the auto complete suggestions based on the user input
+ final List suggestions = new ArrayList<>();
+
+ for (final AutoComplete autoComplete : teiCompleter.getConfiguration().getAutoCompletes()) {
+ suggestions.addAll(teiCompleter.requestAutoComplete(autoComplete, selection, dependent));
+ }
+
+ this.suggestions.addAll(suggestions);
+
+ return null;
+ }
+
+ @Override
+ protected void done() {
+ // Update UI on EDT when the task is complete
+ DefaultTableModel model = (DefaultTableModel) restultsJTable.getModel();
+
+ //populate with the new results
+ for(int i= 0;i< suggestions.size();i++) {
+ results.add(new SuggestedAutocomplete(suggestions.get(i).getValue(), suggestions.get(i).getAnnotation(), new ArrayList<>()));
+ model.addRow(new Object[]{suggestions.get(i).getValue(), suggestions.get(i).getAnnotation()});
+ System.out.println(suggestions.get(i).getAnnotation());
+ }
+
+ if(suggestions.size() == 0) {
+ model.addRow(new Object[]{"No results Matching " + dependent + "+" + selection , ""});
+ }
+
+ runningState.set(false);
+ }
+ }
+}
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/SuggestedAutocomplete.java b/src/main/java/org/humanistika/oxygen/tei/completer/SuggestedAutocomplete.java
new file mode 100644
index 0000000..9c34b0d
--- /dev/null
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/SuggestedAutocomplete.java
@@ -0,0 +1,52 @@
+package org.humanistika.oxygen.tei.completer;
+
+
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public class SuggestedAutocomplete {
+
+ public static class UserValue {
+ private final String name;
+ private final String value;
+
+ public UserValue(final String name, final String value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getValue() {
+ return value;
+ }
+ }
+
+ private final String suggestion;
+ @Nullable
+ private final String description;
+ @Nullable private final List userValues;
+
+ public SuggestedAutocomplete(final String suggestion, final String description, final List userValues) {
+ this.suggestion = suggestion;
+ this.description = description;
+ this.userValues = userValues;
+ }
+
+ public String getSuggestion() {
+ return suggestion;
+ }
+
+ @Nullable
+ public String getDescription() {
+ return description;
+ }
+
+ @Nullable
+ public List getUserValues() {
+ return userValues;
+ }
+}
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/TeiCompleter.java b/src/main/java/org/humanistika/oxygen/tei/completer/TeiCompleter.java
index 7bd5ba7..3b616e5 100755
--- a/src/main/java/org/humanistika/oxygen/tei/completer/TeiCompleter.java
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/TeiCompleter.java
@@ -25,6 +25,7 @@
import org.humanistika.ns.tei_completer.Suggestion;
import org.humanistika.ns.tei_completer.Suggestions;
+import org.humanistika.oxygen.tei.completer.GUI.newSuggestionForm;
import org.humanistika.oxygen.tei.completer.configuration.beans.Authentication;
import org.humanistika.oxygen.tei.completer.configuration.beans.AutoComplete;
import org.humanistika.oxygen.tei.completer.configuration.Configuration;
@@ -35,6 +36,7 @@
import org.humanistika.oxygen.tei.completer.remote.ClientFactory.AuthenticationType;
import org.humanistika.oxygen.tei.completer.remote.impl.JerseyClientFactory;
import javax.annotation.Nullable;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
@@ -50,6 +52,10 @@
import static org.humanistika.oxygen.tei.completer.XPathUtil.isSubset;
import static org.humanistika.oxygen.tei.completer.XPathUtil.parseXPath;
+
+import java.awt.*;
+import java.util.List;
+
/**
* TEI-Completer
*
@@ -87,6 +93,11 @@ public List filterAttributeValues(final List list, final WhatP
if(autoCompleteSuggestions != null) {
list.addAll(autoCompleteSuggestions.getSuggestions());
}
+ if(autoCompleteSuggestions != null && autoCompleteSuggestions.getSuggestions().size() == 0) {
+ // the value needs to be prefixed with a space character to bump it to the top of the list
+ list.add(new CustomCIValue(" Custom Entry...", this));
+ }
+
}
return list;
}
@@ -102,7 +113,13 @@ public List filterAttributeValues(final List list, final WhatP
protected final AutoCompleteSuggestions getAutoCompleteSuggestions(final WhatPossibleValuesHasAttributeContext context) {
final String elemXPath = context.computeContextXPathExpression();
final String attrXPath = elemXPath + "/@" + context.getAttributeName();
- final Expr attributeExpr = parseXPath(attrXPath);
+ Expr attributeExpr;
+ try {
+ attributeExpr = parseXPath(attrXPath);
+ } catch (Exception e) {
+ return null;
+ }
+
for (final AutoComplete autoComplete : getConfiguration().getAutoCompletes()) {
final AutoCompleteXPaths autoCompleteXPaths = getXPaths(autoComplete);
@@ -130,19 +147,24 @@ protected final AutoCompleteSuggestions getAutoCompleteSuggestions
return null;
}
- protected List requestAutoComplete(final AutoComplete autoComplete, final String selection, @Nullable final String dependent) {
+ public List requestAutoComplete(final AutoComplete autoComplete, final String selection, @Nullable final String dependent) {
final Authentication.AuthenticationType authenticationType = autoComplete.getRequestInfo().getAuthentication() == null ? null : autoComplete.getRequestInfo().getAuthentication().getAuthenticationType();
- final Suggestions suggestions = getClient(authenticationType).getSuggestions(autoComplete.getRequestInfo(), selection, dependent, autoComplete.getResponseAction());
- final List results = new ArrayList<>();
- for(final Suggestion suggestion : suggestions.getSuggestion()) {
- results.add(new CIValue(suggestion.getValue(), suggestion.getDescription()));
+ //TODO USE a constant for this value
+ if(selection.length() > 3 && dependent.length() > 3) {
+ final Suggestions suggestions = getClient(authenticationType).getSuggestions(autoComplete.getRequestInfo(), selection, dependent, autoComplete.getResponseAction());
+ final List results = new ArrayList<>();
+ for(final Suggestion suggestion : suggestions.getSuggestion()) {
+ results.add(new CIValue(suggestion.getValue(), suggestion.getDescription()));
+ }
+ return results;
}
- return results;
+ return Collections.emptyList();
//TODO(AR) consider some visual warnings/errors in Oxygen such as JOptionPane.showMessageDialog(KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(), "some error message here");
}
- protected Configuration extends AutoComplete> getConfiguration() {
+
+ public Configuration extends AutoComplete> getConfiguration() {
if(configuration == null) {
synchronized(this) {
if(configuration == null) {
@@ -304,7 +326,7 @@ protected String getDependent(final Context context, final String elemXPath, fin
}
private String getAutoCompleteSelectionXPath(final String elemXPath, final AutoComplete autoComplete) {
- return elemXPath + "/" + autoComplete.getSelection();
+ return elemXPath + "/" + autoComplete.getSelection().getDefault();
}
private String getAutoCompleteDependentXPath(final String elemXPath, final Dependent dependent) {
@@ -374,4 +396,63 @@ public List filterAttributes(final List list, final Wh
public List filterElementValues(final List list, final Context context) {
return list;
}
+
+
+ /**
+ * A CIValue labelled "Add New..." which
+ * prompts the user to enter a new suggestion
+ * via a dialog box
+ */
+ public class CustomCIValue extends CIValue {
+ private TeiCompleter teiCompleter;
+ private String suggestion;
+ public CustomCIValue(String s, final TeiCompleter teiCompleter) {
+ super(s);
+ this.teiCompleter = teiCompleter;
+ }
+
+ @Override
+ public String getInsertString() {
+ if(suggestion == null) {
+ //Ask the user for an autocomplete dependent and selection
+ final SuggestedAutocomplete suggestedAutocomplete = promptUserForNewSuggestion();
+ suggestion = suggestedAutocomplete.getSuggestion();
+ }
+
+ return suggestion;
+ }
+
+ private SuggestedAutocomplete promptUserForNewSuggestion() {
+ final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ final Component comp = keyboardFocusManager.getFocusOwner();
+ final Frame parentFrame = getParentFrame(comp);
+ final newSuggestionForm newSuggestionForm = new newSuggestionForm(parentFrame, teiCompleter);
+
+
+
+ //display the dialog
+ newSuggestionForm.setLocationRelativeTo(parentFrame);
+ newSuggestionForm.setVisible(true);
+ final SuggestedAutocomplete suggestedAutocomplete = newSuggestionForm.getSuggestedAutocomplete();
+ newSuggestionForm.dispose();
+ return suggestedAutocomplete;
+ }
+
+ private Frame getParentFrame(final Component component) {
+ if(component == null) {
+ return null;
+ }
+
+ final Component parent = component.getParent();
+ if(parent == null) {
+ return null;
+ }
+
+ if(parent instanceof Frame) {
+ return (Frame)parent;
+ }
+
+ return getParentFrame(parent);
+ }
+ }
}
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/AutoComplete.java b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/AutoComplete.java
index 3f71b5c..b8011a1 100644
--- a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/AutoComplete.java
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/AutoComplete.java
@@ -36,11 +36,11 @@ public class AutoComplete {
private final String context;
private final String attribute;
@Nullable private final Dependent dependent;
- private final String selection;
+ private final Selection selection;
private final RequestInfo requestInfo;
@Nullable private final ResponseAction responseAction;
- public AutoComplete(final Map namespaceBindings, final String context, final String attribute, final Dependent dependent, final String selection, final RequestInfo requestInfo, final ResponseAction responseAction) {
+ public AutoComplete(final Map namespaceBindings, final String context, final String attribute, final Dependent dependent, final Selection selection, final RequestInfo requestInfo, final ResponseAction responseAction) {
this.namespaceBindings = namespaceBindings;
this.context = context;
this.attribute = attribute;
@@ -67,7 +67,7 @@ public Dependent getDependent() {
return dependent;
}
- public String getSelection() {
+ public Selection getSelection() {
return selection;
}
@@ -79,4 +79,6 @@ public RequestInfo getRequestInfo() {
public ResponseAction getResponseAction() {
return responseAction;
}
+
+
}
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Dependent.java b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Dependent.java
index bfaf35d..05dc84f 100644
--- a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Dependent.java
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Dependent.java
@@ -28,9 +28,12 @@ public class Dependent {
@Nullable private final String def; //default
private final String attribute;
- public Dependent(@Nullable final String def, final String attribute) {
+ private final String label;
+
+ public Dependent(@Nullable final String def, final String attribute, final String label) {
this.def = def;
this.attribute = attribute;
+ this.label = label;
}
@Nullable
@@ -41,4 +44,8 @@ public String getDefault() {
public String getAttribute() {
return attribute;
}
+
+ public String getLabel() {
+ return label;
+ }
}
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Selection.java b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Selection.java
new file mode 100644
index 0000000..21b861e
--- /dev/null
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/beans/Selection.java
@@ -0,0 +1,45 @@
+/**
+ * TEI Completer
+ * An Oxygen XML Editor plugin for customizable attribute and value completion for TEI P5 documents
+ * Copyright (C) 2016 Belgrade Center for Digital Humanities
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package org.humanistika.oxygen.tei.completer.configuration.beans;
+
+import javax.annotation.Nullable;
+
+/**
+ * Configuration Details of an optional selection of the {@link AutoComplete#context}
+ */
+public class Selection {
+ @Nullable private final String def; //default
+
+ private final String label;
+
+ public Selection(@Nullable final String def, final String label) {
+ this.def = def;
+ this.label = label;
+ }
+
+ @Nullable
+ public String getDefault() {
+ return def;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
diff --git a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/impl/XmlConfiguration.java b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/impl/XmlConfiguration.java
index ddada05..a98de37 100755
--- a/src/main/java/org/humanistika/oxygen/tei/completer/configuration/impl/XmlConfiguration.java
+++ b/src/main/java/org/humanistika/oxygen/tei/completer/configuration/impl/XmlConfiguration.java
@@ -102,7 +102,18 @@ private List expandConfig(final Config config) {
} else {
dependent = new Dependent(
autoComplete.getDependent().getDefault(),
- autoComplete.getDependent().getValue()
+ autoComplete.getDependent().getValue(),
+ autoComplete.getDependent().getLabel()
+ );
+ }
+
+ final Selection selection;
+ if(autoComplete.getSelection() == null) {
+ selection = null;
+ } else {
+ selection = new Selection(
+ autoComplete.getSelection().getValue(),
+ autoComplete.getSelection().getLabel()
);
}
@@ -124,7 +135,7 @@ private List expandConfig(final Config config) {
autoComplete.getContext(),
autoComplete.getAttribute(),
dependent,
- autoComplete.getSelection(),
+ selection,
requestInfo,
responseAction
));
diff --git a/src/main/resources/config.xsd b/src/main/resources/config.xsd
index 9e7085f..f97a95b 100644
--- a/src/main/resources/config.xsd
+++ b/src/main/resources/config.xsd
@@ -6,10 +6,10 @@
26 January 2016
-->
+ elementFormDefault="qualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:tc="http://humanistika.org/ns/tei-completer"
+ xmlns:h="http://www.w3.org/1999/xhtml">
XML Schema for configuration of the TEI-Completer.
@@ -73,7 +73,7 @@
- Optional. An attribute which we have a dependency on being non-empty
+ Optional. An attribute which we have a dependency on being non-empty
@@ -83,14 +83,30 @@
An optional default value to be used for the dependency if the attribute value is empty
+
+
+ A human-readable label for the dependent, this is used in the GUI.
+
+
-
+
The XPath (relative to the context) to use for the selection. e.g. text()
+
+
+
+
+
+ A human-readable label for the selection, this is used in the GUI.
+
+
+
+
+