/* PANDA -- a simple transaction monitor
Copyright (C) 1998-1999 Ogochan.
2000-2003 Ogochan & JMA (Japan Medical Association).
2002-2006 OZAWA Sakuro.
This module is part of PANDA.
PANDA is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves
any particular purpose or works at all, unless he says so in writing.
Refer to the GNU General Public License for full details.
Everyone is granted permission to copy, modify and redistribute
PANDA, but only under the conditions described in the GNU General
Public License. A copy of this license is supposed to have been given
to you along with PANDA so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
copies.
*/
package org.montsuqi.monsia;
import java.util.LinkedList;
import java.util.Map;
import org.xml.sax.Attributes;
/**
* SAX document handler which parses interface definition by Glade version 1.
*/
public class Glade1Handler extends AbstractDocumentHandler {
private final LinkedList<WidgetInfo> pendingWidgets;
String signalName;
String signalHandler;
String signalObject;
boolean signalAfter;
int accelKey;
int accelModifiers;
String accelSignal;
WidgetInfo getLastPendingWidget() {
return (WidgetInfo) pendingWidgets.getLast();
}
void initializeWidgetInfo() {
WidgetInfo w = new WidgetInfo();
WidgetInfo parent = null;
if (pendingWidgets.size() > 0) {
parent = getLastPendingWidget();
final ChildInfo childInfo = new ChildInfo();
childInfo.setWidgetInfo(w);
parent.addChild(childInfo);
}
w.setParent(parent);
pendingWidgets.add(w);
}
void flushWidgetInfo() {
WidgetInfo w = getLastPendingWidget();
dialogHack(w);
pendingWidgets.removeLast();
widgets.put(w.getName(), w);
if (pendingWidgets.size() == 0) {
topLevels.add(w);
state = GTK_INTERFACE;
} else {
WidgetInfo parent = getLastPendingWidget();
ChildInfo childInfo = parent.getLastChild();
// x, y property should go to childinfo
Map widgetProperties = w.getProperties();
if (widgetProperties.containsKey("x")) {
childInfo.addProperty("x", (String) widgetProperties.get("x")); //$NON-NLS-2$
//widgetProperties.remove("x");
}
if (widgetProperties.containsKey("y")) {
childInfo.addProperty("y", (String) widgetProperties.get("y")); //$NON-NLS-2$
//widgetProperties.remove("y");
}
}
propertyName = null;
properties.clear();
signals.clear();
accels.clear();
}
public Glade1Handler() {
super();
startState = START;
pendingWidgets = new LinkedList<>();
}
@Override
protected boolean shouldAppendCharactersToContent() {
return state == WIDGET_ATTRIBUTE
|| state == WIDGET_CHILD_ATTRIBUTE
|| state == SIGNAL_ATTRIBUTE
|| state == ACCELERATOR_ATTRIBUTE
|| state == STYLE_ATTRIBUTE
|| state == PREVIEW;
}
void noElementHere(String inner) {
warnUnexpectedElement(state.getName(), inner);
prevState = state;
state = UNKNOWN;
unknownDepth++;
}
final ParserState START = new ParserState("START") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
if (!localName.equals("GTK-Interface")) {
warnUnexpectedElement("<null>", localName);
}
state = GTK_INTERFACE;
}
@Override
void endElement(String uri, String localName, String qName) {
logger.warn("should not be closing any elements in this state");
}
};
final ParserState GTK_INTERFACE = new ParserState("GTK_INTERFACE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
if (localName.equals("widget")) {
state = WIDGET;
initializeWidgetInfo();
} else if (localName.equals("style")) {
state = STYLE;
// ignore style stuff in Java
} else {
prevState = state;
state = UNKNOWN;
unknownDepth++;
}
}
@Override
void endElement(String uri, String localName, String qName) {
state = FINISH;
}
};
final ParserState WIDGET = new ParserState("WIDGET") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
if (localName.equals("style")) {
state = STYLE;
// ignore all style stuff in Java
} else if (localName.equals("accelerator") || localName.equals("Accelerator")) { //$NON-NLS-2$
state = ACCELERATOR;
} else if (localName.equals("signal") || localName.equals("Signal")) { //$NON-NLS-2$
state = SIGNAL;
} else if (localName.equals("child")) {
// the child section
state = WIDGET_CHILD;
} else if (localName.equals("widget")) {
initializeWidgetInfo();
} else if (localName.equals("preview") || localName.equals("Preview")) {
state = PREVIEW;
} else {
propertyType = PropertyType.WIDGET;
propertyName = localName;
state = WIDGET_ATTRIBUTE;
clearContent();
}
}
@Override
void endElement(String uri, String localName, String qName) {
if (localName.equals("widget")) {
flushWidgetInfo();
}
}
};
final ParserState WIDGET_ATTRIBUTE = new ParserState("WIDGET_ATTRIBUTE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
noElementHere(localName);
}
@Override
void endElement(String uri, String localName, String qName) {
state = WIDGET;
String value = content.toString();
WidgetInfo w = getLastPendingWidget();
if (localName.equals("class")) {
if (value.startsWith("Gtk")) {
value = value.substring("Gtk".length());
} else if (value.startsWith("Gnome")) {
value = value.substring("Gnome".length());
}
w.setClassName(value);
} else if (localName.equals("name")) {
w.setName(value);
} else if (localName.equals("visible")) {
w.addProperty("visible", content.charAt(0) == 'T' ? "true" : "false"); //$NON-NLS-2$ //$NON-NLS-3$
} else if (localName.equals("sensitive")) {
w.addProperty("sensitive", content.charAt(0) == 'T' ? "true" : "false"); //$NON-NLS-2$ //$NON-NLS-3$
} else if (localName.equals("can_default")) {
w.addProperty("can_default", content.charAt(0) == 'T' ? "true" : "false"); //$NON-NLS-2$ //$NON-NLS-3$
} else if (localName.equals("can_focus")) {
w.addProperty("can_focus", content.charAt(0) == 'T' ? "true" : "false"); //$NON-NLS-2$ //$NON-NLS-3$
} else if (localName.equals("has_default")) {
w.addProperty("has_default", content.charAt(0) == 'T' ? "true" : "false"); //$NON-NLS-2$ //$NON-NLS-3$
} else if (localName.equals("has_focus")) {
w.addProperty("has_focus", content.charAt(0) == 'T' ? "true" : "false"); //$NON-NLS-2$ //$NON-NLS-3$
} else if (localName.equals("style_name")) {
// ignore
} else {
// some other attribute
w.addProperty(propertyName, value);
}
}
};
final ParserState WIDGET_CHILD = new ParserState("WIDGET_CHILD") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
propertyType = PropertyType.CHILD;
propertyName = localName;
state = WIDGET_CHILD_ATTRIBUTE;
clearContent();
}
@Override
void endElement(String uri, String localName, String qName) {
WidgetInfo w = getLastPendingWidget();
WidgetInfo parent = w.getParent();
ChildInfo childInfo = parent.getLastChild();
childInfo.setProperties(properties);
properties.clear();
state = WIDGET;
}
};
final ParserState WIDGET_CHILD_ATTRIBUTE = new ParserState("WIDGET_CHILD_ATTRIBUTE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
noElementHere(localName);
}
@Override
void endElement(String uri, String localName, String qName) {
properties.put(propertyName, content.toString());
state = WIDGET_CHILD;
}
};
final ParserState SIGNAL = new ParserState("SIGNAL") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
state = SIGNAL_ATTRIBUTE;
clearContent();
}
@Override
void endElement(String uri, String localName, String qName) {
state = WIDGET;
SignalInfo signal = new SignalInfo(signalName, signalHandler, signalObject, signalAfter);
signalName = "";
signalHandler = "";
signalObject = "";
signalAfter = false;
WidgetInfo w = getLastPendingWidget();
w.addSignalInfo(signal);
}
};
final ParserState SIGNAL_ATTRIBUTE = new ParserState("SIGNAL_ATTRIBUTE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
noElementHere(localName);
}
@Override
void endElement(String uri, String localName, String qName) {
state = SIGNAL;
String value = content.toString();
if (localName.equals("name")) {
signalName = value;
} else if (localName.equals("handler")) {
signalHandler = value;
} else if (localName.equals("data")) {
signalObject = value;
} else if (localName.equals("after")) {
signalAfter = value.charAt(0) == 'T';
}
}
};
final ParserState ACCELERATOR = new ParserState("ACCELERATOR") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
state = ACCELERATOR_ATTRIBUTE;
clearContent();
}
@Override
void endElement(String uri, String localName, String qName) {
state = WIDGET;
if (accelKey != 0) {
AccelInfo accel = new AccelInfo(accelKey, accelModifiers, accelSignal);
WidgetInfo w = getLastPendingWidget();
w.addAccelInfo(accel);
} else {
logger.warn("accelerator ignored");
}
}
};
final ParserState ACCELERATOR_ATTRIBUTE = new ParserState("ACCELERATOR_ATTRIBUTE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
noElementHere(localName);
}
@Override
void endElement(String uri, String localName, String qName) {
state = ACCELERATOR;
String value = content.toString();
if (localName.equals("key") && value.startsWith("GDK_")) { //$NON-NLS-2$
accelKey = keyCode(value);
} else if (localName.equals("modifiers")) {
accelModifiers = parseModifiers(value);
} else if (localName.equals("signal")) {
accelSignal = value;
}
}
};
final ParserState STYLE = new ParserState("STYLE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
state = STYLE_ATTRIBUTE;
clearContent();
}
@Override
void endElement(String uri, String localName, String qName) {
// ignore all style stuff in Java
}
};
final ParserState STYLE_ATTRIBUTE = new ParserState("STYLE_ATTRIBUTE") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
noElementHere(localName);
}
@Override
void endElement(String uri, String localName, String qName) {
state = STYLE;
// ignore all style stuff in Java
}
};
final ParserState PREVIEW = new ParserState("PREVIEW") {
@Override
void startElement(String uri, String localName, String qName, Attributes attrs) {
noElementHere(localName);
}
@Override
void endElement(String uri, String localName, String qName) {
WidgetInfo w = getLastPendingWidget();
String value = content.toString();
w.addProperty("do_preview", value.charAt(0) == 'T' ? "true" : "false");
state = WIDGET;
}
};
}