/**
* Copyright (c) 2005-2017, KoLmafia development team
* http://kolmafia.sourceforge.net/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* [1] Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* [2] Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* [3] Neither the name "KoLmafia" nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.sourceforge.kolmafia.swingui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTextPane;
import javax.swing.ListSelectionModel;
import javax.swing.ToolTipManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.JTextComponent;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import net.java.dev.spellcast.utilities.JComponentUtilities;
import net.sourceforge.kolmafia.persistence.Script;
import net.sourceforge.kolmafia.persistence.ScriptManager;
import net.sourceforge.kolmafia.swingui.menu.ThreadedMenuItem;
import net.sourceforge.kolmafia.swingui.panel.GenericPanel;
import net.sourceforge.kolmafia.swingui.widget.AutoFilterTextField;
import net.sourceforge.kolmafia.swingui.widget.GenericScrollPane;
import net.sourceforge.kolmafia.swingui.widget.ShowDescriptionTable;
public class ScriptManageFrame
extends GenericPanelFrame
{
private class ScriptManageTable
extends ShowDescriptionTable
{
public ScriptManageTable()
{
super( ScriptManager.getInstalledScripts(), 4, 4 );
ScriptManageFrame.doColumnSetup( this );
ScriptManageFrame.doHighlighterSetup( this );
this.contextMenu.removeAll();
ThreadedMenuItem t = new ThreadedMenuItem( "Delete script", new DeleteScriptRunnable( this ) );
t.setIcon( JComponentUtilities.getImage( "xred.gif" ) );
this.contextMenu.add( t );
this.contextMenu.add( new JSeparator() );
t = new ThreadedMenuItem( "Open forum thread", new ShowThreadRunnable( this ) );
t.setIcon( JComponentUtilities.getImage( "home.gif" ) );
this.contextMenu.add( t );
t = new ThreadedMenuItem( "Refresh script list", new RefreshScriptsRunnable() );
t.setIcon( JComponentUtilities.getImage( "reload.gif" ) );
this.contextMenu.add( t );
this.contextMenu.add( new ThreadedMenuItem( "Update this script", new UpdateScriptRunnable( this, false ) ) );
this.contextMenu.add( new ThreadedMenuItem( "Update all scripts", new UpdateScriptRunnable( this, true ) ) );
}
}
private class RepoManageTable
extends ShowDescriptionTable
{
public RepoManageTable()
{
super( ScriptManager.getRepoScripts(), 4, 4 );
ScriptManageFrame.doColumnSetup( this );
ScriptManageFrame.doHighlighterSetup( this );
this.contextMenu.removeAll();
ThreadedMenuItem t = new ThreadedMenuItem( "Install script", new InstallScriptRunnable( this ) );
t.setIcon( JComponentUtilities.getImage( "icon_plus.gif" ) );
this.contextMenu.add( t );
this.contextMenu.add( new JSeparator() );
t = new ThreadedMenuItem( "Open forum thread", new ShowThreadRunnable( this ) );
t.setIcon( JComponentUtilities.getImage( "home.gif" ) );
this.contextMenu.add( t );
t = new ThreadedMenuItem( "Reload remote repository", new ReloadRepoRunnable() );
t.setIcon( JComponentUtilities.getImage( "reload.gif" ) );
this.contextMenu.add( t );
}
}
private final ScriptManageTable scriptTable = new ScriptManageTable();
private RepoManageTable repoTable = new RepoManageTable();
public ScriptManageFrame()
{
super( "Script Manager" );
this.tabs.add( "Manage", new ManageScriptsPanel() );
this.tabs.add( "Install", new InstallScriptsPanel() );
this.setCenterComponent( this.tabs );
}
private class InstallScriptsPanel
extends GenericPanel
{
public InstallScriptsPanel()
{
super( new Dimension( 1, 1 ), null, true );
GenericScrollPane manageScroller = new GenericScrollPane( ScriptManageFrame.this.repoTable );
JPanel top = layoutTopPanel();
JTextPane textPane = new JTextPane();
textPane.setContentType( "text/html" );
textPane.setText( "<html>Select a script for more details</html>" );
textPane.setBorder( BorderFactory.createEtchedBorder() );
textPane.setEditable( false );
textPane.setMinimumSize( new Dimension( 0, 0 ) ); //allow JSplitPane to be squished all the way down
ScriptManageFrame.this.repoTable.getSelectionModel().addListSelectionListener( new LongDescriptionListener(
ScriptManageFrame.this.repoTable, textPane ) );
this.setContent( this.elements, true );
this.container.remove( this.eastContainer );
JSplitPane splitter = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, manageScroller, textPane );
splitter.setBorder( null );
splitter.setResizeWeight( .7d ); //table gets 70% space by default
this.container.add( top, BorderLayout.NORTH );
this.container.add( splitter, BorderLayout.CENTER );
}
private JPanel layoutTopPanel()
{
JPanel top = new JPanel( new BorderLayout() );
JPanel topInnerLeft = new JPanel( new FlowLayout( FlowLayout.LEFT ) );
top.add( topInnerLeft, BorderLayout.WEST );
JPanel topInnerRight = new JPanel( new BorderLayout() );
top.add( topInnerRight, BorderLayout.EAST );
JLabel baseLabel = new JLabel( "<html>Install new scripts from SVN here. </html>" );
topInnerLeft.add( baseLabel );
JLabel helpLabel = new JLabel( "<html><u>Hover for more info.</u></html>" );
topInnerLeft.add( helpLabel );
helpLabel.setForeground( Color.blue.darker() );
helpLabel.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
top.add( Box.createVerticalStrut( 25 ), BorderLayout.CENTER );
JLabel label = new JLabel( "Search: " );
topInnerRight.add( label, BorderLayout.WEST );
JComponent filter = new AutoFilterTextField( ScriptManageFrame.this.repoTable.getDisplayModel() );
filter.setPreferredSize( new Dimension( 150, filter.getPreferredSize().height ) );
topInnerRight.add( filter, BorderLayout.CENTER );
String tooltip = "<html>On this panel you can install community-created scripts.<br>"
+ "Scripts so installed will automatically receive available updates when you perform the \"svn update\" command<br>"
+ "(which can be set to automatically run on login - look in General > Preferences > SVN).<br><br>"
+ "Notable things you can do here:<br>"
+ "<ul><li>Click a header column to sort ascending/descending</li>"
+ "<li>Left-click a script to see more details on the bottom panel</li>"
+ "<li>Right-click to install, go to the author's kolmafia.us forum thread, and/or see additional options</li></ul></html>";
helpLabel.setToolTipText( tooltip );
// remove delay and fade from tooltip
ToolTipManager.sharedInstance().registerComponent( helpLabel );
ToolTipManager.sharedInstance().setInitialDelay( 0 );
ToolTipManager.sharedInstance().setDismissDelay( Integer.MAX_VALUE );
return top;
}
@Override
public void actionConfirmed()
{
}
@Override
public void actionCancelled()
{
}
}
private class LongDescriptionListener
implements ListSelectionListener
{
private JTextComponent comp;
private JXTable table;
public LongDescriptionListener( JXTable table, JTextComponent comp )
{
this.table = table;
this.comp = comp;
}
public void valueChanged( ListSelectionEvent e )
{
int row = table.getSelectedRow();
if ( row < 0 ) // this can happen during sorting, seems buggy to me...
return;
Object ob = table.getValueAt( row, 0 );
if ( ob instanceof Script )
{
comp.setText( ( (Script) ob ).getLongDesc() );
}
}
}
private class ManageScriptsPanel
extends GenericPanel
{
public ManageScriptsPanel()
{
super( new Dimension( 1, 1 ), null, true );
GenericScrollPane manageScroller = new GenericScrollPane( ScriptManageFrame.this.scriptTable );
JPanel top = new JPanel( new BorderLayout() );
JLabel baseLabel = new JLabel( "<html>Manage current SVN-installed scripts. Right click for options." );
top.add( baseLabel, BorderLayout.WEST );
top.add( Box.createVerticalStrut( 25 ) );
JPanel managePanel = new JPanel( new BorderLayout() );
managePanel.add( manageScroller, BorderLayout.CENTER );
JTextPane textPane = new JTextPane();
textPane.setContentType( "text/html" );
textPane.setText( "<html>Select a script for more details</html>" );
textPane.setBorder( BorderFactory.createEtchedBorder() );
textPane.setEditable( false );
textPane.setMinimumSize( new Dimension( 0, 0 ) ); //allow JSplitPane to be squished all the way down
ScriptManageFrame.this.scriptTable.getSelectionModel().addListSelectionListener( new LongDescriptionListener(
ScriptManageFrame.this.scriptTable, textPane ) );
this.setContent( this.elements, true );
this.container.remove( this.eastContainer );
JSplitPane splitter = new JSplitPane( JSplitPane.VERTICAL_SPLIT, true, manageScroller, textPane );
splitter.setBorder( null );
splitter.setResizeWeight( .7d );
JComponentUtilities.setComponentSize( splitter, 640, 550 );
this.container.add( top, BorderLayout.NORTH );
this.container.add( splitter, BorderLayout.CENTER );
}
@Override
public void actionConfirmed()
{
ScriptManager.updateInstalledScripts();
}
@Override
public void actionCancelled()
{
}
}
private static void doColumnSetup( ShowDescriptionTable table )
{
table.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
//some magic numbers, enjoy
table.getColumnModel().getColumn( 0 ).setPreferredWidth( 150 );
table.getColumnModel().getColumn( 1 ).setPreferredWidth( 100 );
table.getColumnModel().getColumn( 2 ).setPreferredWidth( 250 );
table.getColumnModel().getColumn( 3 ).setPreferredWidth( 80 );
//no reordering of columns, that's just silly
table.getTableHeader().setReorderingAllowed( false );
}
public static void doHighlighterSetup( JXTable t )
{
// light gray/blue
t.addHighlighter( HighlighterFactory.createSimpleStriping( new Color( 230, 240, 240 ) ) );
}
}