package org.gjt.sp.jedit.gui;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JOptionPane;
import org.gjt.sp.jedit.ActionSet;
import org.gjt.sp.jedit.Buffer;
import org.gjt.sp.jedit.EBComponent;
import org.gjt.sp.jedit.EBMessage;
import org.gjt.sp.jedit.EditAction;
import org.gjt.sp.jedit.EditBus;
import org.gjt.sp.jedit.GUIUtilities;
import org.gjt.sp.jedit.Mode;
import org.gjt.sp.jedit.View;
import org.gjt.sp.jedit.jEdit;
import org.gjt.sp.jedit.gui.DockableWindowManager.DockingLayout;
import org.gjt.sp.jedit.msg.BufferUpdate;
import org.gjt.sp.jedit.msg.EditPaneUpdate;
import org.gjt.sp.jedit.msg.ViewUpdate;
import org.gjt.sp.jedit.options.DockingOptionPane;
/** Saves and loads dockable layouts to disk
@author Shlomy Reinstein
@since jEdit 4.3pre16
*/
public class DockingLayoutManager implements EBComponent
{
private static final String SAVE_LAYOUT_FAILED = "save-layout-failed.message";
private static final String LOAD_LAYOUT_TITLE = "load-layout.title";
private static final String LOAD_LAYOUT_MESSAGE = "load-layout.message";
private static final String SAVE_LAYOUT_TITLE = "save-layout.title";
private static final String SAVE_LAYOUT_MESSAGE = "save-layout.message";
private static ActionSet actions;
private static DockingLayoutManager instance;
private Map<View, String> currentMode;
private DockingLayoutManager()
{
currentMode = new HashMap<View, String>();
}
private static boolean save(View view, String layoutName)
{
if (jEdit.getSettingsDirectory() == null)
{
GUIUtilities.error(view,"no-settings",null);
return false;
}
DockingLayout docking = view.getViewConfig().docking;
if (docking != null)
{
boolean ret = docking.saveLayout(layoutName, DockingLayout.NO_VIEW_INDEX);
if (! ret)
return false;
addAction(layoutName);
}
return true;
}
public static void saveAs(View view)
{
if (jEdit.getSettingsDirectory() == null)
{
GUIUtilities.error(view,"no-settings",null);
return;
}
String layoutName = JOptionPane.showInputDialog(view,
jEdit.getProperty(SAVE_LAYOUT_MESSAGE),
jEdit.getProperty(SAVE_LAYOUT_TITLE),
JOptionPane.QUESTION_MESSAGE);
if (layoutName == null)
return;
if (! save(view, layoutName))
JOptionPane.showMessageDialog(view, jEdit.getProperty(SAVE_LAYOUT_FAILED));
}
private static void load(View view, String layoutName)
{
if (jEdit.getSettingsDirectory() == null)
{
GUIUtilities.error(view,"no-settings",null);
return;
}
DockingLayout docking = View.getDockingFrameworkProvider().createDockingLayout();
if (docking.loadLayout(layoutName, DockingLayout.NO_VIEW_INDEX))
view.getDockableWindowManager().setDockingLayout(docking);
}
public static void load(View view)
{
if (jEdit.getSettingsDirectory() == null)
{
GUIUtilities.error(view,"no-settings",null);
return;
}
String layoutName = (String) JOptionPane.showInputDialog(view,
jEdit.getProperty(LOAD_LAYOUT_MESSAGE),
jEdit.getProperty(LOAD_LAYOUT_TITLE),
JOptionPane.QUESTION_MESSAGE,
null,
getSavedLayouts(),
null);
if (layoutName == null)
return;
load(view, layoutName);
}
private static String[] getSavedLayouts()
{
DockingLayout docking = View.getDockingFrameworkProvider().createDockingLayout();
String[] layouts = null;
if (docking != null)
layouts = docking.getSavedLayouts();
if (layouts == null)
return new String[0];
return layouts;
}
private static void addAction(String layoutName)
{
if ((actions != null) && (! actions.contains(layoutName)))
actions.addAction(new LoadPerspectiveAction(layoutName));
}
public static void init()
{
createActions();
instance = new DockingLayoutManager();
EditBus.addToBus(instance);
}
private static void createActions()
{
actions = new ActionSet("Docking Layouts");
String[] layouts = getSavedLayouts();
for (String layout: layouts)
addAction(layout);
jEdit.addActionSet(actions);
actions.initKeyBindings();
}
public static void removeActions()
{
jEdit.removeActionSet(actions);
}
private static class LoadPerspectiveAction extends EditAction
{
private static final String LOAD_PREFIX = "load-";
public LoadPerspectiveAction(String layoutName)
{
super(LOAD_PREFIX + layoutName, new String[] { layoutName });
jEdit.setTemporaryProperty(LOAD_PREFIX + layoutName + ".label", LOAD_PREFIX + layoutName);
}
@Override
public void invoke(View view)
{
DockingLayoutManager.load(view, (String) args[0]);
}
}
private boolean canChangeEditMode(EBMessage message)
{
if (message instanceof BufferUpdate)
{
BufferUpdate bu = (BufferUpdate) message;
Object what = bu.getWhat();
if ((what == BufferUpdate.CLOSED) ||
(what == BufferUpdate.CREATED) ||
(what == BufferUpdate.PROPERTIES_CHANGED))
{
return true;
}
}
else if (message instanceof EditPaneUpdate)
{
EditPaneUpdate ep = (EditPaneUpdate) message;
Object what = ep.getWhat();
if ((what == EditPaneUpdate.BUFFER_CHANGED) ||
(what == EditPaneUpdate.CREATED))
{
return true;
}
}
return false;
}
public void handleMessage(EBMessage message)
{
boolean autoLoadModeLayout = jEdit.getBooleanProperty(
DockingOptionPane.AUTO_LOAD_MODE_LAYOUT_PROP, false);
if (! autoLoadModeLayout)
return;
if (message instanceof ViewUpdate)
{
ViewUpdate vu = (ViewUpdate) message;
if (vu.getWhat() == ViewUpdate.CLOSED)
{
View view = jEdit.getActiveView();
String mode = currentMode.get(view);
saveModeLayout(view, mode);
return;
}
}
// Check for a change in the edit mode
View view = jEdit.getActiveView();
if (view == null)
return;
if (! canChangeEditMode(message))
return;
String newMode = getCurrentEditMode(view);
String mode = currentMode.get(view);
boolean sameMode =
(mode == null && newMode == null) ||
(mode != null && mode.equals(newMode));
if (! sameMode)
{
boolean autoSaveModeLayout = jEdit.getBooleanProperty(
DockingOptionPane.AUTO_SAVE_MODE_LAYOUT_PROP, false);
if (autoSaveModeLayout)
saveModeLayout(view, mode);
currentMode.put(view, newMode);
loadModeLayout(view, newMode);
}
}
private String getCurrentEditMode(View view)
{
Buffer buffer = view.getBuffer();
if (buffer == null)
return null;
Mode bufferMode = buffer.getMode();
if (bufferMode == null)
return null;
return bufferMode.getName();
}
private static final String GLOBAL_MODE = "DEFAULT";
private void saveModeLayout(View view, String mode)
{
String modeLayout = getModePerspective(mode);
if (modeLayout == null)
return;
save(view, modeLayout);
}
private void loadModeLayout(View view, String mode)
{
String modeLayout = getModePerspective(mode);
if (modeLayout == null)
return;
load(view, modeLayout);
}
public static void loadCurrentModeLayout(View view)
{
if (view == null)
return;
String mode = instance.getCurrentEditMode(view);
instance.loadModeLayout(view, mode);
}
public static void saveCurrentModeLayout(View view)
{
if (view == null)
return;
String mode = instance.getCurrentEditMode(view);
instance.saveModeLayout(view, mode);
}
private String getModePerspective(String mode)
{
if (mode == null)
mode = GLOBAL_MODE;
return "mode-" + mode;
}
}