public void onResize() { if (application != null) { if (application.getActiveEuclidianView().getEuclidianController() instanceof HasOffsets) ((HasOffsets) application.getActiveEuclidianView().getEuclidianController()) .updateOffsets(); } App.debug("resized"); }
public static void evalScript(App app, String script, String arg) { // Application.debug(app.getKernel().getLibraryJavaScript() + script); Context cx = Context.enter(); // Initialize the standard objects (Object, Function, etc.) // This must be done before scripts can be executed. Returns // a scope object that we use in later calls. Scriptable scope = cx.initStandardObjects(); // initialise the JavaScript variable applet so that we can call // GgbApi functions, eg ggbApplet.evalCommand() GeoGebraGlobal.initStandardObjects((AppD) app, scope, arg, false); // JavaScript to execute // String s = "ggbApplet.evalCommand('F=(2,3)')"; // No class loader for unsigned applets so don't try and optimize. // http://www.mail-archive.com/[email protected]/msg00108.html if (!AppD.hasFullPermissions()) { cx.setOptimizationLevel(-1); Context.setCachingEnabled(false); } // Now evaluate the string we've collected. Object result = cx.evaluateString( scope, ((AppD) app).getKernel().getLibraryJavaScript() + script, app.getPlain("ErrorAtLine"), 1, null); // Convert the result to a string and print it. // Application.debug("script result: "+(Context.toString(result))); }
private void applyFontStyle(ArrayList<GeoElement> geos) { int fontStyle = 0; if (btnBold.isSelected()) fontStyle += 1; if (btnItalic.isSelected()) fontStyle += 2; App.printStacktrace(geos.size() + ""); for (int i = 0; i < geos.size(); i++) { GeoElement geo = geos.get(i); App.debug(((GeoCasCell) geo).getGeoText()); if (geo instanceof GeoCasCell && ((GeoCasCell) geo).getGeoText().getFontStyle() != fontStyle) { ((GeoCasCell) geo).getGeoText().setFontStyle(fontStyle); geo.updateRepaint(); needUndo = true; } } }
/** * Prepares a spreadsheet cell editor string for processing in the kernel and returns either (1) a * new GeoElement for the cell or (2) null. * * @param kernel kernel * @param app application * @param inputText string representation of the new GeoElement * @param oldValue current cell GeoElement * @param column cell column * @param row cell row * @return either (1) a new GeoElement for the cell or (2) null * @throws Exception */ public static GeoElement prepareAddingValueToTableNoStoringUndoInfo( Kernel kernel, App app, String inputText, GeoElement oldValue, int column, int row) throws Exception { String text = inputText; // get the cell name String name = GeoElementSpreadsheet.getSpreadsheetCellName(column, row); // trim the text if (text != null) { text = text.trim(); if (text.length() == 0) { text = null; } } // if "=" is required before commands and text is not a number // or does not begin with "=" then surround it with quotes. // This will force the cell to become GeoText. if (app.getSettings().getSpreadsheet().equalsRequired() && text != null) { if (!((text.charAt(0) == '=') || isNumber(text))) { text = "\"" + text + "\""; } } // if the cell is currently GeoText then prepare it for changes // make sure it can be changed to something else // eg (2,3 can be overwritten as (2,3) // if (oldValue != null && oldValue.isGeoText() && // !oldValue.hasChildren()) { // oldValue.remove(); // oldValue = null; // } // if the text is null then remove the current cell geo and return null if (text == null) { if (oldValue != null) { oldValue.remove(); } return null; // else if the target cell is empty, try to create a new GeoElement // for this cell } else if (oldValue == null) { try { // this will be a new geo return prepareNewValue(kernel, name, text); } catch (Throwable t) { return prepareNewValue(kernel, name, ""); } // else the target cell is an existing GeoElement, so redefine it } else { return updateOldValue(kernel, oldValue, name, text); } }
public void playFile(String url) { // TODO check extension, play MIDI .mid files // TODO use MADJSto play MP3 in Firefox if (!url.endsWith(".mp3")) { App.warn("assuming MP3 file: " + url); } playMP3(url); }
/** Returns the GeoElement for the cell with the given column and row values. */ public static GeoElement getValue(App app, int column, int row) { SpreadsheetTableModel tableModel = app.getSpreadsheetTableModel(); if ((row < 0) || (row >= tableModel.getRowCount())) { return null; } if ((column < 0) || (column >= tableModel.getColumnCount())) { return null; } return (GeoElement) tableModel.getValueAt(row, column); }
@Override public GeoElement[] process(Command c) throws MyError { int n = c.getArgumentNumber(); GeoElement[] arg; arg = resArgs(c); BooleanValue cumulative = null; // default for n=2 (false) switch (n) { case 3: if (!arg[1].isGeoFunction() || !((GeoFunction) arg[1]).toString(StringTemplate.defaultTemplate).equals("x")) { throw argErr(app, c.getName(), arg[1]); } if (arg[2].isGeoBoolean()) { cumulative = (BooleanValue) arg[2]; } else throw argErr(app, c.getName(), arg[2]); // fall through case 2: if (arg[0].isNumberValue()) { if (arg[1].isGeoFunction() && ((GeoFunction) arg[1]).toString(StringTemplate.defaultTemplate).equals("x")) { App.debug("jhgjhgjhg"); AlgoTDistributionDF algo = new AlgoTDistributionDF(cons, c.getLabel(), (NumberValue) arg[0], cumulative); return algo.getGeoElements(); } else if (arg[1].isNumberValue()) { AlgoTDistribution algo = new AlgoTDistribution( cons, c.getLabel(), (NumberValue) arg[0], (NumberValue) arg[1]); GeoElement[] ret = {algo.getResult()}; return ret; } else throw argErr(app, c.getName(), arg[1]); } throw argErr(app, c.getName(), arg[0]); default: throw argNumErr(app, c.getName(), n); } }
@Override public void compute() { if (!factorList.isDefined() || !Kernel.isInteger(number.getDouble())) { result.setUndefined(); return; } long res = 1; for (int i = 0; i < factorList.size(); i++) { GeoList pair = (GeoList) factorList.get(i); double exp = ((NumberValue) pair.get(1)).getDouble(); if (sum) { double prime = ((NumberValue) pair.get(0)).getDouble(); App.debug(prime); res = res * Math.round((Math.pow(prime, exp + 1) - 1) / (prime - 1.0)); } else { res = res * Math.round(exp + 1); } } result.setValue(res); }
public synchronized void initFileChooser() { if (fileChooser == null) { try { setFileChooser( new GeoGebraFileChooser( ((AppD) app), ((AppD) app).getCurrentImagePath())); // non-restricted fileChooser.addPropertyChangeListener( JFileChooser.FILE_FILTER_CHANGED_PROPERTY, new FileFilterChangedListener()); } catch (Exception e) { // fix for java.io.IOException: Could not get shell folder ID // list // Java bug // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6544857 App.debug("Error creating GeoGebraFileChooser - using fallback option"); setFileChooser( new GeoGebraFileChooser( ((AppD) app), ((AppD) app).getCurrentImagePath(), true)); // restricted // version } updateJavaUILanguage(); } }
public void pauseResumeSound(boolean b) { App.debug("unimplemented"); }
@Override protected String prompt(String message, String def) { App.debug("Shouldn't ever be called"); return null; }
/** * Performs spreadsheet drag-copy operation. * * @param sx1 source minimum column * @param sy1 source minimum row * @param sx2 source maximum column * @param sy2 source maximum row * @param dx1 destination minimum column * @param dy1 destination minimum row * @param dx2 destination maximum column * @param dy2 destination maximum row * @return */ public boolean doDragCopy( int sx1, int sy1, int sx2, int sy2, int dx1, int dy1, int dx2, int dy2) { // -|1|- // 2|-|3 // -|4|- app.setWaitCursor(); Construction cons = kernel.getConstruction(); try { boolean success = false; // collect all redefine operations cons.startCollectingRedefineCalls(); boolean patternOK = isPatternSource(new CellRange(app, sx1, sy1, sx2, sy2)); // ============================================== // vertical drag // ============================================== if ((sx1 == dx1) && (sx2 == dx2)) { if (dy2 < sy1) { // 1 ----- drag up if (((sy1 + 1) == sy2) && patternOK) { // two row source, so drag copy a linear pattern for (int x = sx1; x <= sx2; ++x) { GeoElement v1 = getValue(app, x, sy1); GeoElement v2 = getValue(app, x, sy2); if ((v1 == null) || (v2 == null)) { continue; } for (int y = dy2; y >= dy1; --y) { GeoElement v3 = getValue(app, x, y + 2); GeoElement v4 = getValue(app, x, y + 1); String vs1 = v3.isGeoFunction() ? "(x)" : ""; String vs2 = v4.isGeoFunction() ? "(x)" : ""; String d0 = GeoElementSpreadsheet.getSpreadsheetCellName(x, y + 2) + vs1; String d1 = GeoElementSpreadsheet.getSpreadsheetCellName(x, y + 1) + vs2; String text = "=2*" + d1 + "-" + d0; doCopyNoStoringUndoInfo1(kernel, app, text, v4, x, y); } } } else { // not two row source, so drag-copy the first row // of the source doCopyVerticalNoStoringUndoInfo1(sx1, sx2, sy1, dy1, dy2); } success = true; } else if (dy1 > sy2) { // 4 ---- drag down if (((sy1 + 1) == sy2) && patternOK) { // two row source, so drag copy a linear pattern for (int x = sx1; x <= sx2; ++x) { GeoElement v1 = getValue(app, x, sy1); GeoElement v2 = getValue(app, x, sy2); if ((v1 == null) || (v2 == null)) { continue; } for (int y = dy1; y <= dy2; ++y) { GeoElement v3 = getValue(app, x, y - 2); GeoElement v4 = getValue(app, x, y - 1); String vs1 = v3.isGeoFunction() ? "(x)" : ""; String vs2 = v4.isGeoFunction() ? "(x)" : ""; String d0 = GeoElementSpreadsheet.getSpreadsheetCellName(x, y - 2) + vs1; String d1 = GeoElementSpreadsheet.getSpreadsheetCellName(x, y - 1) + vs2; String text = "=2*" + d1 + "-" + d0; doCopyNoStoringUndoInfo1(kernel, app, text, v4, x, y); } } } else { // not two row source, so drag-copy the last row of the // source doCopyVerticalNoStoringUndoInfo1(sx1, sx2, sy2, dy1, dy2); } success = true; } } // ============================================== // horizontal drag // ============================================== else if ((sy1 == dy1) && (sy2 == dy2)) { if (dx2 < sx1) { // 2 ---- drag left if (((sx1 + 1) == sx2) && patternOK) { // two column source, so drag copy a linear pattern for (int y = sy1; y <= sy2; ++y) { GeoElement v1 = getValue(app, sx1, y); GeoElement v2 = getValue(app, sx2, y); if ((v1 == null) || (v2 == null)) { continue; } for (int x = dx2; x >= dx1; --x) { GeoElement v3 = getValue(app, x + 2, y); GeoElement v4 = getValue(app, x + 1, y); String vs1 = v3.isGeoFunction() ? "(x)" : ""; String vs2 = v4.isGeoFunction() ? "(x)" : ""; String d0 = GeoElementSpreadsheet.getSpreadsheetCellName(x + 2, y) + vs1; String d1 = GeoElementSpreadsheet.getSpreadsheetCellName(x + 1, y) + vs2; String text = "=2*" + d1 + "-" + d0; doCopyNoStoringUndoInfo1(kernel, app, text, v4, x, y); } } } else { // not two column source, so drag-copy the first column // of the source doCopyHorizontalNoStoringUndoInfo1(sy1, sy2, sx1, dx1, dx2); } success = true; } else if (dx1 > sx2) { // 4 --- drag right if (((sx1 + 1) == sx2) && patternOK) { // two column source, so drag copy a linear pattern for (int y = sy1; y <= sy2; ++y) { GeoElement v1 = getValue(app, sx1, y); GeoElement v2 = getValue(app, sx2, y); if ((v1 == null) || (v2 == null)) { continue; } for (int x = dx1; x <= dx2; ++x) { GeoElement v3 = getValue(app, x - 2, y); GeoElement v4 = getValue(app, x - 1, y); String vs1 = v3.isGeoFunction() ? "(x)" : ""; String vs2 = v4.isGeoFunction() ? "(x)" : ""; String d0 = GeoElementSpreadsheet.getSpreadsheetCellName(x - 2, y) + vs1; String d1 = GeoElementSpreadsheet.getSpreadsheetCellName(x - 1, y) + vs2; String text = "=2*" + d1 + "-" + d0; doCopyNoStoringUndoInfo1(kernel, app, text, v4, x, y); } } } else { // not two column source, so drag-copy the last column // of the source doCopyHorizontalNoStoringUndoInfo1(sy1, sy2, sx2, dx1, dx2); } success = true; } } // now do all redefining and build new construction cons.processCollectedRedefineCalls(); if (success) { return true; } String msg = "sx1 = " + sx1 + "\r\n" + "sy1 = " + sy1 + "\r\n" + "sx2 = " + sx2 + "\r\n" + "sy2 = " + sy2 + "\r\n" + "dx1 = " + dx1 + "\r\n" + "dy1 = " + dy1 + "\r\n" + "dx2 = " + dx2 + "\r\n" + "dy2 = " + dy2 + "\r\n"; throw new RuntimeException("Error from RelativeCopy.doCopy:\r\n" + msg); } catch (Exception ex) { // kernel.getApplication().showError(ex.getMessage()); ex.printStackTrace(); return false; } finally { cons.stopCollectingRedefineCalls(); app.setDefaultCursor(); } }
public static GeoElement doCopyNoStoringUndoInfo0( Kernel kernel, App app, GeoElement value, GeoElement oldValue, int dx, int dy) throws Exception { if (value == null) { if (oldValue != null) { MatchResult matcher = GeoElementSpreadsheet.spreadsheetPatternPart.exec( oldValue.getLabel(StringTemplate.defaultTemplate)); int column = GeoElementSpreadsheet.getSpreadsheetColumn(matcher); int row = GeoElementSpreadsheet.getSpreadsheetRow(matcher); prepareAddingValueToTableNoStoringUndoInfo(kernel, app, null, oldValue, column, row); } return null; } String text = null; // make sure a/0.001 doesn't become a/0 StringTemplate highPrecision = StringTemplate.maxPrecision; if (value.isPointOnPath() || value.isPointInRegion()) { text = value.getCommandDescription(highPrecision); } else if (value.isChangeable()) { text = value.toValueString(highPrecision); } else { text = value.getCommandDescription(highPrecision); } // handle GeoText source value if (value.isGeoText() && !((GeoText) value).isTextCommand()) { // enclose text in quotes if we are copying an independent GeoText, // e.g. "2+3" if (value.isIndependent()) { text = "\"" + text + "\""; } else { // check if 'text' parses to a GeoText GeoText testGeoText = kernel.getAlgebraProcessor().evaluateToText(text, false, false); // if it doesn't then force it to by adding +"" on the end if (testGeoText == null) { text = text + "+\"\""; } } } // for E1 = Polynomial[D1] we need value.getCommandDescription(); // even though it's a GeoFunction if (value.isGeoFunction() && text.equals("")) { // we need the definition without A1(x)= on the front text = ((GeoFunction) value).toSymbolicString(highPrecision); } boolean freeImage = false; if (value.isGeoImage()) { GeoImage image = (GeoImage) value; if (image.getParentAlgorithm() == null) { freeImage = true; } } // Application.debug("before:"+text); text = updateCellReferences(value, text, dx, dy); // Application.debug("after:"+text); // condition to show object GeoBoolean bool = value.getShowObjectCondition(); String boolText = null, oldBoolText = null; if (bool != null) { if (bool.isChangeable()) { oldBoolText = bool.toValueString(highPrecision); } else { oldBoolText = bool.getCommandDescription(highPrecision); } } if (oldBoolText != null) { boolText = updateCellReferences(bool, oldBoolText, dx, dy); } String startPoints[] = null; if (value instanceof Locateable) { Locateable loc = (Locateable) value; GeoPointND[] pts = loc.getStartPoints(); startPoints = new String[pts.length]; for (int i = 0; i < pts.length; i++) { startPoints[i] = ((GeoElement) pts[i]).getLabel(highPrecision); startPoints[i] = updateCellReferences((GeoElement) pts[i], startPoints[i], dx, dy); } } // dynamic color function GeoList dynamicColorList = value.getColorFunction(); String colorText = null, oldColorText = null; if (dynamicColorList != null) { if (dynamicColorList.isChangeable()) { oldColorText = dynamicColorList.toValueString(highPrecision); } else { oldColorText = dynamicColorList.getCommandDescription(highPrecision); } } if (oldColorText != null) { colorText = updateCellReferences(dynamicColorList, oldColorText, dx, dy); } // allow pasting blank strings if (text.equals("")) { text = "\"\""; } // make sure that non-GeoText elements are copied when the // equalsRequired option is set if (!value.isGeoText() && app.getSettings().getSpreadsheet().equalsRequired()) { text = "=" + text; } // Application.debug("add text = " + text + ", name = " + (char)('A' + // column + dx) + (row + dy + 1)); // create the new cell geo MatchResult matcher = GeoElementSpreadsheet.spreadsheetPatternPart.exec( value.getLabel(StringTemplate.defaultTemplate)); int column0 = GeoElementSpreadsheet.getSpreadsheetColumn(matcher); int row0 = GeoElementSpreadsheet.getSpreadsheetRow(matcher); GeoElement value2; if (freeImage || value.isGeoButton()) { value2 = value.copy(); if (oldValue != null) { oldValue.remove(); } // value2.setLabel(table.getModel().getColumnName(column0 + dx) // + (row0 + dy + 1)); value2.setLabel(GeoElementSpreadsheet.getSpreadsheetCellName(column0 + dx, row0 + dy + 1)); value2.updateRepaint(); } else { value2 = prepareAddingValueToTableNoStoringUndoInfo( kernel, app, text, oldValue, column0 + dx, row0 + dy); } value2.setAllVisualProperties(value, false); value2.setAuxiliaryObject(true); // attempt to set updated condition to show object (if it's changed) if ((boolText != null)) { // removed as doesn't work for eg "random()<0.5" #388 // && !boolText.equals(oldBoolText)) { try { // Application.debug("new condition to show object: "+boolText); GeoBoolean newConditionToShowObject = kernel.getAlgebraProcessor().evaluateToBoolean(boolText); value2.setShowObjectCondition(newConditionToShowObject); value2.update(); // needed to hide/show object as appropriate } catch (Exception e) { e.printStackTrace(); return null; } } // attempt to set updated dynamic color function (if it's changed) if ((colorText != null)) { // removed as doesn't work for eg "random()" #388 // && !colorText.equals(oldColorText)) { try { // Application.debug("new color function: "+colorText); GeoList newColorFunction = kernel.getAlgebraProcessor().evaluateToList(colorText); value2.setColorFunction(newColorFunction); // value2.update(); } catch (Exception e) { e.printStackTrace(); return null; } } if (startPoints != null) { for (int i = 0; i < startPoints.length; i++) { ((Locateable) value2) .setStartPoint( kernel.getAlgebraProcessor().evaluateToPoint(startPoints[i], false, true), i); } value2.update(); } // Application.debug((row + dy) + "," + column); // Application.debug("isGeoFunction()=" + value2.isGeoFunction()); // Application.debug("row0 ="+row0+" dy="+dy+" column0= "+column0+" dx="+dx); return value2; }
public void playFunction( GeoFunction geoFunction, double double1, double double2, int double3, int double4) { App.debug("unimplemented"); }
@Override protected boolean confirm(String string) { App.debug("Shouldn't ever be called"); return false; }
public void playSequenceFromString(String string, int double1) { App.debug("unimplemented"); }
public void attachApp(App app) { if (application != app) { application = app; setAlgebraView((AlgebraViewW) application.getAlgebraView()); } }
/** Handles data import. */ @Override public boolean importData(JComponent comp, Transferable t) { // give the drop target (this EV) the view focus requestViewFocus(); Point mousePos = ev.getMousePosition(); // ------------------------------------------ // Import handling is done in this order: // 1) PlotPanel GeoElement copies // 2) Images // 3) Text // 4) CASTableCells // 5) GGB files // ------------------------------------------ // try to get PlotPanel GeoElement copies if (t.isDataFlavorSupported(PlotPanelEuclidianView.plotPanelFlavor)) { try { AbstractAction act = (AbstractAction) t.getTransferData(PlotPanelEuclidianView.plotPanelFlavor); act.putValue("euclidianViewID", ev.getViewID()); act.actionPerformed(new ActionEvent(act, 0, null)); } catch (UnsupportedFlavorException e) { e.printStackTrace(); return false; } catch (IOException e) { e.printStackTrace(); return false; } return true; } // try to get an image boolean imageDropped = ((GuiManagerD) ev.getApplication().getGuiManager()).loadImage(t, false); if (imageDropped) return true; // handle CAS table cells as simple latex string (not dynamic!!) // ToDo: make it dynamic (after ticket 2449 is finished) DataFlavor[] df = t.getTransferDataFlavors(); for (DataFlavor d : df) { App.debug(d); } if (t.isDataFlavorSupported(CASTransferHandler.casTableFlavor)) { try { // after it is possible to refer to cas cells with "$1" we can refer dynamically // String tableRef; StringBuilder sb = new StringBuilder("FormulaText[$"); sb.append(1 + (Integer) t.getTransferData(CASTransferHandler.casTableFlavor)); sb.append("]"); // tableRef = "$" + (cellnumber+1); // create a GeoText on the specific mouse position GeoElement[] ret = ev.getApplication() .getKernel() .getAlgebraProcessor() .processAlgebraCommandNoExceptionHandling(sb.toString(), true, false, false); if (ret != null && ret[0].isTextValue()) { GeoText geo = (GeoText) ret[0]; geo.setLaTeX(true, false); // TODO: h should equal the geo height, this is just an // estimate double h = 2 * app.getFontSize(); geo.setRealWorldLoc( ev.toRealWorldCoordX(mousePos.x), ev.toRealWorldCoordY(mousePos.y - h)); geo.updateRepaint(); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } // check for ggb file drop boolean ggbFileDropped = ((GuiManagerD) app.getGuiManager()).handleGGBFileDrop(t); if (ggbFileDropped) return true; // handle all text flavors if (t.isDataFlavorSupported(DataFlavor.stringFlavor) || t.isDataFlavorSupported(AlgebraViewTransferHandler.algebraViewFlavor)) { try { String text = null; // expression to be converted into GeoText boolean isLaTeX = false; // get text from AlgebraView flavor if (t.isDataFlavorSupported(AlgebraViewTransferHandler.algebraViewFlavor)) { isLaTeX = true; // get list of selected geo labels ArrayList<String> list = (ArrayList<String>) t.getTransferData(AlgebraViewTransferHandler.algebraViewFlavor); // exit if empty list if (list.size() == 0) return false; // single geo if (list.size() == 1) { text = "FormulaText[" + list.get(0) + ", true, true]"; } // multiple geos, wrap in TableText else { text = "TableText["; for (int i = 0; i < list.size(); i++) { text += "{FormulaText[" + list.get(i) + ", true, true]}"; if (i < list.size() - 1) { text += ","; } } text += "]"; } } // get text from String flavor else { try { // first try to read text line-by-line Reader r = textReaderFlavor.getReaderForText(t); if (r != null) { StringBuilder sb = new StringBuilder(); String line = null; BufferedReader br = new BufferedReader(r); line = br.readLine(); while (line != null) { sb.append(line + "\n"); line = br.readLine(); } br.close(); text = sb.toString(); } } catch (Exception e) { App.debug("Caught exception decoding text transfer:" + e.getMessage()); } // if the reader didn't work, try to get whatever string is // available if (text == null) text = (String) t.getTransferData(DataFlavor.stringFlavor); // exit if no text found if (text == null) return false; // TODO --- validate the text? e.g. no quotes for a GeoText // wrap text in quotes text = "\"" + text + "\""; } // --------------------------------- // create GeoText GeoElement[] ret = ev.getApplication().getKernel().getAlgebraProcessor().processAlgebraCommand(text, true); if (ret != null && ret[0].isTextValue()) { GeoText geo = (GeoText) ret[0]; geo.setLaTeX(isLaTeX, false); // TODO: h should equal the geo height, this is just an // estimate double h = 2 * app.getFontSize(); geo.setRealWorldLoc( ev.toRealWorldCoordX(mousePos.x), ev.toRealWorldCoordY(mousePos.y - h)); geo.updateRepaint(); } return true; } catch (UnsupportedFlavorException ignored) { // TODO } catch (IOException ignored) { // TODO } } return false; }
public void playSequenceNote(int double1, double double2, int i, int j) { App.debug("unimplemented"); }
/** * Adds the given modes to a two-dimensional toolbar. The toolbar definition string looks like "0 * , 1 2 | 3 4 5 || 7 8 9" where the int values are mode numbers, "," adds a separator within a * menu, "|" starts a new menu and "||" adds a separator before starting a new menu. * * @param modes * @param tb * @param bg */ private void addCustomModesToToolbar(ModeToggleButtonGroup bg) { Vector<ToolbarItem> toolbarVec; try { if (dockPanel != null) { toolbarVec = ToolBar.parseToolbarString(dockPanel.getToolbarString()); } else { toolbarVec = ToolBar.parseToolbarString(((GuiManagerD) app.getGuiManager()).getToolbarDefinition()); } } catch (Exception e) { if (dockPanel != null) { App.debug("invalid toolbar string: " + dockPanel.getToolbarString()); } else { App.debug( "invalid toolbar string: " + ((GuiManagerD) app.getGuiManager()).getToolbarDefinition()); } toolbarVec = ToolBar.parseToolbarString(getDefaultToolbarString()); } // set toolbar boolean firstButton = true; // make the loop go backwards for eg Hebrew / Arabic int first = app.isRightToLeftReadingOrder() ? toolbarVec.size() - 1 : 0; int increment = app.isRightToLeftReadingOrder() ? -1 : 1; // for (int i = 0; i < toolbarVec.size(); i++) { for (int i = first; i >= 0 && i < toolbarVec.size(); i += increment) { ToolbarItem ob = toolbarVec.get(i); // separator between menus if (ob.getMode() == ToolBar.SEPARATOR) { addSeparator(); continue; } // new menu Vector<Integer> menu = ob.getMenu(); ModeToggleMenu tm = new ModeToggleMenu(app, this, bg); modeToggleMenus.add(tm); for (int k = 0; k < menu.size(); k++) { // separator int addMode = menu.get(k).intValue(); if (addMode < 0) { // separator within menu: tm.addSeparator(); } else { // standard case: add mode // check mode if (!"".equals(app.getToolName(addMode))) { tm.addMode(addMode); if (i == 0 && firstButton) { tm.getJToggleButton().setSelected(true); firstButton = false; } } } } if (tm.getToolsCount() > 0) add(tm); } }