/*
* EditModesPane.java - Mode-specific options panel
* :tabSize=4:indentSize=4:noTabs=false:
* :folding=explicit:collapseFolds=1:
*
* Copyright (C) 1998, 2002 Slava Pestov
*
* 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gjt.sp.jedit.options;
// {{{ Imports
import java.awt.*;
import static java.awt.GridBagConstraints.BOTH;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;
import org.gjt.sp.jedit.*;
import org.gjt.sp.jedit.browser.VFSBrowser;
import org.gjt.sp.jedit.gui.PingPongList;
import org.gjt.sp.jedit.syntax.ModeProvider;
import org.gjt.sp.util.StandardUtilities;
// }}}
/**
* Option pane to set available edit modes and to add modes from a file.
* @author Dale Anson
* @version $Id: EditModesPane.java 24012 2015-08-12 08:48:07Z kpouer $
*/
public class EditModesPane extends AbstractOptionPane
{
// {{{ Instance variables
private JComboBox<Mode> defaultMode;
private PingPongList<Mode> pingPongList;
private JTextField modeName;
private JTextField modeFile;
private JButton browse;
private JTextField filenameGlob;
private JTextField firstLineGlob;
private JButton ok;
private JButton deleteSelectedButton;
// }}}
// {{{ EditModesPane constructor
public EditModesPane()
{
super( "editmodes" );
} //}}}
// {{{ _init() method
@Override
protected void _init()
{
Mode[] modes = loadAllModes();
Mode[] userSelectedModes = loadSelectedModes();
defaultMode = new JComboBox<Mode>( userSelectedModes );
defaultMode.setSelectedItem( jEdit.getMode( jEdit.getProperty( "buffer.defaultMode" ) ) );
JPanel topPanel = new JPanel( new BorderLayout() );
topPanel.add( new JLabel( jEdit.getProperty( "options.editing.defaultMode" ) ), BorderLayout.WEST );
topPanel.add( defaultMode );
addComponent( topPanel );
addSeparator();
List<Mode> availableModes = new ArrayList<Mode>();
List<Mode> selectedModes = new ArrayList<Mode>();
for ( Mode mode : modes ) {
String modeName = mode.getName();
boolean selected = !jEdit.getBooleanProperty( "mode.opt-out." + modeName, false );
if ( selected )
{
selectedModes.add( mode );
}
else
{
availableModes.add( mode );
}
}
pingPongList = new PingPongList<Mode>( availableModes, selectedModes );
pingPongList.setLeftTitle( jEdit.getProperty( "options.editing.modes.available" ) );
pingPongList.setRightTitle( jEdit.getProperty( "options.editing.modes.selected" ) );
pingPongList.setLeftTooltip( jEdit.getProperty( "options.editing.modes.available.tooltip" ) );
pingPongList.setRightTooltip( jEdit.getProperty( "options.editing.modes.selected.tooltip" ) );
pingPongList.setRightCellRenderer(new MyCellRenderer());
pingPongList.addRightListSelectionListener(new MyListSelectionListener());
deleteSelectedButton = new JButton( jEdit.getProperty("options.editing.modes.deleteSelected", "Delete Selected") );
deleteSelectedButton.setEnabled(false);
pingPongList.addButton( deleteSelectedButton );
deleteSelectedButton.addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent ae )
{
List<Mode> modes = pingPongList.getRightSelectedValues();
StringBuilder sb = new StringBuilder();
sb.append(jEdit.getProperty("options.editing.modes.Delete_these_modes?", "Delete these modes?")).append('\n');
for (Mode m : modes)
{
if (m.isUserMode())
sb.append(m.getName()).append('\n');
}
int answer = JOptionPane.showConfirmDialog(jEdit.getActiveView(), sb.toString(), jEdit.getProperty("options.editing.deleteMode.dialog.title", "Confirm Mode Delete"), JOptionPane.WARNING_MESSAGE );
if (answer == JOptionPane.YES_OPTION) {
for (Mode m : modes)
{
if (m.isUserMode())
{
try
{
ModeProvider.instance.removeMode(m.getName());
}
catch (IOException e)
{
JOptionPane.showMessageDialog(jEdit.getActiveView(),
jEdit.getProperty("options.editing.deleteMode.dialog.message1") + ' ' + m.getProperty("file") +
'\n' + jEdit.getProperty("options.editing.deleteMode.dialog.message2") + ' ' + m.getName());
}
}
}
reloadLists(null);
}
}
}
);
addComponent( pingPongList, BOTH );
addSeparator();
// add mode panel
addComponent( new JLabel( jEdit.getProperty( "options.editing.addMode.dialog.title", "Add Mode" ) ) );
JPanel content = new JPanel( new BorderLayout() );
content.setBorder( BorderFactory.createEmptyBorder( 12, 12, 11, 11 ) );
addComponent( content );
// main content
AbstractOptionPane mainContent = new AbstractOptionPane( "addmode" );
mainContent.setBorder( BorderFactory.createEmptyBorder( 0, 0, 0, 0 ) );
modeName = new JTextField( 36 );
mainContent.addComponent( jEdit.getProperty( "options.editing.addMode.dialog.modeName" ), modeName );
modeFile = new JTextField();
browse = new JButton( "..." );
browse.addActionListener( new ActionHandler() );
JPanel browsePanel = new JPanel( new BorderLayout() );
browsePanel.add( modeFile, BorderLayout.CENTER );
browsePanel.add( browse, BorderLayout.EAST );
mainContent.addComponent( jEdit.getProperty( "options.editing.addMode.dialog.modeFile" ), browsePanel );
filenameGlob = new JTextField( 36 );
mainContent.addComponent( jEdit.getProperty( "options.editing.addMode.dialog.filenameGlob" ), filenameGlob );
firstLineGlob = new JTextField( 36 );
mainContent.addComponent( jEdit.getProperty( "options.editing.addMode.dialog.firstLineGlob" ), firstLineGlob );
content.add( mainContent );
// buttons
JPanel buttons = new JPanel();
buttons.setLayout( new BoxLayout( buttons, BoxLayout.X_AXIS ) );
buttons.setBorder( BorderFactory.createEmptyBorder( 17, 0, 0, 6 ) );
ok = new JButton( jEdit.getProperty("options.editing.addMode", "Add Mode" ));
ok.addActionListener( new ActionHandler() );
buttons.add( Box.createGlue() );
buttons.add( ok );
content.add( BorderLayout.SOUTH, buttons );
addComponent( content );
} //}}}
private Mode[] loadSelectedModes()
{
Mode[] modes = jEdit.getModes();
Arrays.sort( modes, new StandardUtilities.StringCompare<Mode>( true ) );
return modes;
}
// returns all modes
private Mode[] loadAllModes()
{
Mode[] modes = jEdit.getAllModes();
Arrays.sort( modes, new StandardUtilities.StringCompare<Mode>( true ) );
return modes;
}
// {{{ _save() method
@Override
protected void _save()
{
jEdit.setProperty( "buffer.defaultMode",
( ( Mode )defaultMode.getSelectedItem() ).getName() );
Iterator<Mode> available = pingPongList.getLeftDataIterator();
while ( available.hasNext() ) {
Mode mode = available.next();
jEdit.setBooleanProperty( "mode.opt-out." + mode.getName(), true );
}
Iterator<Mode> selected = pingPongList.getRightDataIterator();
while ( selected.hasNext() ) {
Mode mode = selected.next();
jEdit.unsetProperty( "mode.opt-out." + mode.getName() );
}
} //}}}
private class ActionHandler implements ActionListener
{
public void actionPerformed( ActionEvent evt )
{
Object source = evt.getSource();
if ( source == browse )
{
View view = jEdit.getActiveView();
String path = jEdit.getSettingsDirectory();
int type = VFSBrowser.OPEN_DIALOG;
boolean multiSelect = false;
String[] filename = GUIUtilities.showVFSFileDialog( view, path, type, multiSelect );
if ( filename != null && filename.length > 0 )
{
modeFile.setText( filename[0] );
}
else
{
modeFile.setText( "" );
}
}
else
if ( source == ok )
{
ok();
}
}
}
public String getModeName()
{
return modeName.getText();
}
public String getModeFile()
{
return modeFile.getText();
}
public String getFilenameGlob()
{
return filenameGlob.getText();
}
public String getFirstLineGlob()
{
return firstLineGlob.getText();
}
public void ok()
{
// check values
String modeName = getModeName();
if ( modeName == null || modeName.isEmpty() )
{
JOptionPane.showMessageDialog( jEdit.getActiveView(), jEdit.getProperty( "options.editing.addMode.dialog.Mode_name_may_not_be_empty.", "Mode name may not be empty." ), jEdit.getProperty( "options.editing.addMode.dialog.errorTitle", "Error" ), JOptionPane.ERROR_MESSAGE );
return;
}
String modeFile = getModeFile();
if ( modeFile == null || modeFile.isEmpty() )
{
JOptionPane.showMessageDialog( jEdit.getActiveView(), jEdit.getProperty( "options.editing.addMode.dialog.Mode_file_may_not_be_empty.", "Mode file may not be empty." ), jEdit.getProperty( "options.editing.addMode.dialog.errorTitle", "Error" ), JOptionPane.ERROR_MESSAGE );
return;
}
String filenameGlob = getFilenameGlob();
String firstLineGlob = getFirstLineGlob();
if ( ( filenameGlob == null || filenameGlob.isEmpty() ) && ( firstLineGlob == null || firstLineGlob.isEmpty() ) )
{
JOptionPane.showMessageDialog( jEdit.getActiveView(), jEdit.getProperty( "options.editing.addMode.dialog.Either_file_name_glob_or_first_line_glob_or_both_must_be_filled_in.", "Either file name glob or first line glob or both must be filled in." ), jEdit.getProperty( "options.editing.addMode.dialog.errorTitle", "Error" ), JOptionPane.ERROR_MESSAGE );
return;
}
boolean exists = jEdit.getMode( modeName ) != null;
if ( exists )
{
int answer = JOptionPane.showConfirmDialog( EditModesPane.this, jEdit.getProperty( "options.editing.addMode.dialog.warning.message" ), jEdit.getProperty( "options.editing.addMode.dialog.warning.title" ) + " " + modeName, JOptionPane.YES_NO_OPTION );
if ( JOptionPane.YES_OPTION != answer )
{
return;
}
}
// create mode and set properties from dialog values
Mode newMode = new Mode( modeName );
newMode.setProperty( "file", modeFile );
newMode.setProperty( "filenameGlob", filenameGlob );
newMode.setProperty( "firstlineGlob", firstLineGlob );
File file = new File( modeFile );
Path target = FileSystems.getDefault().getPath( jEdit.getSettingsDirectory(), "modes", file.getName() );
try
{
ModeProvider.instance.addUserMode( newMode, target );
}
catch ( IOException e )
{
JOptionPane.showMessageDialog( jEdit.getActiveView(), jEdit.getProperty( "options.editing.addMode.dialog.warning.message1" ) + " " + modeFile + "\n--> " + target );
}
// refresh the mode dropdown so the new mode is in the list
jEdit.reloadModes();
// add the new mode to the selected list
reloadLists( newMode );
}
private void reloadLists( Mode newMode )
{
// load the ping pong lists
List<Mode> selectedModes = new ArrayList<Mode>();
List<Mode> availableModes = new ArrayList<Mode>();
Mode[] modes = loadAllModes();
for ( Mode mode : modes ) {
boolean selected = !jEdit.getBooleanProperty( "mode.opt-out." + mode.getName(), false );
if ( selected )
{
selectedModes.add( mode );
}
else
{
availableModes.add( mode );
}
}
pingPongList.setLeftData( availableModes );
pingPongList.setRightData( selectedModes );
if ( newMode != null )
{
pingPongList.setRightSelected( newMode );
}
// reload the default mode combo box
defaultMode.setModel( new DefaultComboBoxModel<Mode>( loadSelectedModes() ) );
defaultMode.setSelectedItem( jEdit.getMode( jEdit.getProperty( "buffer.defaultMode" ) ) );
}
// show user modes in green
class MyCellRenderer extends JLabel implements ListCellRenderer<Mode>
{
public Component getListCellRendererComponent(
JList<? extends Mode> list,
Mode value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
String s = value.toString();
setText( s );
setForeground(value.isUserMode() ? Color.GREEN : isSelected ? list.getSelectionForeground() : list.getForeground());
setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
setOpaque( true );
return this;
}
}
// enable/disable the delete button based on selection
class MyListSelectionListener implements ListSelectionListener
{
public void valueChanged(ListSelectionEvent e)
{
List<Mode> modes = pingPongList.getRightSelectedValues();
boolean enabled = false;
for (Mode m : modes)
{
if (m.isUserMode())
{
enabled = true;
break;
}
}
deleteSelectedButton.setEnabled(enabled);
}
}
}