package com.applang.berichtsheft.plugin;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.border.Border;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.JTextComponent;
import org.gjt.sp.jedit.BeanShell;
import org.gjt.sp.jedit.Buffer;
import org.gjt.sp.jedit.EditPane;
import org.gjt.sp.jedit.GUIUtilities;
import org.gjt.sp.jedit.MiscUtilities;
import org.gjt.sp.jedit.View;
import org.gjt.sp.jedit.jEdit;
import org.gjt.sp.jedit.EditBus.EBHandler;
import org.gjt.sp.jedit.gui.DockableWindowManager;
import org.gjt.sp.jedit.msg.BufferChanging;
import org.gjt.sp.jedit.msg.ViewUpdate;
import android.app.Activity;
import android.app.AlertDialog;
import android.util.Log;
import com.applang.Util.Constraint;
import com.applang.components.AndroidBridge;
import com.applang.components.DataConfiguration;
import com.applang.components.DataManager;
import com.applang.components.DataView;
import com.applang.components.DoubleFeaturePlugin;
import com.applang.components.ManagerBase;
import com.applang.components.TextEdit;
import com.applang.components.TextToggle;
import static com.applang.Util.*;
import static com.applang.Util2.*;
import static com.applang.SwingUtil.*;
import static com.applang.PluginUtils.*;
/**
* The Berichtsheft Plugin
*
*/
public class BerichtsheftPlugin extends DoubleFeaturePlugin
{
public static final String TAG = BerichtsheftPlugin.class.getSimpleName();
public static final String NAME = "berichtsheft";
public static final String OPTION_PREFIX = join(".", "options", NAME, "");
public static final String MENU = "plugin.com.applang.berichtsheft.plugin.BerichtsheftPlugin.menu";
public static final String CMD_PATH = "/com/applang/berichtsheft/plugin/bsh/";
@Override
public void start() {
super.start();
loadSettings();
setupSpellChecker(System.getProperty("settings.dir"));
BeanShell.getNameSpace().addCommandPath(CMD_PATH, getClass());
BerichtsheftToolBar.init();
// checkAvailabilityOfTools();
}
@Override
public void stop() {
super.stop();
BeanShell.getNameSpace().removeCommandPath(CMD_PATH, getClass());
BerichtsheftToolBar.remove();
Settings.save();
}
@EBHandler
@Override
public void handleViewUpdate(ViewUpdate msg)
{
super.handleViewUpdate(msg);
view = msg.getView();
if (msg.getWhat() == ViewUpdate.CREATED) {
BerichtsheftToolBar.create(view);
Activity.frame = view;
}
else if (msg.getWhat() == ViewUpdate.CLOSED) {
BerichtsheftToolBar.remove(view);
view = null;
}
}
@Override
protected boolean setGutterBorder(Component component, Border border) {
if (component instanceof DataManager.DataPanel) {
DataManager.DataPanel dp = (DataManager.DataPanel) component;
dp.getGutter().setBorder(border);
return true;
}
else
return super.setGutterBorder(component, border);
}
@Override
protected JComponent featuredWidget(JComponent widget, BufferChanging msg) {
if (widget instanceof DataManager.DataPanel) {
DataManager dm = ((DataManager.DataPanel)widget).getDataManager();
if (msg instanceof FeatureBufferChanging) {
InputEvent ev = ((FeatureBufferChanging)msg).inputEvent;
dm.setIndex(isCtrlKeyHeld(ev) ? 1 : 0);
}
widget = dm.getPane(dm.getIndex());
}
return widget;
}
@Override
protected JComponent constructFeature(final Buffer buffer, String feature, JComponent container, Object...params) throws IOException {
container = super.constructFeature(buffer, feature, container, params);
if (feature.startsWith("data")) {
buffer.setAutoReloadDialog(false);
buffer.setAutoReload(true);
Properties props = param(new Properties(), 1, params);
String text = buffer.getText();
props.load(new StringReader(text));
MouseListener focusRequestListener = param(null, 0, params);
DataManager dm = new DataManager(view, props, buffer.getName(), focusRequestListener);
container = dm.getPane(0);
}
else {
if (feature.startsWith("spell")) {
TextEdit textEdit = new TextEdit();
addNamePart(textEdit.getTextComponent(), DoubleFeature.FOCUS);
textEdit.installSpellChecker();
textEdit.setText(buffer.getText());
container = new JPanel(new BorderLayout());
addCenterComponent(textEdit.getComponent(), container);
if (feature.equals("spellcheck")) {
final JToolBar bar = northToolBar(container, BorderLayout.SOUTH);
bar.add(new ManagerBase<Object>() {
{
createButton(bar,
ACCEPT_BUTTON_KEY,
new ActionListener() {
public void actionPerformed(ActionEvent e) {
EditPane[] editPanes = getEditPanesFor(buffer);
if (editPanes.length > 0) {
DoubleFeature df = doubleFeatures.get(editPanes[0]);
JTextComponent textComponent = (JTextComponent)
findFirstComponent(df.getWidget(),
DoubleFeature.FOCUS, Constraint.AMONG);
df.getTextArea2().setText(textComponent.getText());
}
removeFeature(buffer);
bufferChange(buffer);
}
});
createButton(bar,
REJECT_BUTTON_KEY,
new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeFeature(buffer);
bufferChange(buffer);
}
});
}
});
}
}
else {
container = jEdit.getActiveView().getEditPane().getTextArea();
addNamePart(container, DoubleFeature.FOCUS);
}
installFocusClickListener(container);
}
return container;
}
@Override
protected void deconstructFeature(String feature, JComponent container) {
if (!feature.startsWith("data")) {
installFocusClickListener(container, false);
removeNamePart(container, DoubleFeature.FOCUS);
}
}
public static void installDataManager(EditPane editPane) {
final DoubleFeature doubleFeature = registerPane(editPane);
if (doubleFeature != null) {
Properties props = new Properties();
if (DataConfiguration.dataProperties(editPane.getView(), props)) {
String path = featureFile(getNextFeatureTemp(), "data-manage", props);
jEdit.openFile(editPane, path);
}
}
}
public static void loadSettings() {
String settingsDir = jEdit.getSettingsDirectory();
if (settingsDir == null)
settingsDir = tempPath();
File dir = fileOf(settingsDir, "plugins", NAME);
dir.mkdirs();
String path = MiscUtilities.constructPath(settingsDir, "console");
path = MiscUtilities.constructPath(path, "commando");
File file = new File(path);
if (!file.exists())
file.mkdirs();
BerichtsheftToolBar.userCommandDirectory = path;
path = dir.getPath();
System.setProperty("settings.dir", path);
Settings.load(pathCombine(path, NAME + ".properties"));
path = pathCombine(settingsDir, "jars", "sqlite4java");
System.setProperty("sqlite4java.library.path", path);
}
// NOTE used in scripts
public static void spellcheckSelection(View view) {
final TextToggle jEditor = getJEditor();
String text = jEditor.getSelectedText();
if (nullOrEmpty(text)) {
consoleMessage("berichtsheft.no-text-selection.message");
return;
}
final TextToggle textToggle = new TextToggle();
textToggle.setText(text);
Job<Void> takeThis = new Job<Void>() {
public void perform(Void t, Object[] params) throws Exception {
String text = textToggle.getText();
jEditor.setSelectedText(text);
}
};
textToggle.getTextEdit().installSpellChecker();
Component component = textToggle.getUIComponent();
component.setPreferredSize(new Dimension(400,300));
new AlertDialog(view,
getProperty("berichtsheft.spellcheck-selection.title"),
"",
component,
JOptionPane.OK_CANCEL_OPTION,
Behavior.MODAL,
loadIcon("manager.action-SPELLCHECK.icon"),
takeThis)
.open();
textToggle.getTextEdit().uninstallSpellChecker();
}
public static String getOptionProperty(String name) {
return getProperty(BerichtsheftPlugin.OPTION_PREFIX + name);
}
public static void setOptionProperty(String name, String value) {
setProperty(BerichtsheftPlugin.OPTION_PREFIX + name, value);
}
public static void print(Object... params) {
if (insideJEdit())
BerichtsheftShell.print(params);
else
com.applang.Util2.print(params);
}
public static void consoleMessage(String key, Object...params) {
String format = getProperty(key);
String msg = notNullOrEmpty(format) ?
String.format(format, params) :
String.format("<<< message text missing for key '%s'>>>", key) + com.applang.Util.toString(params);
print(msg, NEWLINE);
}
public static TextToggle getJEditor() {
return new TextToggle(jEdit.getActiveView());
}
public static JComponent getDockable(View view, String name, boolean add) {
DockableWindowManager wm = view.getDockableWindowManager();
if (add)
wm.addDockableWindow(name);
return wm.getDockableWindow(name);
}
public static void showDockable(View view, String name) {
DockableWindowManager wm = view.getDockableWindowManager();
wm.showDockableWindow(name);
}
// NOTE used in scripts
public static void checkAvailabilityOfTools() {
print("Welcome...", NEWLINE);
print("settings.dir", System.getProperty("settings.dir"), NEWLINE);
print("jedit.settings.dir", getSettingsDirectory(), NEWLINE);
print("temp.dir", tempPath(), NEWLINE);
String[] tools = {"AWK_COMMAND", "ADB_COMMAND", "SQLITE_COMMAND"};
for (int i = 0; i < tools.length; i++) {
no_println(i, tools[i]);
String cmd = getCommand(tools[i]);
no_println(i, cmd);
if (!fileExists(cmd)) {
if (nullOrEmpty(runShellScript("which", "which " + cmd)))
consoleMessage("berichtsheft.tool-missing.message", cmd);
}
else if (tools[i].startsWith("ADB")) {
String msg = AndroidBridge.adbRestart();
print(msg, NEWLINE);
}
}
}
public static String getCommand(String path) {
String cmd = getProperty(path);
no_println(path, cmd);
if (!cmd.startsWith(PATH_SEP) && cmd.contains(PATH_SEP)) {
String sdk = getProperty("ANDROID_SDK");
no_println("ANDROID_SDK", sdk);
cmd = pathCombine(System.getProperty("user.home"), sdk, cmd);
}
return cmd;
}
public static Function<File> fileChooser(final View view) {
return new Function<File>() {
public File apply(Object... params) {
boolean toOpen = param(true, 0, params);
Container parent = param(null, 1, params);
String title = param(null, 2, params);
File file = param(null, 3, params);
String fileName = file == null ? null : file.getPath();
FileFilter filter = param(null, 4, params);
String[] paths = view != null ?
GUIUtilities.showVFSFileDialog(view, fileName,
toOpen ? JFileChooser.OPEN_DIALOG : JFileChooser.SAVE_DIALOG,
false) :
chooseFileNames(toOpen, parent, title, fileName, filter);
if (isAvailable(0, paths))
return new File(paths[0]);
else
return null;
}
};
}
// NOTE used in scripts
public static String inquireDbFileName(View view, String fileName) {
File dbFile = DataView.chooseDb(BerichtsheftPlugin.fileChooser(view), true, fileName, true);
if (dbFile != null) {
return dbFile.getPath();
}
return null;
}
public static String sqliteScript(String db, String statement) {
String cmd = getCommand("SQLITE_COMMAND");
if (notNullOrEmpty(db))
cmd += " " + db;
cmd += " <<<\"" + statement + "\"";
return cmd;
}
public static File getTempFile(String name) {
return tempFile(name, NAME);
}
public static String jedit_test_settings() {
String subDirName = BerichtsheftPlugin.NAME;
File jarsDir = tempDir(true, subDirName, "settings", "jars");
try {
makeLinks(jarsDir, ".jedit/jars",
"BerichtsheftPlugin.jar",
"sqlite4java.jar",
"Console.jar",
"ProjectViewer.jar",
"InfoViewer.jar",
"ErrorList.jar",
"CommonControls.jar",
"kappalayout.jar");
makeLinks(jarsDir, ".jedit/jars", "sqlite4java");
File settingsDir = tempDir(false, subDirName, "settings");
makeLinks(settingsDir, ".jedit", "keymaps");
makeLinks(settingsDir, ".jedit", "macros");
makeLinks(settingsDir, ".jedit", "modes");
settingsDir = tempDir(false, subDirName, "settings", "plugins");
makeLinks(settingsDir, ".jedit/plugins", "berichtsheft");
File commandoDir = tempDir(false, subDirName, "settings", "console");
makeLinks(commandoDir, ".jedit/console", "commando");
copyFile(
new File(tempDir(false, subDirName, "settings", "plugins", "berichtsheft"), "jedit.properties"),
new File(tempDir(false, subDirName, "settings"), "properties"));
} catch (Exception e) {
Log.e(TAG, "test_jedit_settings", e);
}
return jarsDir.getParent();
}
private static DataView dataView = null;
public static DataView getDataView() {
if (dataView == null)
dataView = new DataView();
return dataView;
}
}