package org.openrosa.client.view;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.openrosa.client.Context;
import org.openrosa.client.controller.ITextListener;
import org.openrosa.client.model.FormDef;
import org.openrosa.client.model.ItextModel;
import org.openrosa.client.util.Itext;
import org.openrosa.client.util.ItextLocale;
import org.openrosa.client.util.FormUtil;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.store.StoreListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ButtonGroup;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
/**
* The widget for the internationalization tab.
*
*
*/
public class TextTabWidget extends com.extjs.gxt.ui.client.widget.Composite {
private EditorGrid<ItextModel> grid;
private ContentPanel contentPanel = new ContentPanel();
private Window window = new Window();
private ColumnModel cm;
private int currentColumnIndex = 0;
private int currentRowIndex = 0;
private ITextListener listener;
private static boolean showWindow = false;
private String curSelectedRowID = "";
/** The images for the tool bar icons. */
public final Images images;
public interface Images extends ClientBundle{
ImageResource smallAdd();
ImageResource smallRemove();
}
public TextTabWidget(ITextListener listener){
this.listener = listener;
this.images = GWT.create(Images.class);
window.setMaximizable(true);
window.setHeading("Localization");
grid = new EditorGrid<ItextModel>(new ListStore<ItextModel>(), createColumnModel());
grid.setBorders(true);
grid.setStripeRows(true);
grid.setWidth(700);
contentPanel.setHeaderVisible(false);
contentPanel.setLayout(new FitLayout());
contentPanel.add(grid);
contentPanel.setWidth(700);
makeToolbar();
makeContextMenu();
window.add(contentPanel);
window.setWidth(700);
window.setMinHeight(400);
window.setMinWidth(400);
FormUtil.maximizeWidget(grid);
FormUtil.maximizeWidget(contentPanel);
window.addListener(Events.Resize, new Listener<ComponentEvent>() {
public void handleEvent(final ComponentEvent event) {
contentPanel.setWidth(window.getWidth());
}});
setupContextMenu();
FormUtil.maximizeWidget(this);
}
private void setupContextMenu() {
grid.addListener(Events.HeaderContextMenu, new Listener<GridEvent<ModelData>>(){
public void handleEvent(final GridEvent<ModelData> ge)
{
currentColumnIndex = ge.getColIndex();
MenuItem menuItem = new MenuItem("Add Language");
menuItem.addListener(Events.Select, new Listener<BaseEvent>(){
public void handleEvent(BaseEvent be)
{
addNewLanguage("Language");
}
});
ge.getMenu().add(menuItem);
if(cm.getColumnCount() > 3){
menuItem = new MenuItem("Remove Language");
menuItem.addListener(Events.Select, new Listener<BaseEvent>(){
public void handleEvent(BaseEvent be)
{
removeLanguage();
}
});
ge.getMenu().add(menuItem);
}
if(currentColumnIndex > 1){
menuItem = new MenuItem("Rename Language");
menuItem.addListener(Events.Select, new Listener<BaseEvent>(){
public void handleEvent(BaseEvent be)
{
renameLanguage(currentColumnIndex);
}
});
ge.getMenu().add(menuItem);
}
}
});
grid.addListener(Events.CellClick, new Listener<GridEvent<ModelData>>(){
public void handleEvent(final GridEvent<ModelData> ge)
{
currentColumnIndex = ge.getColIndex();
currentRowIndex = ge.getRowIndex();
curSelectedRowID = ge.getModel().get("id");
}
});
grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<ItextModel>() {
public void selectionChanged(SelectionChangedEvent<ItextModel> se) {
Itext.updateRow(se.getSelectedItem(), curSelectedRowID);
curSelectedRowID = se.getSelectedItem().get("id");
}
});
grid.addListener(Events.SelectionChange, new Listener<GridEvent<ModelData>>() {
@Override
public void handleEvent(GridEvent<ModelData> be) {
// TODO Auto-generated method stub
System.out.println("asd");
}
});
}
public void makeToolbar(){
Button addLang,removeLang, btnSave, btnAddRow, btnRemoveRow, btnRemoveItext;
btnSave = new Button("Save");
addLang = new Button("Add Language");
removeLang = new Button("Remove Language");
btnAddRow = new Button("Add Row");
btnRemoveRow = new Button("Remove Row");
btnRemoveItext = new Button("Remove Unused Itext");
ButtonGroup group = new ButtonGroup(6);
ToolBar tb = new ToolBar();
tb.add(btnSave);
tb.add(new SeparatorToolItem());
tb.add(addLang);
tb.add(new SeparatorToolItem());
tb.add(removeLang);
tb.add(new SeparatorToolItem());
tb.add(btnAddRow);
tb.add(new SeparatorToolItem());
tb.add(btnRemoveRow);
tb.add(new SeparatorToolItem());
tb.add(btnRemoveItext);
// btnRemoveItext.disable(); //turned off for now to prevent shitty itext removal code from happening.
contentPanel.setTopComponent(tb);
btnSave.addListener(Events.Select, new Listener<ButtonEvent>(){
public void handleEvent(ButtonEvent be)
{
save(true);
}
});
addLang.addListener(Events.Select, new Listener<ButtonEvent>(){
public void handleEvent(ButtonEvent be)
{
addNewLanguage("Language");
}
});
removeLang.addListener(Events.Select, new Listener<ButtonEvent>(){
public void handleEvent(ButtonEvent be)
{
removeLang();
}
});
btnAddRow.addListener(Events.Select, new Listener<ButtonEvent>(){
public void handleEvent(ButtonEvent be)
{
addNewRow();
}
});
btnRemoveRow.addListener(Events.Select, new Listener<ButtonEvent>(){
public void handleEvent(ButtonEvent be)
{
removeRow();
}
});
btnRemoveItext.addListener(Events.Select, new Listener<ButtonEvent>(){
public void handleEvent(ButtonEvent be)
{
removeCrufItext();
}
});
}
public void makeContextMenu(){
Menu contextMenu = new Menu();
MenuItem addLang = new MenuItem();
addLang.setText("Add Language");
addLang.setIcon(AbstractImagePrototype.create(images.smallAdd()));
addLang.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
addNewLanguage("Language");
}
});
contextMenu.add(addLang);
MenuItem removeLang = new MenuItem();
removeLang.setText("Remove Language");
removeLang.setIcon(AbstractImagePrototype.create(images.smallRemove()));
removeLang.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
removeLang();
}
});
contextMenu.add(removeLang);
MenuItem addRow = new MenuItem();
addRow.setText("Add Row");
addRow.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
addNewRow();
}
});
contextMenu.add(addRow);
MenuItem btnRemoveRow = new MenuItem();
btnRemoveRow.setText("Remove Row");
btnRemoveRow.addSelectionListener(new SelectionListener<MenuEvent>() {
public void componentSelected(MenuEvent ce) {
removeRow();
}
});
contextMenu.add(btnRemoveRow);
grid.setContextMenu(contextMenu);
}
private void removeLang(){
if(cm.getColumnCount() > 3)
removeLanguage();
else{
com.google.gwt.user.client.Window.alert("Must have at least one language!");
}
}
public void showWindow(){
window.show();
}
public void hideWindow(){
window.hide();
}
private ColumnModel createColumnModel(){
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig xpath = new ColumnConfig("xpath", "Xpath", 5);
xpath.setHidden(true);
configs.add(xpath);
ColumnConfig formId = new ColumnConfig("id", "Id", 200);
configs.add(formId);
TextField<String> text = new TextField<String>();
CellEditor cellEditor = new CellEditor(text);
formId.setEditor(cellEditor);
//cellEditor.setStyle
List<ItextLocale> locales = Itext.locales;
if(locales != null){
for(ItextLocale locale : locales){
ColumnConfig columnConfig = new ColumnConfig(locale.getName(), locale.getName(), 200);
configs.add(columnConfig);
columnConfig.setEditor(new CellEditor(new TextField<String>()));
columnConfig.setStyle("font-size: 20px");
}
}
return new ColumnModel(configs);
}
/**
* Called by external methods when loading the Edit Itext window
*/
public void loadItext(){
cm = createColumnModel();
ListStore<ItextModel> rows = Itext.getItextRows();
grid.reconfigure(rows, cm);
}
public void adjustHeight(String height){
contentPanel.setHeight(height);
}
public void addNewLanguage(String defaultName) {
String lang = com.google.gwt.user.client.Window.prompt("Please enter the language name", defaultName);
if(lang != null && lang.trim().length() > 0){
if(languageExists(lang.trim())){
com.google.gwt.user.client.Window.alert("Please enter a language name different from those that exist.");
addNewLanguage(lang);
return;
}
ColumnConfig columnConfig = new ColumnConfig(lang, lang, 200);
grid.getColumnModel().getColumns().add(columnConfig);
columnConfig.setEditor(new CellEditor(new TextField<String>()));
Itext.addLocale(lang);
grid.reconfigure(Itext.getItextRows(), cm);
}
}
public void removeLanguage(){
String language = cm.getColumnHeader(currentColumnIndex);
if(!com.google.gwt.user.client.Window.confirm("Do you really want to remove the " + language + " language?")){
return;
}
Itext.removeLocale(language);
cm.getColumns().remove(currentColumnIndex);
grid.reconfigure(Itext.getItextRows(), cm);
}
public void renameLanguage(int curColIndex){
String oldLanguage = cm.getColumnHeader(curColIndex);
String newLanguage = com.google.gwt.user.client.Window.prompt("Please enter the new name", oldLanguage);
if(newLanguage.equals(oldLanguage)) renameLanguage(curColIndex);
if(newLanguage != null && newLanguage.trim().length() > 0){
Itext.renameLocale(oldLanguage, newLanguage);
cm.getColumns().get(currentColumnIndex).setHeader(newLanguage);
grid.reconfigure(Itext.getItextRows(), cm);
}
}
public void addNewRow(){
ItextModel newrow = new ItextModel();
newrow.set("id", "new_row");
newrow.set(Itext.getDefaultLocale().name, "value me!");
grid.stopEditing();
grid.getStore().insert(newrow, grid.getStore().getCount());
grid.startEditing(grid.getStore().indexOf(newrow), 0);
// String lang = Itext.getDefaultLocale().name;
// Itext.addText(lang, "new_row", "value me!");
// Itext.getItextRows().commitChanges();
// grid.reconfigure(Itext.getItextRows(), cm);
}
public void removeRow(){
if(currentRowIndex < 0)
return;
String id = grid.getStore().getModels().get(currentRowIndex).get("id");
if(!com.google.gwt.user.client.Window.confirm("Do you really want to remove the " + id + " row?"))
return;
Itext.removeRow(id);
grid.reconfigure(Itext.getItextRows(), cm);
}
public void save(boolean showWindow){
Itext.updateModel(grid.getStore());
TextTabWidget.showWindow = showWindow;
grid.getStore().commitChanges();
hideWindow();
GWT.log("TextTabWidget:388 Itext.getItextRows().len="+Itext.getItextRows().getCount());
FormUtil.dlg.setText("Saving Itext...");
FormUtil.dlg.show();
DeferredCommand.addCommand(new Command() {
public void execute() {
try{
listener.onSaveItext(Itext.getItextRows());
grid.reconfigure(Itext.getItextRows(), createColumnModel()); //refresh everything
FormUtil.dlg.hide();
if(TextTabWidget.showWindow){
showWindow();
}
}
catch(Exception ex){
FormUtil.displayException(ex);
}
}
});
}
private boolean languageExists(String name){
for(ItextLocale locale : Itext.locales){
if(locale.getName().equals(name)){
return true;
}
}
return false;
}
private void removeCrufItext(){
String warning = "WARNING: This action will cause the FormDesigner to remove all Itext entries it thinks are not being used. Are you sure you want to continue?";
if(!com.google.gwt.user.client.Window.confirm(warning)){
return;
}
FormDef formDef = Context.getFormDef();
List<String> usedIDs = formDef.getAllChildrenItextIDs();
Itext.removeUnusedItext(usedIDs);
grid.reconfigure(Itext.getItextRows(), cm);
}
}