Mercurial Hosting > junotu
view src/junotu/TabEdit.java @ 59:a2696310fa8c
Default to TabSearch search, and added a way to get to TabBoard from TabEdit
Also renamed TabColumns into TabBoard.
author | Fox |
---|---|
date | Fri, 23 Dec 2022 15:02:21 +0100 |
parents | 7cf2788649a7 |
children | cda50e8f5135 |
line wrap: on
line source
package junotu; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.DocumentListener; import javax.swing.event.DocumentEvent; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.FlowLayout; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JTextField; import javax.swing.JTextArea; import javax.swing.JScrollPane; import javax.swing.JScrollBar; import junotu.Main; import junotu.Database; import junotu.Window.Tab; import junotu.GUIToolbox; import junotu.Card; public class TabEdit extends JPanel implements ActionListener { private class TagWidget extends JButton implements ActionListener { public String tag; public Object value; public TagWidget( String tag, Object value ) { super(); this.tag = tag; this.value = value; this.setToolTipText("Click to edit this tag. Use ':' to delimit name and value."); addActionListener(this); update(); } public void update() { if( value != null ) { setText( tag+": "+value.toString() ); } else { setText( tag ); } } public void actionPerformed( ActionEvent e ) { /* Not exactly sure how this works, but it does. */ tagEdit( this ); } } private final String KEY_ACTION_BACK = "back"; private final String KEY_ACTION_SAVE = "save"; private Card card = null; private boolean newCard = true; private TagWidget editedTag = null; private JTextField editedTagField; private JScrollPane scroll; private JTextField title; private JTextArea content; private JPanel tags; private JButton addTag; private JButton back; private JButton delete; private JButton editAsBoard; private JButton save; public TabEdit() { this.setLayout( new BorderLayout() ); JPanel scrollContent = new JPanel( new GUIToolbox.CardEditLayout() ); scroll = new JScrollPane( scrollContent ); title = new JTextField(); content = new JTextArea(); tags = new JPanel(); editedTagField = new JTextField(); addTag = new JButton("+"); Box bottom = Box.createHorizontalBox(); back = new JButton("Cancel"); delete = new JButton("Delete"); editAsBoard = new JButton("As board"); 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( Integer.MAX_VALUE, 64 ) ); //content.setMaximumSize( new Dimension( Integer.MAX_VALUE, Integer.MAX_VALUE ) ); content.setLineWrap( true ); /* 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 ); bottom.add( Box.createHorizontalGlue() ); bottom.add( delete ); bottom.add( editAsBoard ); bottom.add( save ); //scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); back.addActionListener(this); delete.addActionListener(this); editAsBoard.addActionListener(this); save.addActionListener(this); addTag.addActionListener(this); editedTagField.addFocusListener( new FocusListener() { @Override public void focusGained(FocusEvent e) { } @Override public void focusLost(FocusEvent e) { tagCommit(); } } ); title.getDocument().addDocumentListener( new DocumentListener() { @Override public void changedUpdate( DocumentEvent e ) { updateTitle(); } @Override public void removeUpdate( DocumentEvent e ) { updateTitle(); } @Override public void insertUpdate( DocumentEvent e ) { updateTitle(); } } ); registerKeyboardAction( this, KEY_ACTION_BACK, KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0 ), WHEN_IN_FOCUSED_WINDOW ); registerKeyboardAction( this, KEY_ACTION_SAVE, KeyStroke.getKeyStroke( KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK ), WHEN_IN_FOCUSED_WINDOW ); title.setToolTipText("Card title."); back.setToolTipText("Go back without saving. Can also use [ESC]."); delete.setToolTipText("Delete the card. There is no confirmation, nor going back."); editAsBoard.setToolTipText("Edit this card as board."); save.setToolTipText("Save and go back. Shift-click to save without exiting. Can also use [CTRL]+[S]."); addTag.setToolTipText("Add new tag."); } private void scrollTop() { JScrollBar scrollbar = scroll.getVerticalScrollBar(); scrollbar.setValue(0); } private void scrollBottom() { JScrollBar scrollbar = scroll.getVerticalScrollBar(); int maximum = scrollbar.getMaximum()-scrollbar.getVisibleAmount(); scrollbar.setValue(maximum); } public void cardCreate() { newCard = true; card = new Card(); updateTitle(); delete.setVisible(false); updateTags(); } public void cardEdit( Card card ) { newCard = false; this.card = card; title.setText( card.titleGet() ); content.setText( card.contentGet() ); updateTitle(); delete.setVisible(true); updateTags(); SwingUtilities.invokeLater( new Runnable() { public void run() { scrollTop(); } } ); } private void reset() { title.setText(""); content.setText(""); card = null; } private void updateTitle() { Window window = (Window)this.getTopLevelAncestor(); String text = title.getText(); String action = newCard ? "Create" : "Edit"; if( text.length() > 0 ) { window.setTitle( window.preferredTitle( action+": "+text ) ); } else { window.setTitle( window.preferredTitle( action ) ); } } private void updateTags() { tags.removeAll(); for( String tag : card.tagNames() ) { if( tag.startsWith("_") ) { continue; } 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 buttonClickedBack() { Window window = (Window)this.getTopLevelAncestor(); reset(); window.tabSwitch( Tab.SEARCH ); } private void buttonClickedDelete() { if( newCard ) { return; } try { Main.database.cardDelete( card.identifierGet() ); } catch( Exception e ) { throw new RuntimeException(e); } Window window = (Window)this.getTopLevelAncestor(); window.tabSearch.search(); reset(); window.tabSwitch( Tab.SEARCH ); } private void buttonClickedEditAsBoard() { Window window = (Window)this.getTopLevelAncestor(); buttonClickedSave(true); window.tabBoard.boardNew(title.getText()); reset(); window.tabSwitch( Tab.BOARD ); } private void buttonClickedSave( boolean noSwitch ) { card.titleSet( title.getText() ); card.contentSet( content.getText() ); try { if( newCard ) { Main.database.cardAdd( card ); } else { Main.database.cardUpdate( card ); } } catch( Exception e ) { throw new RuntimeException(e); } Window window = (Window)this.getTopLevelAncestor(); window.tabSearch.search(); if( noSwitch ) { if( newCard ) { cardEdit( this.card ); } } else { reset(); window.tabSwitch( Tab.SEARCH ); } } public void actionPerformed( ActionEvent e ) { Object source = e.getSource(); if( source == this ) { switch( e.getActionCommand() ) { case KEY_ACTION_BACK: { buttonClickedBack(); break; } case KEY_ACTION_SAVE: { buttonClickedSave( true ); try { Main.database.databaseCommit(); } catch( Exception ex ) { System.out.print( "Failed to write database: "+ex.getMessage()+"\n" ); } break; } } } else if( source == back ) { buttonClickedBack(); } else if( source == editAsBoard ) { buttonClickedEditAsBoard(); } else if( source == delete ) { buttonClickedDelete(); } else if( source == save ) { boolean noSwitch = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; buttonClickedSave( noSwitch ); } else if( source == addTag ) { tagAdd(); } } }