Mercurial Hosting > junotu
changeset 15:4bb371496315
Tag editing
author | Fox |
---|---|
date | Sun, 10 Apr 2022 02:20:14 +0200 |
parents | d90a9b1065d1 |
children | 736bcfba1d2d |
files | src/junotu/Card.java src/junotu/Database.java src/junotu/GUIToolbox.java src/junotu/TabEdit.java |
diffstat | 4 files changed, 369 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/src/junotu/Card.java Sat Apr 09 16:40:55 2022 +0200 +++ b/src/junotu/Card.java Sun Apr 10 02:20:14 2022 +0200 @@ -18,9 +18,9 @@ public SortedMap< String, Set<Object> > tags = new TreeMap< String, Set<Object> >(); - public Card( long identifier ) + public Card() { - tagValueSetOnly( TAG_IDENTIFIER, new Long( identifier ) ); + tagValueSetOnly( TAG_IDENTIFIER, new Long( -1 ) ); } public long identifierGet() @@ -54,11 +54,22 @@ tagValueSetOnly( TAG_CONTENT, content ); } + /** Return all set tags. */ + public Set<String> tagNames() + { + return tags.keySet(); + } + public Set<Object> tagValues( String tag ) { return tags.get( tag ); } + public void tagRemove( String tag ) + { + tags.remove( tag ); + } + public void tagValueSetOnly( String tag, Object value ) { Set<Object> values = new HashSet<Object>(); @@ -85,9 +96,17 @@ public void tagValueRemove( String tag, Object value ) { Set<Object> values = tags.get( tag ); - if( values != null ) { - values.remove( value ); + + if( values == null ) { + return; } + + values.remove( value ); + + if( values.size() == 0 ) { + tagRemove( tag ); + } + } public void tagValueReplace( String tag, Object previous, Object value )
--- a/src/junotu/Database.java Sat Apr 09 16:40:55 2022 +0200 +++ b/src/junotu/Database.java Sun Apr 10 02:20:14 2022 +0200 @@ -12,6 +12,7 @@ import org.apache.lucene.store.FSDirectory; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.util.Version; +import org.apache.lucene.document.Fieldable; import org.apache.lucene.document.Field; import org.apache.lucene.document.NumericField; @@ -100,8 +101,10 @@ for( String tag : card.tags.keySet() ) { Set<Object> values = card.tags.get( tag ); for( Object value : values ) { - if( false ) { - + if( value == null ) { + if( !tag.equals("") ) { + document.add( new Field( tag, "", Field.Store.YES, Field.Index.NOT_ANALYZED ) ); + } } else if( value instanceof String ) { document.add( new Field( tag, (String)value, Field.Store.YES, Field.Index.ANALYZED ) ); } else if( value instanceof Number ) { @@ -123,11 +126,15 @@ private Card cardFromDocument( Document document ) throws Exception { - /** TODO: Find how to get NumericField from document. */ - Card card = new Card( Long.valueOf( document.get( Card.TAG_IDENTIFIER ) ) ); + Card card = new Card(); - card.titleSet( document.get( Card.TAG_TITLE ) ); - card.contentSet( document.get( Card.TAG_CONTENT ) ); + for( Fieldable field : document.getFields() ) { + /** TODO: Find how to get NumericField from document. */ + String value = field.stringValue(); + card.tagValueAdd( field.name(), value.equals("") ? null : value ); + } + + card.tagValueSetOnly( Card.TAG_IDENTIFIER, Long.valueOf( document.get( Card.TAG_IDENTIFIER ) ) ); return card; @@ -141,7 +148,7 @@ card.tagValueSetOnly( Card.TAG_LAST_EDIT, new Long( System.currentTimeMillis() ) ); luceneWriter.addDocument( cardToDocument( card ) ); - System.out.print("Added card with identifier "+Long.toString(highestIdentifier)+": '"+card.titleGet()+"'\n"); + System.out.print( "Added card with identifier "+Long.toString(highestIdentifier)+": '"+card.titleGet()+"'\n" ); searcherRefresh(); //luceneWriter.commit();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/junotu/GUIToolbox.java Sun Apr 10 02:20:14 2022 +0200 @@ -0,0 +1,64 @@ +package junotu; + +import java.awt.Dimension; +import java.awt.Rectangle; +import java.awt.LayoutManager; + +import java.awt.Component; +import java.awt.Container; + +import javax.swing.SwingConstants; +import javax.swing.JPanel; +import javax.swing.Scrollable; + +public class GUIToolbox { + + /** Source: https://stackoverflow.com/a/2814718 */ + public static class JPanelScrollable extends JPanel implements Scrollable { + + public boolean scrollVertical = false; + + public JPanelScrollable() + { + super(); + } + + public JPanelScrollable( LayoutManager layout ) + { + super( layout ); + } + + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + public int getScrollableUnitIncrement( Rectangle visibleRect, int orientation, int direction ) { + return 10; + } + + public int getScrollableBlockIncrement( Rectangle visibleRect, int orientation, int direction ) { + return ((orientation == SwingConstants.VERTICAL) ? visibleRect.height : visibleRect.width) - 10; + } + + public boolean getScrollableTracksViewportWidth() { + return !scrollVertical; + } + + public boolean getScrollableTracksViewportHeight() { + return scrollVertical; + } + } + + public static final int componentGetIndex( Component component ) { + if (component != null && component.getParent() != null) { + Container parent = component.getParent(); + for( int i = 0; i < parent.getComponentCount(); i++ ) { + if( parent.getComponent(i) == component ) + return i; + } + } + + return -1; + } + +}
--- a/src/junotu/TabEdit.java Sat Apr 09 16:40:55 2022 +0200 +++ b/src/junotu/TabEdit.java Sun Apr 10 02:20:14 2022 +0200 @@ -4,6 +4,8 @@ import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; import javax.swing.SwingUtilities; import javax.swing.event.DocumentListener; @@ -12,6 +14,7 @@ import javax.swing.JPanel; import java.awt.BorderLayout; +import java.awt.FlowLayout; import javax.swing.Box; import javax.swing.JButton; @@ -23,17 +26,59 @@ import junotu.Main; import junotu.Database; import junotu.Window.Tab; +import junotu.GUIToolbox; import junotu.Card; public class TabEdit extends JPanel { + private class TagWidget extends JButton { + + public String tag; + public Object value; + + public TagWidget( String tag, Object value ) { + super(); + this.tag = tag; + this.value = value; + TagWidget ref = this; + + addActionListener( + new ActionListener() { + @Override + public void actionPerformed( ActionEvent e ) + { + tagEdit( ref ); + } + } + ); + + update(); + + } + + public void update() + { + if( value != null ) { + setText( tag+": "+value.toString() ); + } else { + setText( tag ); + } + } + + } + + private Card card = null; private boolean newCard = true; - private long identifier = -1; + + private TagWidget editedTag = null; + private JTextField editedTagField; private JScrollPane scroll; private JTextField title; private JTextArea content; + private JPanel tags; + private JButton addTag; private JButton delete; @@ -42,26 +87,37 @@ this.setLayout( new BorderLayout() ); Box scrollContent = Box.createVerticalBox(); - scroll = new JScrollPane( scrollContent ); - title = new JTextField(); - content = new JTextArea(); + scroll = new JScrollPane( scrollContent ); + title = new JTextField(); + content = new JTextArea(); + tags = new JPanel(); + editedTagField = new JTextField(); + addTag = new JButton("+"); Box bottom = Box.createHorizontalBox(); JButton back = new JButton("Cancel"); delete = new JButton("Delete"); JButton save = new JButton("Save"); + tags.setLayout( new FlowLayout() ); + title.setFont( new Font( "Monospaced", Font.PLAIN, 32 ) ); content.setFont( new Font( "Monospaced", Font.PLAIN, 16 ) ); + editedTagField.setFont( new Font( "Monospaced", Font.PLAIN, 12 ) ); scroll.getVerticalScrollBar().setUnitIncrement(16); - title.setMaximumSize( new Dimension( 1000000, 64 ) ); + title.setMaximumSize( new Dimension( Integer.MAX_VALUE, 64 ) ); + //content.setMaximumSize( new Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE ) ); + /* TODO: Figure out tags layout mess. */ + tags.setPreferredSize( new Dimension( 16, 256 ) ); + tags.setMaximumSize( new Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE ) ); this.add( scroll, BorderLayout.CENTER ); scrollContent.add( title ); scrollContent.add( Box.createVerticalStrut(10) ); scrollContent.add( content ); + scrollContent.add( tags ); this.add( bottom, BorderLayout.SOUTH ); bottom.add( back ); @@ -89,7 +145,7 @@ buttonClickedDelete(); } } - ); + ); save.addActionListener( new ActionListener() { @@ -99,7 +155,33 @@ buttonClickedSave(); } } - ); + ); + + addTag.addActionListener( + new ActionListener() { + @Override + public void actionPerformed( ActionEvent e ) + { + tagAdd(); + } + } + ); + + editedTagField.addFocusListener( + new FocusListener() + { + @Override + public void focusGained(FocusEvent e) + { + } + + @Override + public void focusLost(FocusEvent e) + { + tagCommit(); + } + } + ); title.getDocument().addDocumentListener( new DocumentListener() @@ -140,19 +222,21 @@ public void cardCreate() { newCard = true; - identifier = -1; + card = new Card(); updateTitle(); delete.setVisible(false); + updateTags(); } public void cardEdit( Card card ) { newCard = false; - identifier = card.identifierGet(); + this.card = card; title.setText( card.titleGet() ); content.setText( card.contentGet() ); updateTitle(); delete.setVisible(true); + updateTags(); SwingUtilities.invokeLater( new Runnable() { @@ -164,10 +248,179 @@ ); } - private void clearWidgets() + private void reset() { title.setText(""); content.setText(""); + card = null; + } + + private void updateTags() + { + tags.removeAll(); + for( String tag : card.tagNames() ) { + for( Object value : card.tagValues( tag ) ) { + tags.add( new TagWidget( tag, value ) ); + } + } + tags.add( addTag ); + tags.validate(); + tags.repaint(); + } + + private void tagAdd() + { + tags.add( editedTagField, GUIToolbox.componentGetIndex( addTag ) ); + editedTagField.setText( "" ); + editedTagField.setColumns(12); + editedTagField.grabFocus(); + tags.validate(); + tags.repaint(); + System.out.print( "Opened new tag for editing.\n" ); + } + + private void tagEdit( TagWidget tagWidget ) + { + editedTag = tagWidget; + tags.add( editedTagField, GUIToolbox.componentGetIndex( editedTag ) ); + if( editedTag.value != null ) { + editedTagField.setText( editedTag.tag+":"+editedTag.value.toString() ); + } else { + editedTagField.setText( editedTag.tag ); + } + editedTagField.setColumns(0); + editedTagField.grabFocus(); + editedTag.setVisible(false); + tags.validate(); + tags.repaint(); + System.out.print( "Opened existing tag for editing.\n" ); + } + + private void tagCommit() + { + + String newTag; + Object newValue; + + { + String[] split = editedTagField.getText().split( ":", 2 ); + newTag = split[0]; + newValue = split.length > 1 ? split[1] : null; + } + + /* Either editing tag, or adding a new one. */ + if( editedTag != null ) { + + String oldTag = editedTag.tag; + Object oldValue = editedTag.value; + + logTagChange( oldTag, oldValue, newTag, newValue ); + + if( oldTag.equals(newTag) ) { + card.tagValueReplace( oldTag, oldValue, newValue ); + editedTag.value = newValue; + editedTag.update(); + } else { /* Replace tag with another one. */ + + card.tagValueRemove( oldTag, oldValue ); + card.tagValueAdd( newTag, newValue ); + + if( !newTag.equals("") ) { + editedTag.tag = newTag; + editedTag.value = newValue; + editedTag.update(); + } else { + tags.remove( editedTag ); + } + + } + + editedTag.setVisible( true ); + + } else { /* Adding new tag (value). */ + if( !newTag.equals("") ) { + card.tagValueAdd( newTag, newValue ); + tags.add( new TagWidget( newTag, newValue ), GUIToolbox.componentGetIndex( addTag )-1 ); + logTagChange( "", null, newTag, newValue ); + } else { + logTagChange( "", null, "", null ); + } + } + + editedTagField.setText( "" ); + tags.remove( editedTagField ); + + editedTag = null; + + tags.validate(); + tags.repaint(); + + } + + private void logTagChange( String oldTag, Object oldValue, String newTag, Object newValue ) + { + System.out.print( "Comitted changes to tag: " ); + if( oldTag.equals("") ) { /* Creating tag. */ + if( !newTag.equals("") ) { + if( newValue == null ) { /* No value. */ + System.out.print( "Added tag '"+newTag+"' (with no value)\n" ); + } else { /* Has value. */ + System.out.print( "Added tag '"+newTag+"' with value '"+newValue.toString()+"'\n" ); + } + } else { + System.out.print( "No changes.\n" ); + } + } else { /* Editing tag. */ + if( oldTag.equals(newTag) ) { /* Same tag. */ + if( oldValue == null ) { + if( newValue == null ) { /* Clear before, clear now. */ + System.out.print( "No changes (tag '"+oldTag+"' with no value)\n" ); + } else { /* Assigned value. */ + System.out.print( "Assigned value of tag '"+oldTag+"' to '"+newValue.toString()+"'\n" ); + } + } else { + if( newValue == null ) { /* Clearing value. */ + System.out.print( "Cleared value of tag '"+oldTag+"' (was '" + +oldValue.toString()+"')\n" ); + } else if( oldValue.equals(newValue) ) { /* Value is the same. */ + System.out.print( "No changes (tag '"+oldTag+"' with value '"+oldValue+"')\n" ); + } else { /* Changing value. */ + System.out.print( "Changed value of tag '"+oldTag+"' from '" + +oldValue.toString()+"' to '"+newValue.toString()+"'\n" ); + } + } + } else { /* Replaced tag. */ + if( newTag.equals("") ) { /* Removing tag. */ + if( oldValue == null ) { + System.out.print( "Removed tag '"+oldTag+"' (with no value)\n" ); + } else { + System.out.print( "Removed tag '"+oldTag+"' with value '"+oldValue.toString()+"'\n" ); + } + } else { + if( oldValue == null ) { + if( newValue == null ) { + System.out.print( + "Renamed tag '"+oldTag+"' -> '" + +newTag+"'\n" ); + } else { + System.out.print( + "Changed tag '"+oldTag+"' -> '" + +newTag+"': '"+newValue.toString()+"'\n" ); + } + } else { + if( newValue == null ) { + System.out.print( + "Changed tag '"+oldTag+"': '"+oldValue.toString()+"' -> '" + +newTag+"'\n" ); + } else { + System.out.print( + "Changed tag '"+oldTag+"': '"+oldValue.toString()+"' -> '" + +newTag+"': '"+newValue.toString()+"'\n" ); + } + } + } + } + } } private void updateTitle() @@ -188,8 +441,8 @@ private void buttonClickedBack() { Window window = (Window)this.getTopLevelAncestor(); - clearWidgets(); - window.tabSwitch( Tab.SEARCH ); + reset(); + window.tabSwitch( Tab.SEARCH ); } private void buttonClickedDelete() @@ -200,14 +453,14 @@ } try { - Main.database.cardDelete( identifier ); + Main.database.cardDelete( card.identifierGet() ); } catch( Exception e ) { throw new RuntimeException(e); } Window window = (Window)this.getTopLevelAncestor(); window.tabSearch.search(); - clearWidgets(); + reset(); window.tabSwitch( Tab.SEARCH ); } @@ -215,8 +468,6 @@ private void buttonClickedSave() { - Card card = new Card( identifier ); - card.titleSet( title.getText() ); card.contentSet( content.getText() ); @@ -232,7 +483,7 @@ Window window = (Window)this.getTopLevelAncestor(); window.tabSearch.search(); - clearWidgets(); + reset(); window.tabSwitch( Tab.SEARCH ); }