/*
GeoGebra - Dynamic Mathematics for Everyone
http://www.geogebra.org
This file is part of GeoGebra.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation.
*/
package org.geogebra.common.gui;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import org.geogebra.common.GeoGebraConstants;
import org.geogebra.common.euclidian.EuclidianConstants;
import org.geogebra.common.euclidian.EuclidianView;
import org.geogebra.common.euclidian.EuclidianViewInterfaceCommon;
import org.geogebra.common.gui.layout.DockPanel;
import org.geogebra.common.gui.toolbar.ToolBar;
import org.geogebra.common.gui.view.consprotocol.ConstructionProtocolNavigation;
import org.geogebra.common.gui.view.consprotocol.ConstructionProtocolView;
import org.geogebra.common.gui.view.data.DataAnalysisModel.IDataAnalysisListener;
import org.geogebra.common.gui.view.data.PlotPanelEuclidianViewInterface;
import org.geogebra.common.gui.view.probcalculator.ProbabilityCalculatorView;
import org.geogebra.common.kernel.Kernel;
import org.geogebra.common.kernel.Macro;
import org.geogebra.common.kernel.ModeSetter;
import org.geogebra.common.kernel.View;
import org.geogebra.common.kernel.geos.GeoElement;
import org.geogebra.common.kernel.geos.GeoImage;
import org.geogebra.common.kernel.geos.GeoPoint;
import org.geogebra.common.kernel.kernelND.GeoElementND;
import org.geogebra.common.kernel.kernelND.GeoPointND;
import org.geogebra.common.main.App;
import org.geogebra.common.main.GuiManagerInterface;
import org.geogebra.common.main.settings.ConstructionProtocolSettings;
import org.geogebra.common.main.settings.ProbabilityCalculatorSettings.DIST;
import org.geogebra.common.util.debug.Log;
public abstract class GuiManager implements GuiManagerInterface {
final public View getConstructionProtocolData() {
ConstructionProtocolView view = getConstructionProtocolView();
if (view != null) {
return view.getData();
}
// eg Android
Log.debug("not implemented");
return null;
}
/**
* possible GeoGebraTube syntaxes
* http://www.geogebratube.org/material/show/id/111
* http://www.geogebratube.org/student/m111
* http://www.geogebratube.org/student/cXX/m111/options
* www.geogebratube.org/material/show/id/111
* www.geogebratube.org/student/m111
* www.geogebratube.org/student/cXX/m111/options
* http://geogebratube.org/material/show/id/111
* http://geogebratube.org/student/m111
* http://geogebratube.org/student/cXX/m111/options http://ggbtu.be/m111
* http://ggbtu.be/cXX/m111/options http://www.ggbtu.be/m111
* http://www.ggbtu.be/cXX/options
*
* in an iframe, src= http://www.geogebratube.org/material/iframe/id/111
* http
* ://www.geogebratube.org/material/iframe/id/111/param1/val1/param2/val2
* /... http://ggbtu.be/e111 http://ggbtu.be/e111?param1=¶m2=..
*
*
* also can have ?mobile=true ?mobile=false on end
*/
private static final String ggbTubeOld = "geogebratube.org/";
private static final String ggbTube = "tube.geogebra.org/";
private static final String ggbTubeBeta = "beta.geogebra.org/";
private static final String ggbTubeShort = "ggbtu.be/";
private static final String ggbMatShort = "ggbm.at/";
private static final String material = "/material/show/id/";
protected Kernel kernel;
public App app;
/**
* Abstract constructor
*
* @param app2
*/
public GuiManager(App app2) {
this.app = app2;
this.kernel = app.getKernel();
}
@Override
public void updateMenubar() {
// temporarily nothing
}
@Override
public boolean hasAlgebraView() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isUsingConstructionProtocol() {
// TODO Auto-generated method stub
return false;
}
@Override
public void getExtraViewsXML(StringBuilder sb) {
if (isUsingConstructionProtocol()) {
getConsProtocolXML(sb);
}
if (this.hasDataAnalysisView()) {
((IDataAnalysisListener) getDataAnalysisView()).getModel()
.getXML(sb);
}
}
@Override
public final void getConsProtocolXML(StringBuilder sb) {
if (this.isUsingConstructionProtocol()) {
getConstructionProtocolView().getXML(sb);
}
if (app.showConsProtNavigation()) {
sb.append("\t<consProtNavigationBar ");
sb.append("id=\"");
app.getConsProtNavigationIds(sb);
sb.append('\"');
sb.append(" playButton=\"");
sb.append(
getConstructionProtocolNavigation().isPlayButtonVisible());
sb.append('\"');
sb.append(" playDelay=\"");
sb.append(getConstructionProtocolNavigation().getPlayDelay());
sb.append('\"');
sb.append(" protButton=\"");
sb.append(getConstructionProtocolNavigation()
.isConsProtButtonVisible());
sb.append('\"');
sb.append(" consStep=\"");
sb.append(kernel.getConstructionStep());
sb.append('\"');
sb.append("/>\n");
}
}
@Override
public boolean hasProbabilityCalculator() {
// TODO Auto-generated method stub
return false;
}
@Override
public void getProbabilityCalculatorXML(StringBuilder sb) {
if (probCalculator != null) {
probCalculator.getXML(sb);
}
}
@Override
public void getSpreadsheetViewXML(StringBuilder sb, boolean asPreference) {
// TODO Auto-generated method stub
}
@Override
public void updateActions() {
// TODO Auto-generated method stub
}
@Override
public void updateConstructionProtocol() {
// TODO Auto-generated method stub
}
@Override
public boolean loadURL(String urlString) {
return loadURL(urlString, true);
}
@Override
public boolean loadURL(String urlString, boolean suppressErrorMsg) {
String processedUrlString = urlString.trim();
boolean success = false;
boolean isMacroFile = false;
getApp().setWaitCursor();
try {
// check first for ggb/ggt file
if ((processedUrlString.endsWith(".ggb")
|| processedUrlString.endsWith(".ggt"))
&& (processedUrlString.indexOf("?") == -1)) { // This isn't
// a ggb
// file,
// however ends with ".ggb":
// http://www.geogebra.org/web/test42/?f=_circles5.ggb
// loadURL_GGB(processedUrlString);
app.getGgbApi().openFile(processedUrlString);
// special case: urlString is from GeoGebraTube
// eg http://www.geogebratube.org/student/105 changed to
// http://www.geogebratube.org/files/material-105.ggb
} else if (processedUrlString
.indexOf(GeoGebraConstants.GEOGEBRA_WEBSITE) > -1
|| processedUrlString.indexOf(
GeoGebraConstants.GEOGEBRA_WEBSITE_BETA) > -1
|| processedUrlString.indexOf(ggbTube) > -1
|| processedUrlString.indexOf(ggbTubeShort) > -1
|| processedUrlString.indexOf(ggbMatShort) > -1
|| processedUrlString.indexOf(ggbTubeBeta) > -1
|| processedUrlString.indexOf(ggbTubeOld) > -1) {
// remove eg http:// if it's there
if (processedUrlString.indexOf("://") > -1) {
processedUrlString = processedUrlString.substring(
processedUrlString.indexOf("://") + 3,
processedUrlString.length());
}
// remove hostname
processedUrlString = processedUrlString.substring(
processedUrlString.indexOf('/'),
processedUrlString.length());
String id;
// determine the start position of ID in the URL
int start = -1;
if (processedUrlString.startsWith(material)) {
start = material.length();
} else {
start = processedUrlString.lastIndexOf("/m") + 2;
}
// no valid URL?
if (start == -1) {
Log.debug("problem parsing: " + processedUrlString);
return false;
}
// the end position is either before the next slash or at the
// end of the string
int end = -1;
if (start > -1) {
end = processedUrlString.indexOf('/', start);
}
if (end == -1) {
end = processedUrlString.length();
}
// fetch ID
id = processedUrlString.substring(start, end);
processedUrlString = "https://www.geogebra.org/files/material-";
// Add the login token to assure that private files of the
// logged in user can be accessed
processedUrlString += id + ".ggb";
if (app.getLoginOperation().isLoggedIn()) {
String token = app.getLoginOperation().getModel()
.getLoggedInUser().getLoginToken();
if (token != null) {
processedUrlString += "?lt=" + token;
}
}
Log.debug(processedUrlString);
// success = loadURL_GGB(processedUrlString);
app.getGgbApi().openFile(processedUrlString);
// special case: urlString is actually a base64 encoded ggb file
} else if (processedUrlString.startsWith("UEs")) {
success = true;
app.getGgbApi()
.setBase64(
processedUrlString.replace("\\/", "/"));
// special case: urlString is actually a GeoGebra XML file
} else if (processedUrlString.startsWith("<?xml ")
&& processedUrlString.endsWith("</geogebra>")) {
success = getApp().loadXML(processedUrlString);
// 'standard' case: url with GeoGebra applet (Java or HTML5)
}
// else {
// // try to load from GeoGebra applet
// success = loadFromApplet(processedUrlString);
// isMacroFile = processedUrlString.contains(".ggt");
// }
} catch (Exception ex) {
ex.printStackTrace();
}
if (!success && !suppressErrorMsg) {
getApp().showError(
getApp().getLocalization().getError("LoadFileFailed") + "\n"
+ processedUrlString);
}
updateGUIafterLoadFile(success, isMacroFile);
return success;
}
protected abstract App getApp();
/**
* Attach a view which by using the view ID.
*
* @author Florian Sonner
* @version 2008-10-21
*
* @param viewId
*/
@Override
public void attachView(int viewId) {
switch (viewId) {
case App.VIEW_ALGEBRA:
attachAlgebraView();
break;
case App.VIEW_SPREADSHEET:
attachSpreadsheetView();
break;
case App.VIEW_CAS:
attachCasView();
break;
case App.VIEW_CONSTRUCTION_PROTOCOL:
attachConstructionProtocolView();
break;
case App.VIEW_PROBABILITY_CALCULATOR:
attachProbabilityCalculatorView();
break;
case App.VIEW_DATA_ANALYSIS:
attachDataAnalysisView();
break;
case App.VIEW_PROPERTIES:
attachPropertiesView();
break;
case App.VIEW_EUCLIDIAN:
case App.VIEW_EUCLIDIAN2:
// handled elsewhere
break;
default:
// ignore 3D view
if (!App.isView3D(viewId)) {
Log.error("Error attaching VIEW: " + viewId);
}
}
}
@Override
public void showAxesCmd() {
// get ev with focus
EuclidianViewInterfaceCommon ev = getActiveEuclidianView();
boolean bothAxesShown = ev.getShowXaxis() && ev.getShowYaxis();
if (app.getEuclidianView1() == ev) {
app.getSettings().getEuclidian(1).setShowAxes(!bothAxesShown,
!bothAxesShown);
} else if (app.hasEuclidianView2EitherShowingOrNot(1)
&& app.getEuclidianView2(1) == ev) {
app.getSettings().getEuclidian(2).setShowAxes(!bothAxesShown,
!bothAxesShown);
} else if (app.hasEuclidianView3D() && app.getEuclidianView3D() == ev) {
app.getSettings().getEuclidian(3).setShowAxes(!bothAxesShown);
} else {
ev.setShowAxes(!bothAxesShown, true);
}
ev.repaint();
app.storeUndoInfo();
app.updateMenubar();
}
@Override
public void showGridCmd() {
// get ev with focus
EuclidianView ev = getActiveEuclidianView();
if (app.getEuclidianView1() == ev) {
app.getSettings().getEuclidian(1).showGrid(!ev.getShowGrid());
} else if (app.hasEuclidianView2EitherShowingOrNot(1)
&& app.getEuclidianView2(1) == ev) {
app.getSettings().getEuclidian(2).showGrid(!ev.getShowGrid());
} else if (app.hasEuclidianView3D() && app.getEuclidianView3D() == ev) {
app.getSettings().getEuclidian(3).showGrid(!ev.getShowGrid());
} else {
ev.showGrid(!ev.getShowGrid());
}
ev.repaint();
app.storeUndoInfo();
app.updateMenubar();
}
@Override
public void doAfterRedefine(GeoElementND geo) {
// G.Sturr 2010-6-28
// if a tracing geo has been redefined, then put it back into the
// traceGeoCollection
if (geo.getSpreadsheetTrace()) {
getApp().getTraceManager()
.addSpreadsheetTraceGeo(geo.toGeoElement());
}
}
/**
* Detach a view which by using the view ID.
*
* @author Florian Sonner
* @version 2008-10-21
*
* @param viewId
*/
@Override
public void detachView(int viewId) {
switch (viewId) {
case App.VIEW_ALGEBRA:
detachAlgebraView();
break;
case App.VIEW_SPREADSHEET:
detachSpreadsheetView();
break;
case App.VIEW_CAS:
detachCasView();
break;
case App.VIEW_CONSTRUCTION_PROTOCOL:
detachConstructionProtocolView();
break;
case App.VIEW_PROBABILITY_CALCULATOR:
detachProbabilityCalculatorView();
break;
case App.VIEW_PROPERTIES:
detachPropertiesView();
break;
case App.VIEW_DATA_ANALYSIS:
detachDataAnalysisView();
break;
case App.VIEW_EUCLIDIAN:
case App.VIEW_EUCLIDIAN2:
Log.debug("TODO: should we detach EV1/2?");
break;
default:
if (App.isView3D(viewId)) {
Log.debug("TODO: should we detach EV3D?");
} else {
Log.error("Error detaching VIEW: " + viewId);
}
}
}
@Override
public void openCommandHelp(String command) {
String internalCmd = null;
if (command != null) {
try { // convert eg uppersum to UpperSum
internalCmd = getApp().getReverseCommand(command);
} catch (Exception e) {
Log.warn("Command not found in dictionary:" + command);
}
}
openHelp(internalCmd, Help.COMMAND);
}
protected abstract void openHelp(String internalCmd, Help command);
@Override
public void openHelp(String page) {
openHelp(page, Help.GENERIC);
}
@Override
public void setShowConstructionProtocolNavigation(boolean show, int id) {
getConstructionProtocolNavigation(id).setVisible(show);
if (show) {
if (getApp().getActiveEuclidianView() != null) {
getApp().getActiveEuclidianView().resetMode();
}
getConstructionProtocolView();
}
}
@Override
public void setShowConstructionProtocolNavigation(boolean show, int id,
boolean playButton, double playDelay, boolean showProtButton) {
setShowConstructionProtocolNavigation(show, id);
getConstructionProtocolNavigation().setPlayButtonVisible(playButton);
getConstructionProtocolNavigation().setPlayDelay(playDelay);
getConstructionProtocolNavigation()
.setConsProtButtonVisible(showProtButton);
}
protected HashMap<Integer, ConstructionProtocolNavigation> constProtocolNavigationMap;
@Override
public void updateNavBars() {
if (constProtocolNavigationMap != null) {
Iterator<ConstructionProtocolNavigation> it = constProtocolNavigationMap
.values().iterator();
while (it.hasNext()) {
ConstructionProtocolNavigation navBar = it.next();
navBar.update();
}
}
}
/**
* Returns the construction protocol navigation bar instance.
*
* @param id
* view id
* @return construction protocol for the view id
*/
@Override
final public ConstructionProtocolNavigation getConstructionProtocolNavigation(
int id) {
if (constProtocolNavigationMap == null) {
constProtocolNavigationMap = new HashMap<Integer, ConstructionProtocolNavigation>();
}
ConstructionProtocolNavigation constProtocolNavigation = constProtocolNavigationMap
.get(id);
if (constProtocolNavigation == null) {
constProtocolNavigation = newConstructionProtocolNavigation(id);
constProtocolNavigationMap.put(id, constProtocolNavigation);
}
return constProtocolNavigation;
}
@Override
final public Collection<ConstructionProtocolNavigation> getAllConstructionProtocolNavigations() {
if (constProtocolNavigationMap == null) {
return null;
}
return constProtocolNavigationMap.values();
}
@Override
final public void setNavBarButtonPause() {
if (constProtocolNavigationMap != null) {
for (ConstructionProtocolNavigation cpn : constProtocolNavigationMap
.values()) {
cpn.setButtonPause();
}
}
}
@Override
final public void setNavBarButtonPlay() {
if (constProtocolNavigationMap != null) {
for (ConstructionProtocolNavigation cpn : constProtocolNavigationMap
.values()) {
cpn.setButtonPlay();
}
}
}
/**
*
* @return new construction protocol navigation bar instance
*/
protected abstract ConstructionProtocolNavigation newConstructionProtocolNavigation(
int viewID);
/**
* Returns the default construction protocol navigation bar instance.
*
* @return construction protocol for the view id
*/
@Override
public ConstructionProtocolNavigation getConstructionProtocolNavigation() {
return getConstructionProtocolNavigation(App.VIEW_EUCLIDIAN);
}
/**
* Returns the construction protocol navigation bar instance or null, if it
* not exists.
*/
@Override
public ConstructionProtocolNavigation getConstructionProtocolNavigationIfExists() {
if (constProtocolNavigationMap == null) {
return null;
}
return constProtocolNavigationMap.get(App.VIEW_EUCLIDIAN);
}
@Override
public abstract void updateCheckBoxesForShowConstructinProtocolNavigation(
int id);
@Override
public void applyCPsettings(ConstructionProtocolSettings cps) {
if (constProtocolNavigationMap == null) {
return;
}
for (ConstructionProtocolNavigation constProtocolNavigation : constProtocolNavigationMap
.values()) {
constProtocolNavigation
.setConsProtButtonVisible(cps.showConsProtButton());
constProtocolNavigation.setPlayDelay(cps.getPlayDelay());
constProtocolNavigation.setPlayButtonVisible(cps.showPlayButton());
}
}
@Override
public void registerConstructionProtocolView(ConstructionProtocolView cpv) {
if (constProtocolNavigationMap == null) {
ConstructionProtocolNavigation cpn = getConstructionProtocolNavigation();
cpn.register(cpv);
} else {
for (ConstructionProtocolNavigation cpn : constProtocolNavigationMap
.values()) {
cpn.register(cpv);
}
}
}
// ==================================
// PlotPanel ID handling
// =================================
private HashMap<Integer, PlotPanelEuclidianViewInterface> plotPanelIDMap;
private int lastUsedPlotPanelID = -App.VIEW_PLOT_PANEL;
protected HashMap<Integer, PlotPanelEuclidianViewInterface> getPlotPanelIDMap() {
if (plotPanelIDMap == null) {
plotPanelIDMap = new HashMap<Integer, PlotPanelEuclidianViewInterface>();
}
return plotPanelIDMap;
}
/**
* Adds the given PlotPanelEuclidianView instance to the plotPanelIDMap and
* returns a unique viewID
*
* @param plotPanel
* @return
*/
public int assignPlotPanelID(PlotPanelEuclidianViewInterface plotPanel) {
lastUsedPlotPanelID--;
int viewID = lastUsedPlotPanelID;
getPlotPanelIDMap().put(viewID, plotPanel);
Log.debug(viewID);
return viewID;
}
@Override
public PlotPanelEuclidianViewInterface getPlotPanelView(int viewID) {
return getPlotPanelIDMap().get(viewID);
}
private boolean setModeFinished;
protected ProbabilityCalculatorView probCalculator;
@Override
public void setMode(int mode0, ModeSetter m) {
int mode = mode0;
setModeFinished = false;
// can't move this after otherwise Object Properties doesn't work
kernel.notifyModeChanged(mode, m);
// notifyModeChanged called another setMode => nothing to do here
if (setModeFinished) {
return;
}
// select toolbar button, returns *actual* mode selected - only for
// desktop
// if (caller_APP == DESKTOP) {
int newMode = setToolbarMode(mode, m);
if (mode != EuclidianConstants.MODE_SELECTION_LISTENER
&& newMode != mode) {
mode = newMode;
kernel.notifyModeChanged(mode, m);
}
// }
if (mode == EuclidianConstants.MODE_PROBABILITY_CALCULATOR) {
// show or focus the probability calculator
if (showView(App.VIEW_PROBABILITY_CALCULATOR)) {
this.getLayout().getDockManager()
.setFocusedPanel(App.VIEW_PROBABILITY_CALCULATOR);
} else {
setShowView(true, App.VIEW_PROBABILITY_CALCULATOR);
probCalculator.setProbabilityCalculator(DIST.NORMAL, null,
false);
}
// nothing more to do, so reset to move mode
app.setMoveMode();
}
if ((mode == EuclidianConstants.MODE_SPREADSHEET_ONEVARSTATS
|| mode == EuclidianConstants.MODE_SPREADSHEET_TWOVARSTATS
|| mode == EuclidianConstants.MODE_SPREADSHEET_MULTIVARSTATS)
&& m == ModeSetter.TOOLBAR) {
// save the selected geos so they can be re-selected later
ArrayList<GeoElement> temp = new ArrayList<GeoElement>();
if (app.getSelectionManager().getSelectedGeos() != null) {
for (GeoElement geo : app.getSelectionManager()
.getSelectedGeos()) {
temp.add(geo);
}
}
if (app.getGuiManager() != null) {
app.getDialogManager().showDataSourceDialog(mode, true);
app.setMoveMode();
}
// reselect the geos
app.getSelectionManager().setSelectedGeos(temp);
}
setModeFinished = true;
}
protected void setProbCalculator(ProbabilityCalculatorView pc) {
this.probCalculator = pc;
}
/**
* @param mode
* @param m
* mode setter
* @return sets the toolbar's mode
*/
protected int setToolbarMode(int mode, ModeSetter m) {
return 0;
// should be implemented in subclasses if needed
}
final public String getHelpURL(final Help type, String pageName) {
// try to get help for given language
// eg http://www.geogebra.org/help/en_GB/cmd/FitLogistic
final StringBuilder urlSB = new StringBuilder();
urlSB.append(GeoGebraConstants.GEOGEBRA_WEBSITE);
urlSB.append("help/");
urlSB.append(app.getLocalization().getLanguage()); // eg en_GB
switch (type) {
case COMMAND:
String cmdPageName = app.getLocalization().getEnglishCommand(
pageName);
urlSB.append("/cmd/");
urlSB.append(cmdPageName);
break;
case TOOL:
urlSB.append("/tool/");
urlSB.append(pageName);
break;
case GENERIC:
// eg openHelp("Custom_Tools", Help.GENERIC)
// returns http://www.geogebra.org/help/hu/article/Custom_Tools
// wiki redirects to correct page
// ie http://wiki.geogebra.org/hu/Egy%E9ni_eszk%F6z%F6k
urlSB.append("/article/");
urlSB.append(pageName);
break;
default:
Log.error("Bad getHelpURL call");
}
return urlSB.toString();
}
@Override
public void redo() {
app.setWaitCursor();
kernel.redo();
updateActions();
app.resetPen();
app.setDefaultCursor();
}
@Override
public void undo() {
app.setWaitCursor();
kernel.undo();
updateActions();
app.resetPen();
app.setDefaultCursor();
}
@Override
public abstract String getToolbarDefinition();
public abstract void setToolBarDefinition(String toolBarDefinition);
@Override
public void refreshCustomToolsInToolBar() {
String oldToolbar = getToolbarDefinition() == null
? ToolBar.getAllTools(app) : getToolbarDefinition();
setToolBarDefinition(refreshCustomToolsInToolBar(oldToolbar));
}
public String refreshCustomToolsInToolBar(String initial) {
int macroCount = kernel.getMacroNumber();
// add the ones that have (showInToolbar == true) into the toolbar if
// they are not already there.
StringBuilder customToolBar = new StringBuilder("");
String oldToolbar = initial;
String toolbar3D = "";
if (app.hasEuclidianView3D()) {
DockPanel dockPanel = getLayout().getDockManager()
.getPanel(App.VIEW_EUCLIDIAN3D);
toolbar3D = dockPanel.getToolbarString();
if (toolbar3D == null) {
toolbar3D = getToolbarDefinition();
}
Log.debug("[CT] 3D toolbar: " + toolbar3D);
}
for (int i = 0; i < macroCount; i++) {
Macro macro = kernel.getMacro(i);
int macroMode = EuclidianConstants.MACRO_MODE_ID_OFFSET + i;
int macroViewId = macro.getViewId() != null ? macro.getViewId()
: App.VIEW_EUCLIDIAN;
int activeViewId = getActiveToolbarId();
// boolean tool3d = macroViewId != null
// && macroViewId == App.VIEW_EUCLIDIAN3D
// || toolbar3D.contains(String.valueOf(macroMode));
// Log.debug(
// "[CT] macro: " + macro.getToolName() + " is 3D: " + tool3d);
Log.debug("[CT] macroViewId: " + macroViewId + " activeViewId: "
+ activeViewId);
if (macro.isShowInToolBar()
&& !(oldToolbar.contains(String.valueOf(macroMode)))
&& (macroViewId == activeViewId)) {
customToolBar.append(" ");
customToolBar.append(macroMode);
}
}
String toolbarDef = oldToolbar.trim();
String last = "";
try {
// get the last tool mode number in the toolbar def string
String[] tools = toolbarDef.split(" ");
last = tools[tools.length - 1];
int lastToolId = Integer.parseInt(last);
if (lastToolId >= EuclidianConstants.MACRO_MODE_ID_OFFSET) {
return toolbarDef + customToolBar.toString();
}
return toolbarDef + " ||" + customToolBar.toString();
} catch (NumberFormatException e) {
// could not identify the last tool so just add the custom tools
// onto the end
if (last.contains("|")) {
return toolbarDef + customToolBar.toString();
}
return toolbarDef + " ||" + customToolBar.toString();
}
}
@Override
public void replaceInputSelection(String string) {
// override this in platforms where needed
}
@Override
public void setInputText(String string) {
// override this in platforms where needed
}
private GeoPoint getImageCornerFromSelection(int index) {
ArrayList<GeoElement> sel = app.getSelectionManager().getSelectedGeos();
if (sel.size() > index) {
GeoElement geo0 = sel.get(index);
if (geo0.isGeoPoint()) {
return (GeoPoint) geo0;
}
}
return null;
}
public void ensure2ndCornerOnScreen(double x1, GeoPoint point) {
double x2 = point.inhomX;
EuclidianView ev = app.getActiveEuclidianView();
double xmax = ev.toRealWorldCoordX((double) (ev.getWidth()) + 1);
if (x2 > xmax) {
point.setCoords((x1 + 9 * xmax) / 10, point.inhomY, 1);
point.update();
}
}
private void ensure1stCornerOnScreen(GeoPointND point) {
EuclidianView ev = app.getActiveEuclidianView();
double xmin = ev.toRealWorldCoordX(0.0);
double xmax = ev.toRealWorldCoordX((double) (ev.getWidth()) + 1);
double ymin = ev.toRealWorldCoordY(0.0);
double ymax = ev.toRealWorldCoordY((double) (ev.getHeight()) + 1);
point.setCoords(xmin + (xmax - xmin) / 5, ymax - (ymax - ymin) / 5,
1.0);
point.update();
}
/**
* Loads the image and sets its corners
*
* @param geoImage
* The image.
*/
@Override
public void setImageCornersFromSelection(GeoImage geoImage) {
ArrayList<GeoPointND> corners = new ArrayList<GeoPointND>();
for (int i = 0; i < 3; i++) {
GeoPoint p = getImageCornerFromSelection(i);
if (p != null) {
corners.add(p);
}
}
GeoPointND point1 = null;
if (corners.size() == 0) {
point1 = new GeoPoint(app.getKernel().getConstruction());
point1.setCoords(0, 0, 1.0);
point1.setLabel(null);
ensure1stCornerOnScreen(point1);
corners.add(point1);
} else if (corners.size() == 1) {
point1 = corners.get(0);
}
for (int i = 0; i < corners.size(); i++) {
geoImage.setCorner(corners.get(i), i);
}
if (corners.size() < 2) {
GeoPoint point2 = new GeoPoint(app.getKernel().getConstruction());
geoImage.calculateCornerPoint(point2, 2);
geoImage.setCorner(point2, 1);
point2.setLabel(null);
// make sure 2nd corner is on screen
ensure2ndCornerOnScreen(point1.getInhomX(), point2);
}
geoImage.setLabel(null);
//
GeoImage.updateInstances(app);
// }
// // make sure only the last image will be selected
GeoElement[] geos = { geoImage };
app.getActiveEuclidianView().getEuclidianController().clearSelections();
app.getActiveEuclidianView().getEuclidianController()
.memorizeJustCreatedGeos(geos);
app.setMoveMode();
app.getActiveEuclidianView().resetMode();
}
}