436 lines
14 KiB
Java
436 lines
14 KiB
Java
package pro.litvinovg.libreoffice.metadata.views;
|
|
|
|
import java.awt.BorderLayout;
|
|
import java.awt.EventQueue;
|
|
|
|
import javax.swing.JFrame;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.border.EmptyBorder;
|
|
import java.awt.GridBagLayout;
|
|
import javax.swing.JCheckBox;
|
|
import java.awt.GridBagConstraints;
|
|
import javax.swing.JButton;
|
|
import java.awt.Insets;
|
|
import javax.swing.BoxLayout;
|
|
import javax.swing.UIManager;
|
|
import java.awt.Toolkit;
|
|
import javax.swing.JTabbedPane;
|
|
import java.awt.GridLayout;
|
|
import javax.swing.JMenuBar;
|
|
import javax.swing.JMenuItem;
|
|
import javax.swing.JMenu;
|
|
import javax.swing.JTable;
|
|
import javax.swing.GroupLayout;
|
|
import javax.swing.GroupLayout.Alignment;
|
|
import javax.swing.table.DefaultTableModel;
|
|
import javax.swing.table.TableModel;
|
|
|
|
import pro.litvinovg.libreoffice.metadata.CustomDocumentProperty;
|
|
import pro.litvinovg.libreoffice.metadata.Document;
|
|
import pro.litvinovg.libreoffice.metadata.OutlineElement;
|
|
|
|
import javax.swing.JScrollPane;
|
|
import javax.swing.JPopupMenu;
|
|
import java.awt.Component;
|
|
import java.awt.event.MouseAdapter;
|
|
import java.awt.event.MouseEvent;
|
|
import java.util.ArrayList;
|
|
import java.util.Enumeration;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Vector;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.FocusAdapter;
|
|
import java.awt.event.FocusEvent;
|
|
import javax.swing.JToggleButton;
|
|
import javax.swing.LayoutStyle.ComponentPlacement;
|
|
import javax.swing.JLabel;
|
|
|
|
public class EditorGUI extends JFrame {
|
|
//Components
|
|
private JTable tableDocStandard;
|
|
private JTable tableDocCustom;
|
|
private ArrayList<MetadataTableModel> tableModels ;
|
|
|
|
//Component models
|
|
private DefaultTableModel docPropertiesModel;
|
|
private DefaultTableModel docCustomPropsModel;
|
|
|
|
|
|
private static JFrame singleFrame = null;
|
|
|
|
|
|
private Map<String, String> docProps;
|
|
private ArrayList<CustomDocumentProperty> docCustomProps;
|
|
private Document document = null;
|
|
private JButton btnSaveButton;
|
|
private JMenuItem menuItemPupupDocUserProps;
|
|
private ArrayList<OutlineElement> outline;
|
|
private JTabbedPane tabbedPane;
|
|
private JPanel panelStandardMetadata;
|
|
private JMenuBar menuBar;
|
|
|
|
|
|
/**
|
|
* Launch the application.
|
|
*/
|
|
public static void main(String[] args) {
|
|
testGUI();
|
|
}
|
|
|
|
public static void runGUI(Document doc) {
|
|
if (singleFrame != null) {
|
|
singleFrame.dispose();
|
|
}
|
|
try {
|
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
} catch (Throwable e) {
|
|
e.printStackTrace();
|
|
}
|
|
EventQueue.invokeLater(new Runnable() {
|
|
public void run() {
|
|
try {
|
|
EditorGUI frame = new EditorGUI(doc);
|
|
singleFrame = frame;
|
|
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
frame.setVisible(true);
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
private static void testGUI() {
|
|
try {
|
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
} catch (Throwable e) {
|
|
e.printStackTrace();
|
|
}
|
|
EventQueue.invokeLater(new Runnable() {
|
|
public void run() {
|
|
try {
|
|
EditorGUI frame = new EditorGUI();
|
|
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
frame.setVisible(true);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
public EditorGUI(Document doc) {
|
|
this.document = doc;
|
|
docProps = document.getDocumentProperties();
|
|
docCustomProps = document.getDocumentCustomProperties();
|
|
outline = document.getOutline();
|
|
tableModels = new ArrayList<MetadataTableModel>();
|
|
initComponents();
|
|
createEvents();
|
|
}
|
|
|
|
public EditorGUI() {
|
|
outline = new ArrayList<OutlineElement>();
|
|
initComponents();
|
|
createEvents();
|
|
}
|
|
|
|
private void createEvents() {
|
|
|
|
btnSaveButton.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
saveAction();
|
|
}
|
|
});
|
|
|
|
menuItemPupupDocUserProps.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
docCustomPropsModel.addRow(new Object[] {null, null});
|
|
}
|
|
});
|
|
}
|
|
private void updateDocCustomProps() {
|
|
Vector dataVector = docCustomPropsModel.getDataVector();
|
|
Enumeration elements = dataVector.elements();
|
|
docCustomProps.clear();
|
|
while (elements.hasMoreElements()) {
|
|
Vector row = (Vector) elements.nextElement();
|
|
String name = (String) row.get(0);
|
|
String value = (String) row.get(1);
|
|
if (!name.isEmpty() && !value.isEmpty()) {
|
|
docCustomProps.add(new CustomDocumentProperty(name, value, "string"));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void updateDocProps() {
|
|
Vector dataVector = docPropertiesModel.getDataVector();
|
|
Enumeration elements = dataVector.elements();
|
|
docProps.clear();
|
|
while (elements.hasMoreElements()) {
|
|
Vector row = (Vector) elements.nextElement();
|
|
String name = (String) row.get(0);
|
|
String value = (String) row.get(1);
|
|
docProps.put(name, value);
|
|
}
|
|
}
|
|
private void initComponents() {
|
|
configureWindow();
|
|
panelStandardMetadata = new JPanel();
|
|
tabbedPane.addTab("Метаданные либры", null, panelStandardMetadata, null);
|
|
tabbedPane.setEnabledAt(0, true);
|
|
/*
|
|
* if (true) { addMetadataTab(new OutlineElement(null, "Тестовое название")); }
|
|
*/
|
|
for (OutlineElement element : outline) {
|
|
addMetadataTab(element);
|
|
}
|
|
|
|
createDocPropsModel();
|
|
createCustomDocPropsModel();
|
|
tableDocStandard = new JTable();
|
|
tableDocCustom = new JTable();
|
|
configureTableDocStandard();
|
|
configureTableDocCustom();
|
|
|
|
btnSaveButton = new JButton("Сохранить");
|
|
|
|
GroupLayout gl_panelStandardMetadata = new GroupLayout(panelStandardMetadata);
|
|
configureGroupLayoutDoc(gl_panelStandardMetadata);
|
|
|
|
JPopupMenu popupMenu = new JPopupMenu();
|
|
addPopup(tableDocCustom, popupMenu);
|
|
|
|
menuItemPupupDocUserProps = new JMenuItem("Добавить строку");
|
|
|
|
popupMenu.add(menuItemPupupDocUserProps);
|
|
panelStandardMetadata.setLayout(gl_panelStandardMetadata);
|
|
|
|
menuBar = new JMenuBar();
|
|
setJMenuBar(menuBar);
|
|
|
|
JMenu mnFile = new JMenu("Файл");
|
|
menuBar.add(mnFile);
|
|
}
|
|
|
|
private void addMetadataTab(OutlineElement element) {
|
|
JPanel panelOutline = new JPanel();
|
|
JTable tableOutline = new JTable();
|
|
MetadataTableModel outlineTableModel = createOutlineTableModel(element);
|
|
tableModels.add(outlineTableModel);
|
|
configureTableOutline(tableOutline, outlineTableModel);
|
|
|
|
JButton btnOutlineSave = new JButton("Сохранить");
|
|
btnOutlineSave.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
saveAction();
|
|
}
|
|
});
|
|
|
|
GroupLayout groupLayoutOutlineMetadata = new GroupLayout(panelOutline);
|
|
groupLayoutOutlineMetadata.setHorizontalGroup(
|
|
groupLayoutOutlineMetadata.createParallelGroup(Alignment.LEADING)
|
|
.addGroup(groupLayoutOutlineMetadata.createSequentialGroup()
|
|
.addGap(34)
|
|
.addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 839, Short.MAX_VALUE)
|
|
.addGap(126))
|
|
.addGroup(Alignment.TRAILING, groupLayoutOutlineMetadata.createSequentialGroup()
|
|
.addContainerGap(748, Short.MAX_VALUE)
|
|
.addComponent(btnOutlineSave)
|
|
.addGap(134))
|
|
);
|
|
groupLayoutOutlineMetadata.setVerticalGroup(
|
|
groupLayoutOutlineMetadata.createParallelGroup(Alignment.LEADING)
|
|
.addGroup(groupLayoutOutlineMetadata.createSequentialGroup()
|
|
.addGap(85)
|
|
.addComponent(tableOutline, GroupLayout.DEFAULT_SIZE, 497, Short.MAX_VALUE)
|
|
.addGap(52)
|
|
.addComponent(btnOutlineSave)
|
|
.addGap(43))
|
|
);
|
|
|
|
JPopupMenu popupMenu = new JPopupMenu();
|
|
addPopup(tableOutline, popupMenu);
|
|
|
|
JMenuItem menuItem = new JMenuItem("Добавить строку");
|
|
menuItem.addActionListener(new ActionListener() {
|
|
public void actionPerformed(ActionEvent e) {
|
|
outlineTableModel.addRow(new Object[] {null, null});
|
|
}
|
|
});
|
|
popupMenu.add(menuItem);
|
|
panelOutline.setLayout(groupLayoutOutlineMetadata);
|
|
tabbedPane.addTab(element.getName(), null, panelOutline, null);
|
|
}
|
|
|
|
private void configureTableOutline(JTable tableOutline, DefaultTableModel outlineTableModel) {
|
|
tableOutline.setModel(outlineTableModel);
|
|
tableOutline.putClientProperty("terminateEditOnFocusLost", true);
|
|
tableOutline.setSurrendersFocusOnKeystroke(true);
|
|
tableOutline.setCellSelectionEnabled(true);
|
|
tableOutline.setFillsViewportHeight(true);
|
|
}
|
|
|
|
private void configureWindow() {
|
|
setIconImage(Toolkit.getDefaultToolkit().getImage(EditorGUI.class.getResource("/pro/litvinovg/libreoffice/metadata/resources/webcam.png")));
|
|
setTitle("Редактор метаданных");
|
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
setBounds(100, 100, 1170, 755);
|
|
getContentPane().setLayout(null);
|
|
getContentPane().setLayout(new GridLayout(0, 1, 0, 0));
|
|
|
|
tabbedPane = new JTabbedPane(JTabbedPane.LEFT, JTabbedPane.SCROLL_TAB_LAYOUT);
|
|
tabbedPane.setBounds(125, 138, 913, 546);
|
|
getContentPane().add(tabbedPane);
|
|
}
|
|
|
|
private void configureTableDocStandard() {
|
|
tableDocStandard.putClientProperty("terminateEditOnFocusLost", true);
|
|
tableDocStandard.setSurrendersFocusOnKeystroke(true);
|
|
tableDocStandard.setCellSelectionEnabled(true);
|
|
tableDocStandard.setFillsViewportHeight(true);
|
|
tableDocStandard.setModel(docPropertiesModel);
|
|
}
|
|
|
|
private void configureTableDocCustom() {
|
|
tableDocCustom.setColumnSelectionAllowed(true);
|
|
tableDocCustom.putClientProperty("terminateEditOnFocusLost", true);
|
|
tableDocCustom.setSurrendersFocusOnKeystroke(true);
|
|
tableDocCustom.setFillsViewportHeight(true);
|
|
tableDocCustom.setCellSelectionEnabled(true);
|
|
tableDocCustom.setModel(docCustomPropsModel);
|
|
}
|
|
|
|
private void configureGroupLayoutDoc(GroupLayout gl_panelStandardMetadata) {
|
|
JLabel labelDocProperties = new JLabel("Основные метаданные");
|
|
JLabel labelDocCustomProperties = new JLabel("Дополнительные метаданные");
|
|
gl_panelStandardMetadata.setHorizontalGroup(
|
|
gl_panelStandardMetadata.createParallelGroup(Alignment.TRAILING)
|
|
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
|
|
.addGap(378)
|
|
.addComponent(labelDocProperties, GroupLayout.DEFAULT_SIZE, 260, Short.MAX_VALUE)
|
|
.addGap(421))
|
|
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addGroup(gl_panelStandardMetadata.createParallelGroup(Alignment.LEADING)
|
|
.addGroup(gl_panelStandardMetadata.createSequentialGroup()
|
|
.addComponent(tableDocStandard, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE)
|
|
.addContainerGap())
|
|
.addGroup(Alignment.TRAILING, gl_panelStandardMetadata.createSequentialGroup()
|
|
.addComponent(btnSaveButton)
|
|
.addGap(154))))
|
|
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
|
|
.addGap(350)
|
|
.addComponent(labelDocCustomProperties, GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE)
|
|
.addGap(381))
|
|
.addGroup(Alignment.LEADING, gl_panelStandardMetadata.createSequentialGroup()
|
|
.addContainerGap()
|
|
.addComponent(tableDocCustom, GroupLayout.DEFAULT_SIZE, 940, Short.MAX_VALUE)
|
|
.addContainerGap())
|
|
);
|
|
gl_panelStandardMetadata.setVerticalGroup(
|
|
gl_panelStandardMetadata.createParallelGroup(Alignment.LEADING)
|
|
.addGroup(gl_panelStandardMetadata.createSequentialGroup()
|
|
.addGap(53)
|
|
.addComponent(labelDocProperties)
|
|
.addGap(18)
|
|
.addComponent(tableDocStandard, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(ComponentPlacement.UNRELATED)
|
|
.addComponent(labelDocCustomProperties, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
|
|
.addGap(18)
|
|
.addComponent(tableDocCustom, GroupLayout.PREFERRED_SIZE, 322, GroupLayout.PREFERRED_SIZE)
|
|
.addPreferredGap(ComponentPlacement.RELATED, 90, Short.MAX_VALUE)
|
|
.addComponent(btnSaveButton)
|
|
.addGap(31))
|
|
);
|
|
}
|
|
|
|
private void createDocPropsModel() {
|
|
Object[][] tableArray = new Object[][] {
|
|
{null, null},
|
|
{null, null},
|
|
{null, null},
|
|
{null, null},
|
|
{null, null},
|
|
};
|
|
if (docProps != null) {
|
|
Object[] arrayOfEntries = docProps.entrySet().toArray();
|
|
tableArray = new Object[docProps.size()][2];
|
|
for (int i = 0; i < tableArray.length; i++) {
|
|
Entry<String, String> entry = (Entry<String, String>) arrayOfEntries[i];
|
|
tableArray[i][0] = entry.getKey();
|
|
tableArray[i][1] = entry.getValue();
|
|
}
|
|
}
|
|
docPropertiesModel = new DefaultTableModel(
|
|
tableArray,
|
|
new String[] {
|
|
"Metadata name", "Metadata value"
|
|
});
|
|
}
|
|
|
|
private MetadataTableModel createOutlineTableModel(OutlineElement element) {
|
|
|
|
MetadataTableModel outlineTableModel = new MetadataTableModel(element);
|
|
return outlineTableModel;
|
|
}
|
|
private void createCustomDocPropsModel() {
|
|
Object[][] tableArray = new Object[][] {
|
|
{null, null},
|
|
{null, null},
|
|
{null, null},
|
|
{null, null},
|
|
};
|
|
if (docCustomProps != null) {
|
|
tableArray = new Object[docCustomProps.size()][2];
|
|
for (int i = 0; i < tableArray.length; i++) {
|
|
CustomDocumentProperty curProp = docCustomProps.get(i);
|
|
tableArray[i][0] = curProp.getName();
|
|
tableArray[i][1] = curProp.getValue();
|
|
}
|
|
}
|
|
docCustomPropsModel = new DefaultTableModel(
|
|
tableArray,
|
|
new String[] {
|
|
"Metadata name", "Metadata value"
|
|
});
|
|
}
|
|
|
|
|
|
private static void addPopup(Component component, JPopupMenu popup) {
|
|
component.addMouseListener(new MouseAdapter() {
|
|
public void mousePressed(MouseEvent e) {
|
|
if (e.isPopupTrigger()) {
|
|
showMenu(e);
|
|
}
|
|
}
|
|
public void mouseReleased(MouseEvent e) {
|
|
if (e.isPopupTrigger()) {
|
|
showMenu(e);
|
|
}
|
|
}
|
|
private void showMenu(MouseEvent e) {
|
|
popup.show(e.getComponent(), e.getX(), e.getY());
|
|
}
|
|
});
|
|
}
|
|
public void saveAction() {
|
|
updateDocProps();
|
|
document.setDocumentProperties(docProps);
|
|
updateDocCustomProps();
|
|
document.setCustomDocumentProperties(docCustomProps);
|
|
updateOutlineMetadata();
|
|
document.writeOutlineMetadata();
|
|
document.hideAnnotations();
|
|
}
|
|
|
|
|
|
private void updateOutlineMetadata() {
|
|
for (MetadataTableModel table : tableModels) {
|
|
table.writeToOutline();
|
|
}
|
|
}
|
|
}
|