Compare commits
106 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
efe562f057 | ||
|
d2b7b640d9 | ||
|
79f5e51513 | ||
|
0f605d89f0 | ||
|
cb6828c08e | ||
|
3ff67910c9 | ||
|
51f531f6b4 | ||
|
fc22dd32a2 | ||
|
deca7e51b2 | ||
|
28ffead0a0 | ||
|
d1dfb48be5 | ||
|
9360a27f15 | ||
|
cc8ff94b10 | ||
|
f245116e48 | ||
|
7bd87c50ac | ||
|
86d5c98ed7 | ||
|
5d05f21803 | ||
|
6e2880c8cc | ||
|
87ce3fc0a9 | ||
|
92849b02eb | ||
|
829655f253 | ||
|
b4bdad796e | ||
|
d52e2c04a6 | ||
|
edc3351fd8 | ||
|
73a664ab97 | ||
|
cabca992d1 | ||
|
e734ea350c | ||
|
ac7af5b8f1 | ||
|
43e9f8fcad | ||
|
7a401b648e | ||
|
82ff47220d | ||
|
f3d88e91c4 | ||
|
37419cba66 | ||
|
8b0465bda6 | ||
|
765b1fc80e | ||
|
0d8b6b210e | ||
|
d2c287684f | ||
|
bad11bea88 | ||
|
6c1188314b | ||
|
f4f97d3112 | ||
|
a958fcbd6e | ||
|
02b31e463b | ||
|
6fe53446ce | ||
|
5d62bf520a | ||
|
12448fc6cb | ||
|
ebd6f886d5 | ||
|
66e4b0fb19 | ||
|
f34ec25610 | ||
|
46264991b9 | ||
|
b9748ca23a | ||
|
fe99c9a238 | ||
|
9f495f1e76 | ||
|
dd1698b5d9 | ||
|
c5bf91a9fe | ||
|
ac8309819c | ||
|
e1e9c9ebeb | ||
|
4062b6771c | ||
|
0cdabba5eb | ||
|
064b8f1071 | ||
|
c3dcd8f3a9 | ||
|
b717a5f910 | ||
|
1602421544 | ||
|
fe44da9b43 | ||
|
2a8ae4c397 | ||
|
7f7a67872e | ||
|
322b0ba13e | ||
|
0aa2d67698 | ||
|
3c0055b767 | ||
|
2549305621 | ||
|
42564b2759 | ||
|
032df5fdf4 | ||
|
dbbe8901b7 | ||
|
91f27c4e10 | ||
|
91aeddee70 | ||
|
fab3c96097 | ||
|
b89b08b7b3 | ||
|
ed37b20dfc | ||
|
f44e616a4b | ||
|
e70f2726a3 | ||
|
964505abd4 | ||
|
ce932e57e0 | ||
|
2ec9e70245 | ||
|
fc6d91f59e | ||
|
f8a6607de9 | ||
|
ca0b5bfcbe | ||
|
be545d7103 | ||
|
3832844ee6 | ||
|
b3234675cc | ||
|
146c6d8a17 | ||
|
37e11a5b05 | ||
|
ea5f1afa40 | ||
|
2e0339492d | ||
|
f8d6cdebc4 | ||
|
58ed80d763 | ||
|
61569bc571 | ||
|
7ba21f85bf | ||
|
2c5f7139d5 | ||
|
0c433352c5 | ||
|
07c8a1d8c7 | ||
|
6560973237 | ||
|
596aeeebc4 | ||
|
16e59a0879 | ||
|
2861a7b5f9 | ||
|
b1172f16cc | ||
|
71762ff629 | ||
|
00fd168489 |
@@ -78,7 +78,7 @@ The following code is an example of how to add attach to the div dragImageNode t
|
||||
designer.addDraggedNode(event, node);
|
||||
});
|
||||
|
||||
In the example, a new node is created with text "Node Text !!!!" and a note and a link associated to it when the user drop the node. Something to pay attention is the node.setMetadata("{}"), this attributes will be persisted during the serialization. Here you can store all the data you need.
|
||||
In the example, a new node is created with text "Node Text !!!!" and a note and a link associated to it when the user drop the node. Something to pay attention is the node.setMetadata("{}"), this delegated will be persisted during the serialization. Here you can store all the data you need.
|
||||
|
||||
2) Support for dragging Images: Similar to the point 1,drag support is registered to the div dragImageNode.
|
||||
|
||||
|
@@ -8,7 +8,7 @@ BASE_DIR=`pwd`
|
||||
TARGET_DIR=$BASE_DIR/target
|
||||
JETTY_DIR=$TARGET_DIR/wisemapping-$WISE_VERSION
|
||||
WISE_WEBAPP_DIR=$JETTY_DIR/webapps/wisemapping
|
||||
JETTY_VERSION=8.1.5.v20120716
|
||||
JETTY_VERSION=8.1.8.v20121106
|
||||
JETTY_DIST_DIR=jetty-distribution-${JETTY_VERSION}
|
||||
JETTY_ZIP=${JETTY_DIST_DIR}.zip
|
||||
|
||||
|
14
java.iml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
@@ -228,6 +228,7 @@
|
||||
<include>layout/EventBus.js</include>
|
||||
<include>MessageBundle_en.js</include>
|
||||
<include>MessageBundle_es.js</include>
|
||||
<include>MessageBundle_de.js</include>
|
||||
<include>MessageBundle_fr.js</include>
|
||||
<include>MessageBundle_pt_BR.js</include>
|
||||
<include>MessageBundle_zh_CN.js</include>
|
||||
|
@@ -29,16 +29,12 @@ mindplot.ConnectionLine = new Class({
|
||||
var ctrlPoints = this._getCtrlPoints(sourceNode, targetNode);
|
||||
if (targetNode.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
line = this._createLine(lineType, mindplot.ConnectionLine.CURVED);
|
||||
if (line.getType() == "CurvedLine") {
|
||||
line.setSrcControlPoint(ctrlPoints[0]);
|
||||
line.setDestControlPoint(ctrlPoints[1]);
|
||||
}
|
||||
line.setSrcControlPoint(ctrlPoints[0]);
|
||||
line.setDestControlPoint(ctrlPoints[1]);
|
||||
} else {
|
||||
line = this._createLine(lineType, mindplot.ConnectionLine.SIMPLE_CURVED);
|
||||
if (line.getType() == "CurvedLine") {
|
||||
line.setSrcControlPoint(ctrlPoints[0]);
|
||||
line.setDestControlPoint(ctrlPoints[1]);
|
||||
}
|
||||
line.setSrcControlPoint(ctrlPoints[0]);
|
||||
line.setDestControlPoint(ctrlPoints[1]);
|
||||
}
|
||||
// Set line styles ...
|
||||
var strokeColor = mindplot.ConnectionLine.getStrokeColor();
|
||||
|
@@ -440,8 +440,9 @@ mindplot.Designer = new Class({
|
||||
}
|
||||
// Execute event ...
|
||||
var topic = nodes[0];
|
||||
this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken());
|
||||
|
||||
if (topic.getType() != mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
this._actionDispatcher.shrinkBranch([topic.getId()], !topic.areChildrenShrunken());
|
||||
}
|
||||
},
|
||||
|
||||
createChildForSelectedNode:function () {
|
||||
@@ -697,6 +698,9 @@ mindplot.Designer = new Class({
|
||||
|
||||
var targetTopicId = model.getToNode();
|
||||
var targetTopic = dmodel.findTopicById(targetTopicId);
|
||||
$assert(targetTopic, "targetTopic could not be found:" + targetTopicId + dmodel.getTopics().map(function (e) {
|
||||
return e.getId()
|
||||
}));
|
||||
|
||||
// Build relationship line ....
|
||||
var result = new mindplot.Relationship(sourceTopic, targetTopic, model);
|
||||
@@ -749,7 +753,16 @@ mindplot.Designer = new Class({
|
||||
}
|
||||
},
|
||||
|
||||
_resetEdition:function () {
|
||||
var screenManager = this._workspace.getScreenManager();
|
||||
screenManager.fireEvent("update");
|
||||
screenManager.fireEvent("mouseup");
|
||||
this._relPivot.dispose();
|
||||
},
|
||||
|
||||
deleteSelectedEntities:function () {
|
||||
// Is there some action in progress ?.
|
||||
this._resetEdition();
|
||||
|
||||
var topics = this.getModel().filterSelectedTopics();
|
||||
var relation = this.getModel().filterSelectedRelationships();
|
||||
|
@@ -252,7 +252,7 @@ mindplot.DesignerKeyboard = new Class({
|
||||
designer.zoomOut();
|
||||
},
|
||||
|
||||
'ctrl++':function (event) {
|
||||
'ctrl+=':function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
|
@@ -115,14 +115,16 @@ mindplot.DragTopic = new Class({
|
||||
},
|
||||
|
||||
removeFromWorkspace:function (workspace) {
|
||||
// Remove drag shadow.
|
||||
workspace.removeChild(this._elem2d);
|
||||
this._isInWorkspace = false;
|
||||
if (this._isInWorkspace) {
|
||||
// Remove drag shadow.
|
||||
workspace.removeChild(this._elem2d);
|
||||
|
||||
// Remove pivot shape. To improve performace it will not be removed. Only the visibility will be changed.
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.setVisibility(false);
|
||||
// Remove pivot shape. To improve performance it will not be removed. Only the visibility will be changed.
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.setVisibility(false);
|
||||
|
||||
this._isInWorkspace = false;
|
||||
}
|
||||
},
|
||||
|
||||
isInWorkspace:function () {
|
||||
@@ -130,10 +132,12 @@ mindplot.DragTopic = new Class({
|
||||
},
|
||||
|
||||
addToWorkspace:function (workspace) {
|
||||
workspace.appendChild(this._elem2d);
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.addToWorkspace(workspace);
|
||||
this._isInWorkspace = true;
|
||||
if (!this._isInWorkspace) {
|
||||
workspace.appendChild(this._elem2d);
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.addToWorkspace(workspace);
|
||||
this._isInWorkspace = true;
|
||||
}
|
||||
},
|
||||
|
||||
_getDragPivot:function () {
|
||||
|
@@ -102,7 +102,6 @@ mindplot.ImageIcon = new Class({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mindplot.ImageIcon.prototype.ICON_FAMILIES = [
|
||||
{"id":"face", "icons":["face_plain", "face_sad", "face_crying", "face_smile", "face_surprise", "face_wink"]},
|
||||
{"id":"funy", "icons":["funy_angel", "funy_devilish", "funy_glasses", "funy_grin", "funy_kiss", "funy_monkey"]},
|
||||
@@ -114,6 +113,7 @@ mindplot.ImageIcon.prototype.ICON_FAMILIES = [
|
||||
{"id":"onoff", "icons":["onoff_clock", "onoff_clock_red", "onoff_add", "onoff_delete", "onoff_status_offline", "onoff_status_online"]},
|
||||
{"id":"money", "icons":["money_money", "money_dollar", "money_euro", "money_pound", "money_yen", "money_coins", "money_ruby"]},
|
||||
{"id":"time", "icons":["time_calendar", "time_clock", "time_hourglass"]},
|
||||
{"id":"number", "icons":["number_1", "number_2", "number_3", "number_4", "number_5", "number_6", "number_7", "number_8", "number_9"]},
|
||||
{"id":"chart", "icons":["chart_bar", "chart_line", "chart_curve", "chart_pie", "chart_organisation"]},
|
||||
{"id":"sign", "icons":["sign_warning", "sign_info", "sign_stop", "sign_help", "sign_cancel"]},
|
||||
{"id":"hard", "icons":["hard_cd", "hard_computer", "hard_controller", "hard_driver_disk", "hard_ipod", "hard_keyboard", "hard_mouse", "hard_printer"]},
|
||||
@@ -126,7 +126,7 @@ mindplot.ImageIcon.prototype.ICON_FAMILIES = [
|
||||
{"id":"bullet", "icons":["bullet_black", "bullet_blue", "bullet_green", "bullet_orange", "bullet_red", "bullet_pink", "bullet_purple"]},
|
||||
{"id":"tag", "icons":["tag_blue", "tag_green", "tag_orange", "tag_red", "tag_pink", "tag_yellow"]},
|
||||
{"id":"object", "icons":["object_bell", "object_clanbomber", "object_key", "object_pencil", "object_phone", "object_magnifier", "object_clip", "object_music", "object_star", "object_wizard", "object_house", "object_cake", "object_camera", "object_palette", "object_rainbow"]},
|
||||
{"id":"weather", "icons":["weather_clear-night", "weather_clear", "weather_few-clouds-night", "weather_few-clouds", "weather_overcast", "weather_severe-alert", "weather_showers-scattered", "weather_showers", "weather_snow", "weather_storm"]}
|
||||
{"id":"weather", "icons":["weather_clear-night", "weather_clear", "weather_few-clouds-night", "weather_few-clouds", "weather_overcast", "weather_severe-alert", "weather_showers-scattered", "weather_showers", "weather_snow", "weather_storm"]},
|
||||
{"id":"task", "icons":["task_0", "task_25", "task_50", "task_75", "task_100"]}
|
||||
];
|
||||
|
||||
|
||||
|
@@ -18,8 +18,10 @@
|
||||
|
||||
mindplot.LocalStorageManager = new Class({
|
||||
Extends:mindplot.PersistenceManager,
|
||||
initialize:function () {
|
||||
initialize:function (documentUrl,forceLoad) {
|
||||
this.parent();
|
||||
this.documentUrl = documentUrl;
|
||||
this.forceLoad = forceLoad;
|
||||
},
|
||||
|
||||
saveMapXml:function (mapId, mapXml, pref, saveHistory, events) {
|
||||
@@ -32,10 +34,10 @@ mindplot.LocalStorageManager = new Class({
|
||||
|
||||
loadMapDom:function (mapId) {
|
||||
var xml = localStorage.getItem(mapId + "-xml");
|
||||
if (xml == null) {
|
||||
// Let's try to open one from the local directory ...
|
||||
if (xml == null || this.forceLoad) {
|
||||
var xmlRequest = new Request({
|
||||
url:'samples/' + mapId + '.xml',
|
||||
url:this.documentUrl.replace("{id}", mapId),
|
||||
headers:{"Content-Type":"text/plain","Accept":"application/xml"},
|
||||
method:'get',
|
||||
async:false,
|
||||
onSuccess:function (responseText) {
|
||||
|
@@ -98,28 +98,7 @@ mindplot.MainTopic = new Class({
|
||||
},
|
||||
|
||||
workoutIncomingConnectionPoint:function (sourcePosition) {
|
||||
$assert(sourcePosition, 'sourcePoint can not be null');
|
||||
var pos = this.getPosition();
|
||||
var size = this.getSize();
|
||||
|
||||
var isAtRight = mindplot.util.Shape.isAtRight(sourcePosition, pos);
|
||||
var result = mindplot.util.Shape.calculateRectConnectionPoint(pos, size, isAtRight);
|
||||
if (this.getShapeType() == mindplot.model.TopicShape.LINE) {
|
||||
result.y = result.y + (this.getSize().height / 2);
|
||||
}
|
||||
|
||||
// Move a little the position...
|
||||
var offset = mindplot.Topic.CONNECTOR_WIDTH / 2;
|
||||
if (this.getPosition().x > 0) {
|
||||
result.x = result.x + offset;
|
||||
} else {
|
||||
result.x = result.x - offset;
|
||||
}
|
||||
|
||||
result.x = Math.ceil(result.x);
|
||||
result.y = Math.ceil(result.y);
|
||||
return result;
|
||||
|
||||
return mindplot.util.Shape.workoutIncomingConnectionPoint(this, sourcePosition);
|
||||
},
|
||||
|
||||
workoutOutgoingConnectionPoint:function (targetPosition) {
|
||||
|
@@ -191,7 +191,7 @@ mindplot.MultilineTextEditor = new Class({
|
||||
// Set editor's initial size
|
||||
var displayFunc = function () {
|
||||
// Position the editor and set the size...
|
||||
var textShape = this._topic.getTextShape();
|
||||
var textShape = topic.getTextShape();
|
||||
textShape.positionRelativeTo(this._containerElem, {
|
||||
position:{x:'left', y:'top'},
|
||||
edge:{x:'left', y:'top'}
|
||||
|
@@ -83,14 +83,19 @@ mindplot.Relationship = new Class({
|
||||
|
||||
var targetTopic = this._targetTopic;
|
||||
var targetPosition = targetTopic.getPosition();
|
||||
if (targetTopic.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
targetPosition = mindplot.util.Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition);
|
||||
}
|
||||
|
||||
var sPos, tPos;
|
||||
this._line2d.setStroke(2);
|
||||
var ctrlPoints = this._line2d.getControlPoints();
|
||||
if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) {
|
||||
|
||||
var defaultPoints = mindplot.util.Shape.calculateDefaultControlPoints(sourcePosition, targetPosition);
|
||||
ctrlPoints[0].x = defaultPoints[0].x;
|
||||
ctrlPoints[0].y = defaultPoints[0].y;
|
||||
|
||||
ctrlPoints[1].x = defaultPoints[1].x;
|
||||
ctrlPoints[1].y = defaultPoints[1].y;
|
||||
}
|
||||
@@ -101,6 +106,7 @@ mindplot.Relationship = new Class({
|
||||
var tpoint = new core.Point();
|
||||
tpoint.x = parseInt(ctrlPoints[1].x) + parseInt(targetPosition.x);
|
||||
tpoint.y = parseInt(ctrlPoints[1].y) + parseInt(targetPosition.y);
|
||||
|
||||
sPos = mindplot.util.Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint);
|
||||
tPos = mindplot.util.Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint);
|
||||
|
||||
|
@@ -43,7 +43,9 @@ mindplot.RelationshipPivot = new Class({
|
||||
|
||||
this._pivot = new web2d.CurvedLine();
|
||||
this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||
this._pivot.setFrom(sourcePos.x, sourcePos.y);
|
||||
|
||||
var fromPos = this._calculateFromPosition(sourcePos);
|
||||
this._pivot.setFrom(fromPos.x, fromPos.y);
|
||||
|
||||
this._pivot.setTo(targetPos.x, targetPos.y);
|
||||
this._pivot.setStroke(2, 'solid', strokeColor);
|
||||
@@ -54,7 +56,6 @@ mindplot.RelationshipPivot = new Class({
|
||||
this._startArrow.setStrokeWidth(2);
|
||||
this._startArrow.setFrom(sourcePos.x, sourcePos.y);
|
||||
|
||||
|
||||
this._workspace.appendChild(this._pivot);
|
||||
this._workspace.appendChild(this._startArrow);
|
||||
|
||||
@@ -99,8 +100,13 @@ mindplot.RelationshipPivot = new Class({
|
||||
var pos = screen.getWorkspaceMousePosition(event);
|
||||
|
||||
// Leave the arrow a couple of pixels away from the cursor.
|
||||
var gapDistance = Math.sign(pos.x - this._sourceTopic.getPosition().x) * 5;
|
||||
var sourcePosition = this._sourceTopic.getPosition();
|
||||
var gapDistance = Math.sign(pos.x - sourcePosition.x) * 5;
|
||||
|
||||
var sPos = this._calculateFromPosition(pos);
|
||||
this._pivot.setFrom(sPos.x, sPos.y);
|
||||
|
||||
// Update target position ...
|
||||
this._pivot.setTo(pos.x - gapDistance, pos.y);
|
||||
|
||||
var controlPoints = this._pivot.getControlPoints();
|
||||
@@ -118,6 +124,21 @@ mindplot.RelationshipPivot = new Class({
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
_calculateFromPosition:function (toPosition) {
|
||||
|
||||
// Calculate origin position ...
|
||||
var sourcePosition = this._sourceTopic.getPosition();
|
||||
if (this._sourceTopic.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
sourcePosition = mindplot.util.Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
|
||||
}
|
||||
var controlPoint = mindplot.util.Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
||||
|
||||
var spoint = new core.Point();
|
||||
spoint.x = parseInt(controlPoint[0].x) + parseInt(sourcePosition.x);
|
||||
spoint.y = parseInt(controlPoint[0].y) + parseInt(sourcePosition.y);
|
||||
return mindplot.util.Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
||||
},
|
||||
|
||||
_connectOnFocus:function (targetTopic) {
|
||||
var sourceTopic = this._sourceTopic;
|
||||
var mindmap = this._designer.getMindmap();
|
||||
|
@@ -20,13 +20,13 @@ mindplot.RESTPersistenceManager = new Class({
|
||||
Extends:mindplot.PersistenceManager,
|
||||
initialize:function (options) {
|
||||
this.parent();
|
||||
$assert(options.saveUrl, "saveUrl can not be null");
|
||||
$assert(options.documentUrl, "documentUrl can not be null");
|
||||
$assert(options.revertUrl, "revertUrl can not be null");
|
||||
$assert(options.lockUrl, "lockUrl can not be null");
|
||||
$assert(options.session, "session can not be null");
|
||||
$assert(options.timestamp, "timestamp can not be null");
|
||||
|
||||
this.saveUrl = options.saveUrl;
|
||||
this.documentUrl = options.documentUrl;
|
||||
this.revertUrl = options.revertUrl;
|
||||
this.lockUrl = options.lockUrl;
|
||||
this.timestamp = options.timestamp;
|
||||
@@ -43,8 +43,8 @@ mindplot.RESTPersistenceManager = new Class({
|
||||
|
||||
var persistence = this;
|
||||
var query = "minor=" + !saveHistory;
|
||||
query = query + (this.timestamp ? "×tamp=" + this.timestamp : "");
|
||||
query = query + (this.session ? "&session=" + this.session : "");
|
||||
query = query + "×tamp=" + this.timestamp;
|
||||
query = query + "&session=" + this.session;
|
||||
|
||||
if (!persistence.onSave) {
|
||||
|
||||
@@ -56,7 +56,7 @@ mindplot.RESTPersistenceManager = new Class({
|
||||
}, 10000);
|
||||
|
||||
var request = new Request({
|
||||
url:this.saveUrl.replace("{id}", mapId) + "?" + query,
|
||||
url:this.documentUrl.replace("{id}", mapId) + "?" + query,
|
||||
method:'put',
|
||||
async:!sync,
|
||||
|
||||
@@ -99,10 +99,7 @@ mindplot.RESTPersistenceManager = new Class({
|
||||
}
|
||||
}
|
||||
events.onError(userMsg);
|
||||
|
||||
// @Todo: Only for debug. Remove.
|
||||
persistence.onSave = false;
|
||||
throw new Error("responseText:" + responseText + ",status:" + this.status);
|
||||
},
|
||||
|
||||
headers:{"Content-Type":"application/json", "Accept":"application/json"},
|
||||
@@ -163,6 +160,29 @@ mindplot.RESTPersistenceManager = new Class({
|
||||
severity = "INFO";
|
||||
}
|
||||
return {severity:severity, message:message};
|
||||
},
|
||||
|
||||
loadMapDom:function (mapId) {
|
||||
// Let's try to open one from the local directory ...
|
||||
var xml;
|
||||
var xmlRequest = new Request({
|
||||
url:this.documentUrl.replace("{id}", mapId) + "/xml",
|
||||
method:'get',
|
||||
async:false,
|
||||
headers:{"Content-Type":"text/plain","Accept":"application/xml"},
|
||||
onSuccess:function (responseText) {
|
||||
xml = responseText;
|
||||
}
|
||||
});
|
||||
xmlRequest.send();
|
||||
|
||||
// If I could not load it from a file, hard code one.
|
||||
if (xml == null) {
|
||||
throw new Error("Map could not be loaded");
|
||||
}
|
||||
|
||||
var parser = new DOMParser();
|
||||
return parser.parseFromString(xml, "text/xml");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@@ -270,6 +270,11 @@ mindplot.CommandContext = new Class({
|
||||
return mindmap.createNode(mindplot.NodeModel.MAIN_TOPIC_TYPE);
|
||||
},
|
||||
|
||||
addTopic:function (topic) {
|
||||
var mindmap = this._designer.getMindmap();
|
||||
return mindmap.addBranch(topic.getModel());
|
||||
},
|
||||
|
||||
connect:function (childTopic, parentTopic) {
|
||||
childTopic.connectTo(parentTopic, this._designer._workspace);
|
||||
},
|
||||
|
@@ -598,7 +598,7 @@ mindplot.Topic = new Class({
|
||||
|
||||
areChildrenShrunken:function () {
|
||||
var model = this.getModel();
|
||||
return model.areChildrenShrunken();
|
||||
return model.areChildrenShrunken() && !this.isCentralTopic();
|
||||
},
|
||||
|
||||
isCollapsed:function () {
|
||||
@@ -888,7 +888,12 @@ mindplot.Topic = new Class({
|
||||
|
||||
_setRelationshipLinesVisibility:function (value) {
|
||||
this._relationships.each(function (relationship) {
|
||||
relationship.setVisibility(value);
|
||||
var sourceTopic = relationship.getSourceTopic();
|
||||
var targetTopic = relationship.getTargetTopic();
|
||||
|
||||
var targetParent = targetTopic.getModel().getParent();
|
||||
var sourceParent = sourceTopic.getModel().getParent();
|
||||
relationship.setVisibility(value && (targetParent == null || !targetParent.areChildrenShrunken()) && (sourceParent == null || !sourceParent.areChildrenShrunken()));
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1203,7 +1208,7 @@ mindplot.Topic = new Class({
|
||||
var relationships = child.getRelationships();
|
||||
result = result.concat(relationships);
|
||||
|
||||
if(!child.areChildrenShrunken()){
|
||||
if (!child.areChildrenShrunken()) {
|
||||
var innerChilds = this._flatten2DElements(child);
|
||||
result = result.concat(innerChilds);
|
||||
}
|
||||
|
@@ -41,6 +41,8 @@ mindplot.commands.AddTopicCommand = new Class({
|
||||
var parentTopic = commandContext.findTopics(parentId)[0];
|
||||
commandContext.connect(topic, parentTopic);
|
||||
}
|
||||
}else {
|
||||
commandContext.addTopic(topic);
|
||||
}
|
||||
|
||||
// Select just created node ...
|
||||
|
@@ -149,6 +149,20 @@ mindplot.commands.DeleteCommand = new Class({
|
||||
return this._collectInDepthRelationships(topic);
|
||||
}, this);
|
||||
result.append(rels.flatten());
|
||||
|
||||
if (result.length > 0) {
|
||||
// Filter for unique ...
|
||||
result = result.sort(function (a, b) {
|
||||
return a.getModel().getId() - b.getModel().getId();
|
||||
});
|
||||
var ret = [result[0]];
|
||||
for (var i = 1; i < result.length; i++) { // start loop at 1 as element 0 can never be a duplicate
|
||||
if (result[i - 1] !== result[i]) {
|
||||
ret.push(result[i]);
|
||||
}
|
||||
}
|
||||
result = ret;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -93,7 +93,7 @@ mindplot.model.RelationshipModel = new Class({
|
||||
this._startArrow = startArrow;
|
||||
},
|
||||
|
||||
clone:function (model) {
|
||||
clone:function () {
|
||||
var result = new mindplot.model.RelationshipModel(this._sourceTargetId, this._targetTopicId);
|
||||
result._id = this._id;
|
||||
result._lineType = this._lineType;
|
||||
|
@@ -92,7 +92,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({
|
||||
|
||||
}
|
||||
|
||||
if (topic.areChildrenShrunken()) {
|
||||
if (topic.areChildrenShrunken() && topic.getType() != mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
parentTopic.setAttribute('shrink', 'true');
|
||||
}
|
||||
|
||||
@@ -319,7 +319,8 @@ mindplot.persistence.XMLSerializer_Pela = new Class({
|
||||
}
|
||||
|
||||
var isShrink = domElem.getAttribute('shrink');
|
||||
if ($defined(isShrink)) {
|
||||
// Hack: Some production maps has been stored with the central topic collapsed. This is a bug.
|
||||
if ($defined(isShrink) && type!=mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
topic.setChildrenShrunken(isShrink);
|
||||
}
|
||||
|
||||
|
@@ -46,15 +46,16 @@ mindplot.util.Shape =
|
||||
calculateRelationShipPointCoordinates:function (topic, controlPoint) {
|
||||
var size = topic.getSize();
|
||||
var position = topic.getPosition();
|
||||
var div = (position.x - controlPoint.x);
|
||||
div = (Math.abs(div) > 0.1 ? div : 0.1); // Prevent division by 0.
|
||||
var m;
|
||||
var yGap = position.y - controlPoint.y;
|
||||
var xGap = position.x - controlPoint.x;
|
||||
var disable = Math.abs(yGap) < 5 || Math.abs(xGap) < 5 || Math.abs(yGap - xGap) < 5;
|
||||
|
||||
var m = (position.y - controlPoint.y) / div;
|
||||
var y, x;
|
||||
var gap = 5;
|
||||
if (controlPoint.y > position.y + (size.height / 2)) {
|
||||
y = position.y + (size.height / 2) + gap;
|
||||
x = position.x - ((position.y - y) / m);
|
||||
x = !disable ? position.x - ((position.y - y) / (yGap / xGap)) : position.x;
|
||||
if (x > position.x + (size.width / 2)) {
|
||||
x = position.x + (size.width / 2);
|
||||
} else if (x < position.x - (size.width / 2)) {
|
||||
@@ -62,7 +63,7 @@ mindplot.util.Shape =
|
||||
}
|
||||
} else if (controlPoint.y < position.y - (size.height / 2)) {
|
||||
y = position.y - (size.height / 2) - gap;
|
||||
x = position.x - ((position.y - y) / m);
|
||||
x = !disable ? position.x - ((position.y - y) / (yGap / xGap)) : position.x;
|
||||
if (x > position.x + (size.width / 2)) {
|
||||
x = position.x + (size.width / 2);
|
||||
} else if (x < position.x - (size.width / 2)) {
|
||||
@@ -70,10 +71,10 @@ mindplot.util.Shape =
|
||||
}
|
||||
} else if (controlPoint.x < (position.x - size.width / 2)) {
|
||||
x = position.x - (size.width / 2) - gap;
|
||||
y = position.y - (m * (position.x - x));
|
||||
y = !disable ? position.y - ((yGap / xGap) * (position.x - x)) : position.y;
|
||||
} else {
|
||||
x = position.x + (size.width / 2) + gap;
|
||||
y = position.y - (m * (position.x - x));
|
||||
y = !disable ? position.y - ((yGap / xGap) * (position.x - x)) : position.y;
|
||||
}
|
||||
|
||||
return new core.Point(x, y);
|
||||
@@ -97,6 +98,31 @@ mindplot.util.Shape =
|
||||
var y2 = m * (x2 - tarPos.x) + tarPos.y;
|
||||
|
||||
return [new core.Point(-srcPos.x + x1, -srcPos.y + y1), new core.Point(-tarPos.x + x2, -tarPos.y + y2)];
|
||||
},
|
||||
|
||||
workoutIncomingConnectionPoint:function (targetNode, sourcePosition) {
|
||||
$assert(sourcePosition, 'sourcePoint can not be null');
|
||||
var pos = targetNode.getPosition();
|
||||
var size = targetNode.getSize();
|
||||
|
||||
var isAtRight = mindplot.util.Shape.isAtRight(sourcePosition, pos);
|
||||
var result = mindplot.util.Shape.calculateRectConnectionPoint(pos, size, isAtRight);
|
||||
if (targetNode.getShapeType() == mindplot.model.TopicShape.LINE) {
|
||||
result.y = result.y + (targetNode.getSize().height / 2);
|
||||
}
|
||||
|
||||
// Move a little the position...
|
||||
var offset = mindplot.Topic.CONNECTOR_WIDTH / 2;
|
||||
if (!isAtRight) {
|
||||
result.x = result.x + offset;
|
||||
} else {
|
||||
result.x = result.x - offset;
|
||||
}
|
||||
|
||||
result.x = Math.ceil(result.x);
|
||||
result.y = Math.ceil(result.y);
|
||||
return result;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -29,7 +29,7 @@ mindplot.widget.IconPanel = new Class({
|
||||
|
||||
buildPanel:function () {
|
||||
var content = new Element('div', {'class':'toolbarPanel', 'id':'IconsPanel'});
|
||||
content.setStyles({width:253, height:210, padding:5});
|
||||
content.setStyles({width:253, height:230, padding:5});
|
||||
content.addEvent("click", function (event) {
|
||||
event.stopPropagation()
|
||||
});
|
||||
|
@@ -99,7 +99,7 @@ mindplot.widget.LinkEditor = new Class({
|
||||
});
|
||||
openButton.inject(form);
|
||||
openButton.addEvent('click',function(){
|
||||
window.open(input.value,"_blank", "status=1,width=700,height=450,resize=1");
|
||||
window.open(input.value,"_blank", "status=1,width=700,height=450,resizable=1");
|
||||
});
|
||||
|
||||
|
||||
|
@@ -223,9 +223,10 @@ mindplot.widget.Menu = new Class({
|
||||
this._registerTooltip('export', $msg('EXPORT'));
|
||||
|
||||
this._addButton('print', false, false, function () {
|
||||
this.save(saveElem, designer, false);
|
||||
var baseUrl = window.location.href.substring(0, window.location.href.lastIndexOf("c/maps/"));
|
||||
window.open(baseUrl + 'c/maps/' + mapId + '/print');
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
this._registerTooltip('print', $msg('PRINT'));
|
||||
|
||||
@@ -274,7 +275,7 @@ mindplot.widget.Menu = new Class({
|
||||
}
|
||||
|
||||
this._addButton('addTopic', true, false, function () {
|
||||
designer.createChildForSelectedNode();
|
||||
designer.createSiblingForSelectedNode();
|
||||
});
|
||||
this._registerTooltip('addTopic', $msg('ADD_TOPIC'), "Enter");
|
||||
|
||||
@@ -432,6 +433,20 @@ mindplot.widget.Menu = new Class({
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var videoElem = $("tutorialVideo");
|
||||
if (videoElem) {
|
||||
var width = 900;
|
||||
var height = 500;
|
||||
var left = (screen.width / 2) - (width / 2);
|
||||
var top = (screen.height / 2) - (height / 2);
|
||||
|
||||
videoElem.addEvent('click', function (event) {
|
||||
window.open("https://www.youtube.com/tv?vq=medium#/watch?v=rKxZwNKs9cE", "_blank", 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=yes, copyhistory=no, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_registerEvents:function (designer) {
|
||||
|
59
mindplot/src/main/resources/messages_de.properties
Normal file
@@ -0,0 +1,59 @@
|
||||
ZOOM_IN=Ansicht vergrößern
|
||||
ZOOM_OUT=Ansicht verkleinern
|
||||
TOPIC_SHAPE=Themen Gestaltung
|
||||
TOPIC_ADD=Thema hinzufügen
|
||||
TOPIC_DELETE=Thema löschen
|
||||
TOPIC_ICON=Symbol hinzufügen
|
||||
TOPIC_LINK=Verbindung hinzufügen
|
||||
TOPIC_RELATIONSHIP=Beziehung
|
||||
TOPIC_COLOR=Themenfarbe
|
||||
TOPIC_BORDER_COLOR=Thema Randfarbe
|
||||
TOPIC_NOTE=Notiz hinzufügen
|
||||
FONT_FAMILY=Schrifttyp
|
||||
FONT_SIZE=Schriftgröße
|
||||
FONT_BOLD=Fette Schrift
|
||||
FONT_ITALIC=Kursive Schrift
|
||||
UNDO=Rückgängig machen
|
||||
REDO=Wiederholen
|
||||
INSERT=Einfügen
|
||||
SAVE=Sichern
|
||||
NOTE=Notiz
|
||||
|
||||
ADD_TOPIC=Thema hinzufügen
|
||||
LOADING=Laden ...
|
||||
EXPORT=Exportieren
|
||||
PRINT=Drucken
|
||||
PUBLISH=Publizieren
|
||||
COLLABORATE=Mitbenutzen
|
||||
HISTORY=Historie
|
||||
DISCARD_CHANGES=Änderungen verwerfen
|
||||
FONT_COLOR=Textfarbe
|
||||
SAVING=Sichern ...
|
||||
SAVE_COMPLETE=Sichern abgeschlossen
|
||||
|
||||
ZOOM_IN_ERROR=Zoom zu hoch.
|
||||
ZOOM_ERROR=Es kann nicht weiter vergrößert bzw. verkelinert werden.
|
||||
ONLY_ONE_TOPIC_MUST_BE_SELECTED=Thema konnte nicht angelegt werden. Bitte wählen Sie nur ein Thema aus.
|
||||
ONE_TOPIC_MUST_BE_SELECTED=Thema konnte nicht angelegt werden. Es muss ein Thema ausgewählt werden.
|
||||
ONLY_ONE_TOPIC_MUST_BE_SELECTED_COLLAPSE=Kinderknoten können nicht eingefaltet werden. Es muss ein Thema ausgewäht werden.
|
||||
SAVE_COULD_NOT_BE_COMPLETED=Sichern wurde nicht abgeschlossen. Versuchen Sie es später nocheinmal.
|
||||
UNEXPECTED_ERROR_LOADING=E tut uns Leid, ein unerwarteter Fehler ist aufgetreten.\nVersuchen Sie, den Editor neu zu laden. Falls das Problem erneut auftritt, bitte kontaktieren Sie uns unter support@wisemapping.com.
|
||||
MAIN_TOPIC=Hauptthema
|
||||
SUB_TOPIC=Unterthema
|
||||
ISOLATED_TOPIC=Isoliertes Thema
|
||||
CENTRAL_TOPIC=Zentrales Thema
|
||||
SHORTCUTS=Tastaturkürzel
|
||||
|
||||
ENTITIES_COULD_NOT_BE_DELETED=Konnte das Thema oder die Beziehung nicht löschen. Es muss mindest ein Eintrag ausgewählt sein.
|
||||
AT_LEAST_ONE_TOPIC_MUST_BE_SELECTED=Es muss mindestens ein Thema ausgewählt sein.
|
||||
CLIPBOARD_IS_EMPTY=Es gibt nichts zu kopieren. Die Zwischenablage ist leer.
|
||||
CENTRAL_TOPIC_CAN_NOT_BE_DELETED=Das zentrale Thema kann nicht gelöscht werden.
|
||||
RELATIONSHIP_COULD_NOT_BE_CREATED=Die Beziehung konnte nicht angelegt werden. Es muss erst ein Vater-Thema ausgewählt werden, um die Beziehung herzustellen.
|
||||
SELECTION_COPIED_TO_CLIPBOARD=Themen in der Zwischenablage
|
||||
WRITE_YOUR_TEXT_HERE=Schreiben Sie ihre Notiz hier ...
|
||||
REMOVE=Entfernen
|
||||
ACCEPT=Akzeptieren
|
||||
CANCEL=Abbrechen
|
||||
LINK=Verbindung
|
||||
OPEN_LINK=Öffne URL
|
||||
|
@@ -89,7 +89,7 @@ function testElementFill()
|
||||
assertEquals(opacity, fill.opacity);
|
||||
}
|
||||
|
||||
// Set attributes
|
||||
// Set delegated
|
||||
elem.setAttribute('fillColor', color);
|
||||
elem.setAttribute('fillOpacity', opacity);
|
||||
|
||||
|
@@ -30,6 +30,7 @@ function createStorageManager(mindplot) {
|
||||
},
|
||||
|
||||
loadMapDom : function(mapId) {
|
||||
var xml;
|
||||
var xmlRequest = new Request({
|
||||
url: this.backendUrl + mapId,
|
||||
method: 'get',
|
||||
|
@@ -1,6 +1,5 @@
|
||||
@import "compatibility.less";
|
||||
@import "css/libraries/moodialog/css/MooDialog.css";
|
||||
|
||||
/********************************************************************************/
|
||||
/* Header & Toolbar Styles */
|
||||
/********************************************************************************/
|
||||
@@ -13,7 +12,8 @@ body {
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
overflow:hidden;
|
||||
overflow: hidden;
|
||||
position: fixed
|
||||
}
|
||||
|
||||
div#mindplot {
|
||||
@@ -21,7 +21,7 @@ div#mindplot {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height:100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -36,8 +36,8 @@ div#small_error_icon {
|
||||
background-color: #dfcf3c;
|
||||
padding: 5px 15px;
|
||||
color: #666666;
|
||||
/*font-weight: bold;*/
|
||||
/*width: 100px;*/
|
||||
/*font-weight: bold;*/
|
||||
/*width: 100px;*/
|
||||
font-size: 13px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
@@ -49,8 +49,8 @@ div#small_error_icon {
|
||||
background-color: #dfcf3c;
|
||||
padding: 5px 15px;
|
||||
color: #666666;
|
||||
/*font-weight: bold;*/
|
||||
/*width: 100px;*/
|
||||
/*font-weight: bold;*/
|
||||
/*width: 100px;*/
|
||||
font-size: 13px;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
@@ -150,18 +150,18 @@ div#small_error_icon {
|
||||
/* Modal dialogs definitions */
|
||||
|
||||
div.modalDialog {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 11000;
|
||||
width: 500px;
|
||||
margin: -250px 0 0 -250px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #999;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 11000;
|
||||
width: 500px;
|
||||
margin: -250px 0 0 -250px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #999;
|
||||
padding: 10px;
|
||||
overflow: auto;
|
||||
|
||||
/* IE6-7 */
|
||||
/* IE6-7 */
|
||||
-webkit-border-radius: 6px;
|
||||
-moz-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
@@ -178,31 +178,40 @@ div.modalDialog .content {
|
||||
padding: 5px 5px;
|
||||
}
|
||||
|
||||
div.modalDialog .title
|
||||
{
|
||||
div.modalDialog .title {
|
||||
font-weight: bold;
|
||||
text-shadow: 1px 1px 0 #fff;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 5px 15px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/*--- End Modal Dialog Form ---*/
|
||||
|
||||
.publishModalDialog .content{
|
||||
height:420px;
|
||||
.publishModalDialog .content {
|
||||
height: 420px;
|
||||
}
|
||||
|
||||
.exportModalDialog .content{
|
||||
height:400px;
|
||||
.exportModalDialog .content {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.shareModalDialog .content {
|
||||
height:440px;
|
||||
height: 440px;
|
||||
}
|
||||
|
||||
div.shareModalDialog {
|
||||
width: 550px;
|
||||
}
|
||||
|
||||
#tutorialVideo{
|
||||
background: url(../images/help.png) no-repeat left center;
|
||||
padding-left: 19px;
|
||||
}
|
||||
|
||||
#keyboardShortcuts{
|
||||
background: url(../images/help.png) no-repeat left center;
|
||||
padding-left: 19px;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,6 +1,9 @@
|
||||
@import "editor.less";
|
||||
|
||||
/* Overwrite some styles */
|
||||
body{
|
||||
position: inherit;
|
||||
}
|
||||
|
||||
div#headerInfo {
|
||||
height: 0;
|
||||
|
BIN
wise-editor/src/main/webapp/icons/number_1.png
Executable file
After Width: | Height: | Size: 3.4 KiB |
BIN
wise-editor/src/main/webapp/icons/number_2.png
Executable file
After Width: | Height: | Size: 3.5 KiB |
BIN
wise-editor/src/main/webapp/icons/number_3.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
wise-editor/src/main/webapp/icons/number_4.png
Executable file
After Width: | Height: | Size: 3.5 KiB |
BIN
wise-editor/src/main/webapp/icons/number_5.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
wise-editor/src/main/webapp/icons/number_6.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
wise-editor/src/main/webapp/icons/number_7.png
Executable file
After Width: | Height: | Size: 3.4 KiB |
BIN
wise-editor/src/main/webapp/icons/number_8.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
wise-editor/src/main/webapp/icons/number_9.png
Executable file
After Width: | Height: | Size: 3.6 KiB |
BIN
wise-editor/src/main/webapp/icons/task_0.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
wise-editor/src/main/webapp/icons/task_100.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
wise-editor/src/main/webapp/icons/task_25.png
Executable file
After Width: | Height: | Size: 3.2 KiB |
BIN
wise-editor/src/main/webapp/icons/task_50.png
Executable file
After Width: | Height: | Size: 3.2 KiB |
BIN
wise-editor/src/main/webapp/icons/task_75.png
Executable file
After Width: | Height: | Size: 3.2 KiB |
BIN
wise-editor/src/main/webapp/images/logo-135x135.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
wise-editor/src/main/webapp/images/logo-head-only.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
@@ -87,7 +87,7 @@ function buildDesigner(options) {
|
||||
}
|
||||
|
||||
} else {
|
||||
persistence = new mindplot.LocalStorageManager();
|
||||
persistence = new mindplot.LocalStorageManager("samples/{id}.xml");
|
||||
}
|
||||
mindplot.PersistenceManager.init(persistence);
|
||||
|
||||
|
@@ -22,4 +22,6 @@ Deleting a based on the user id:
|
||||
* Template Path: /service/admin/users/{userId}
|
||||
* curl "http://{host.name}:{host.port}/{context.path}/service/admin/users/{userId}" --request delete --basic -u "admin@wisemapping.org:admin"
|
||||
|
||||
|
||||
Changing Password:
|
||||
Template Path: /service/admin/users/{userId}/password
|
||||
* curl "http://{host.name}:{host.port}/{context.path}/service/admin/users/{userId}/password" --request put --basic -u "admin@wisemapping.org:admin" -H "Content-Type:text/plain" --data "<new_password>"
|
||||
|
@@ -28,7 +28,7 @@
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<org.springframework.version>3.1.0.RELEASE</org.springframework.version>
|
||||
<org.springframework.version>3.1.3.RELEASE</org.springframework.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -77,6 +77,12 @@
|
||||
<version>${org.springframework.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-ldap</artifactId>
|
||||
<version>${org.springframework.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
|
@@ -57,11 +57,9 @@ public class MindmapManagerImpl
|
||||
final Criteria hibernateCriteria = getSession().createCriteria(MindMapHistory.class);
|
||||
hibernateCriteria.add(Restrictions.eq("mindmapId", mindmapId));
|
||||
hibernateCriteria.addOrder(Order.desc("creationTime"));
|
||||
// Mientras no haya paginacion solo los 10 primeros
|
||||
// This line throws errors in some environments, so getting all history and taking firsts 10 records
|
||||
// hibernateCriteria.setMaxResults(10);
|
||||
List list = hibernateCriteria.list();
|
||||
return list.subList(0, (10 < list.size() ? 10 : list.size()));
|
||||
hibernateCriteria.setMaxResults(30);
|
||||
return hibernateCriteria.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -203,6 +201,13 @@ public class MindmapManagerImpl
|
||||
|
||||
@Override
|
||||
public void removeMindmap(@NotNull final Mindmap mindMap) {
|
||||
// Delete history first ...
|
||||
final Criteria hibernateCriteria = getSession().createCriteria(MindMapHistory.class);
|
||||
hibernateCriteria.add(Restrictions.eq("mindmapId", mindMap.getId()));
|
||||
List list = hibernateCriteria.list();
|
||||
getHibernateTemplate().deleteAll(list);
|
||||
|
||||
// Delete mindmap ....
|
||||
getHibernateTemplate().delete(mindMap);
|
||||
}
|
||||
|
||||
|
@@ -28,4 +28,8 @@ abstract public class ClientException extends WiseMappingException {
|
||||
public Severity getSeverity() {
|
||||
return this.severity;
|
||||
}
|
||||
|
||||
public String getTechInfo() {
|
||||
return getMessage();
|
||||
}
|
||||
}
|
||||
|
@@ -23,11 +23,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class MultipleSessionsOpenException
|
||||
extends ClientException
|
||||
{
|
||||
public static final String MSG_KEY = "MINDMAP_TIMESTAMP_OUTDATED";
|
||||
public static final String MSG_KEY = "MINDMAP_OUTDATED_BY_YOU";
|
||||
|
||||
public MultipleSessionsOpenException(@NotNull String msg)
|
||||
public MultipleSessionsOpenException(@NotNull String techInfo)
|
||||
{
|
||||
super(msg,Severity.INFO);
|
||||
super(techInfo,Severity.INFO);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -35,9 +35,4 @@ public class MultipleSessionsOpenException
|
||||
protected String getMsgBundleKey() {
|
||||
return MSG_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object[] getMsgBundleArgs() {
|
||||
return new String[]{"you"};
|
||||
}
|
||||
}
|
||||
|
@@ -26,8 +26,8 @@ public class SessionExpiredException
|
||||
public static final String MSG_KEY = "MINDMAP_TIMESTAMP_OUTDATED";
|
||||
private User lastUpdater;
|
||||
|
||||
public SessionExpiredException(@NotNull User lastUpdater) {
|
||||
super("Map has been updated by " + (lastUpdater != null ? lastUpdater.getEmail() : ""), Severity.FATAL);
|
||||
public SessionExpiredException(@NotNull String debugInfo, @NotNull User lastUpdater) {
|
||||
super(debugInfo, Severity.FATAL);
|
||||
this.lastUpdater = lastUpdater;
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,9 @@
|
||||
|
||||
package com.wisemapping.exporter;
|
||||
|
||||
import org.apache.batik.parser.AWTTransformProducer;
|
||||
import org.apache.batik.parser.ParseException;
|
||||
import org.apache.batik.parser.TransformListParser;
|
||||
import org.apache.batik.transcoder.Transcoder;
|
||||
import org.apache.batik.transcoder.TranscoderException;
|
||||
import org.apache.batik.transcoder.TranscoderInput;
|
||||
@@ -34,22 +37,23 @@ import org.xml.sax.SAXException;
|
||||
import sun.misc.BASE64Encoder;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.io.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ExporterFactory {
|
||||
private static final String GROUP_NODE_NAME = "g";
|
||||
private static final String RECT_NODE_NAME = "rect";
|
||||
private static final String IMAGE_NODE_NAME = "image";
|
||||
public static final int MARGING = 50;
|
||||
private File baseImgDir;
|
||||
|
||||
public ExporterFactory(@NotNull final ServletContext servletContext) throws ParserConfigurationException {
|
||||
@@ -60,7 +64,7 @@ public class ExporterFactory {
|
||||
this.baseImgDir = baseImgDir;
|
||||
}
|
||||
|
||||
public void export(@NotNull ExportProperties properties, @Nullable String xml, @NotNull OutputStream output, @Nullable String mapSvg) throws TranscoderException, IOException, ParserConfigurationException, SAXException, XMLStreamException, TransformerException, JAXBException, ExportException {
|
||||
public void export(@NotNull ExportProperties properties, @Nullable String xml, @NotNull OutputStream output, @Nullable String mapSvg) throws ExportException, IOException, TranscoderException {
|
||||
final ExportFormat format = properties.getFormat();
|
||||
|
||||
switch (format) {
|
||||
@@ -73,8 +77,7 @@ public class ExporterFactory {
|
||||
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth());
|
||||
|
||||
// Create the transcoder input.
|
||||
final Document document = normalizeSvg(mapSvg, false);
|
||||
final String svgString = domToString(document);
|
||||
final String svgString = normalizeSvg(mapSvg, false);
|
||||
final TranscoderInput input = new TranscoderInput(new CharArrayReader(svgString.toCharArray()));
|
||||
|
||||
TranscoderOutput trascoderOutput = new TranscoderOutput(output);
|
||||
@@ -94,8 +97,7 @@ public class ExporterFactory {
|
||||
transcoder.addTranscodingHint(ImageTranscoder.KEY_WIDTH, size.getWidth());
|
||||
|
||||
// Create the transcoder input.
|
||||
final Document document = normalizeSvg(mapSvg, false);
|
||||
final String svgString = domToString(document);
|
||||
final String svgString = normalizeSvg(mapSvg, false);
|
||||
final TranscoderInput input = new TranscoderInput(new CharArrayReader(svgString.toCharArray()));
|
||||
|
||||
TranscoderOutput trascoderOutput = new TranscoderOutput(output);
|
||||
@@ -109,10 +111,8 @@ public class ExporterFactory {
|
||||
final Transcoder transcoder = new PDFTranscoder();
|
||||
|
||||
// Create the transcoder input.
|
||||
final Document document = normalizeSvg(mapSvg, false);
|
||||
final String svgString = domToString(document);
|
||||
final String svgString = normalizeSvg(mapSvg, false);
|
||||
final TranscoderInput input = new TranscoderInput(new CharArrayReader(svgString.toCharArray()));
|
||||
|
||||
TranscoderOutput trascoderOutput = new TranscoderOutput(output);
|
||||
|
||||
// Save the image.
|
||||
@@ -120,8 +120,8 @@ public class ExporterFactory {
|
||||
break;
|
||||
}
|
||||
case SVG: {
|
||||
final Document dom = normalizeSvg(mapSvg, true);
|
||||
output.write(domToString(dom).getBytes("UTF-8"));
|
||||
final String svgString = normalizeSvg(mapSvg, true);
|
||||
output.write(svgString.getBytes("UTF-8"));
|
||||
break;
|
||||
}
|
||||
case FREEMIND: {
|
||||
@@ -134,47 +134,56 @@ public class ExporterFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private Document normalizeSvg(@NotNull String svgXml, boolean embedImg) throws XMLStreamException, ParserConfigurationException, IOException, SAXException, TransformerException {
|
||||
private String normalizeSvg(@NotNull String svgXml, boolean embedImg) throws ExportException {
|
||||
|
||||
final DocumentBuilder documentBuilder = getDocumentBuilder();
|
||||
if (!svgXml.trim().startsWith("<svg xmlns=\"http://www.w3.org/2000/svg\"")) {
|
||||
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
|
||||
} else {
|
||||
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
|
||||
}
|
||||
|
||||
// Hacks for some legacy cases ....
|
||||
svgXml = svgXml.replaceAll("NaN,", "0");
|
||||
svgXml = svgXml.replaceAll(",NaN", "0");
|
||||
|
||||
Document document;
|
||||
try {
|
||||
final Reader in = new CharArrayReader(svgXml.toCharArray());
|
||||
final InputSource is = new InputSource(in);
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
final DocumentBuilder documentBuilder = factory.newDocumentBuilder();
|
||||
|
||||
document = documentBuilder.parse(is);
|
||||
if (!svgXml.trim().startsWith("<svg xmlns=\"http://www.w3.org/2000/svg\"")) {
|
||||
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
|
||||
} else {
|
||||
svgXml = svgXml.replaceFirst("<svg ", "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" ");
|
||||
}
|
||||
|
||||
// Hacks for some legacy cases ....
|
||||
svgXml = svgXml.replaceAll("NaN,", "0");
|
||||
svgXml = svgXml.replaceAll(",NaN", "0");
|
||||
|
||||
// Bratik do not manage nbsp properly.
|
||||
svgXml = svgXml.replaceAll(Pattern.quote(" "), " ");
|
||||
|
||||
Document document;
|
||||
try {
|
||||
final Reader in = new CharArrayReader(svgXml.toCharArray());
|
||||
final InputSource is = new InputSource(in);
|
||||
|
||||
document = documentBuilder.parse(is);
|
||||
} catch (SAXException e) {
|
||||
// It must be a corrupted SVG format. Try to hack it and try again ...
|
||||
svgXml = svgXml.replaceAll("<image([^>]+)>", "<image$1/>");
|
||||
|
||||
final Reader in = new CharArrayReader(svgXml.toCharArray());
|
||||
final InputSource is = new InputSource(in);
|
||||
document = documentBuilder.parse(is);
|
||||
}
|
||||
|
||||
resizeSVG(document);
|
||||
|
||||
final Node child = document.getFirstChild();
|
||||
inlineImages(document, (Element) child);
|
||||
|
||||
return domToString(document);
|
||||
} catch (ParserConfigurationException e) {
|
||||
throw new ExportException(e);
|
||||
} catch (IOException e) {
|
||||
throw new ExportException(e);
|
||||
} catch (SAXException e) {
|
||||
// It must be a corrupted SVG format. Try to hack it and try again ...
|
||||
svgXml = svgXml.replaceAll("<image([^>]+)>", "<image$1/>");
|
||||
|
||||
final Reader in = new CharArrayReader(svgXml.toCharArray());
|
||||
final InputSource is = new InputSource(in);
|
||||
document = documentBuilder.parse(is);
|
||||
throw new ExportException(e);
|
||||
} catch (TransformerException e) {
|
||||
throw new ExportException(e);
|
||||
}
|
||||
|
||||
|
||||
fitSvg(document);
|
||||
|
||||
final Node child = document.getFirstChild();
|
||||
fixImageTagHref(document, (Element) child);
|
||||
|
||||
return document;
|
||||
|
||||
}
|
||||
|
||||
private static DocumentBuilder getDocumentBuilder() throws ParserConfigurationException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
return factory.newDocumentBuilder();
|
||||
}
|
||||
|
||||
private static String domToString(@NotNull Document document) throws TransformerException {
|
||||
@@ -198,7 +207,7 @@ public class ExporterFactory {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private void fixImageTagHref(@NotNull Document document, @NotNull Element element) {
|
||||
private void inlineImages(@NotNull Document document, @NotNull Element element) {
|
||||
|
||||
final NodeList list = element.getChildNodes();
|
||||
|
||||
@@ -207,7 +216,7 @@ public class ExporterFactory {
|
||||
// find all groups
|
||||
if (GROUP_NODE_NAME.equals(node.getNodeName())) {
|
||||
// Must continue looking ....
|
||||
fixImageTagHref(document, (Element) node);
|
||||
inlineImages(document, (Element) node);
|
||||
|
||||
} else if (IMAGE_NODE_NAME.equals(node.getNodeName())) {
|
||||
|
||||
@@ -277,68 +286,72 @@ public class ExporterFactory {
|
||||
}
|
||||
}
|
||||
|
||||
private static void fitSvg(Document document) {
|
||||
// viewBox size
|
||||
int mapWidth = 1024;
|
||||
int mapHeight = 768;
|
||||
// some browser return width and heigth with precision
|
||||
float currentMaxWidth = 0;
|
||||
float currentMaxHeight = 0;
|
||||
private static void resizeSVG(@NotNull Document document) throws ExportException {
|
||||
|
||||
final Element svgNode = (Element) document.getFirstChild();
|
||||
final NodeList list = svgNode.getChildNodes();
|
||||
try {
|
||||
XPathFactory xPathfactory = XPathFactory.newInstance();
|
||||
XPath xpath = xPathfactory.newXPath();
|
||||
XPathExpression expr = xpath.compile("/svg/g/rect");
|
||||
|
||||
for (int i = 0; i < list.getLength(); i++) {
|
||||
final Node node = list.item(i);
|
||||
// find all groups
|
||||
if (GROUP_NODE_NAME.equals(node.getNodeName())) {
|
||||
final NamedNodeMap groupAttributes = node.getAttributes();
|
||||
NodeList nl = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
|
||||
final int length = nl.getLength();
|
||||
double maxX = 0, minX = 0, minY = 0, maxY = 0;
|
||||
|
||||
final String[] transformUnit = getTransformUnit(groupAttributes);
|
||||
|
||||
int groupPositionX = Integer.parseInt(transformUnit[0].trim());
|
||||
int groupPositionY = 0;
|
||||
if (transformUnit.length > 1) {
|
||||
groupPositionY = Integer.parseInt(transformUnit[1].trim());
|
||||
for (int i = 0; i < length; i++) {
|
||||
final Element rectElem = (Element) nl.item(i);
|
||||
final Element gElem = (Element) rectElem.getParentNode();
|
||||
|
||||
|
||||
final TransformListParser p = new TransformListParser();
|
||||
final AWTTransformProducer tp = new AWTTransformProducer();
|
||||
p.setTransformListHandler(tp);
|
||||
p.parse(gElem.getAttribute("transform"));
|
||||
final AffineTransform transform = tp.getAffineTransform();
|
||||
|
||||
double yPos = transform.getTranslateY();
|
||||
if (yPos > 0) {
|
||||
yPos += Double.parseDouble(rectElem.getAttribute("height"));
|
||||
}
|
||||
maxY = maxY < yPos ? yPos : maxY;
|
||||
minY = minY > yPos ? yPos : minY;
|
||||
|
||||
double xPos = transform.getTranslateX();
|
||||
if (xPos > 0) {
|
||||
xPos += Double.parseDouble(rectElem.getAttribute("width"));
|
||||
}
|
||||
|
||||
int signumX = Integer.signum(groupPositionX);
|
||||
int signumY = Integer.signum(groupPositionY);
|
||||
|
||||
final NodeList groupChildren = node.getChildNodes();
|
||||
for (int idx = 0; idx < groupChildren.getLength(); idx++) {
|
||||
final Node rectNode = groupChildren.item(idx);
|
||||
float curentHeight = 0;
|
||||
float curentWidth = 0;
|
||||
|
||||
// If has a rect use the rect to calcular the real width of the topic
|
||||
if (RECT_NODE_NAME.equals(rectNode.getNodeName())) {
|
||||
final NamedNodeMap rectAttributes = rectNode.getAttributes();
|
||||
|
||||
final Node attributeHeight = rectAttributes.getNamedItem("height");
|
||||
final Node attributeWidth = rectAttributes.getNamedItem("width");
|
||||
|
||||
curentHeight = Float.valueOf(attributeHeight.getNodeValue());
|
||||
curentWidth = Float.valueOf(attributeWidth.getNodeValue());
|
||||
}
|
||||
|
||||
float newMaxWidth = groupPositionX + (curentWidth * signumX);
|
||||
if (Math.abs(currentMaxWidth) < Math.abs(newMaxWidth)) {
|
||||
currentMaxWidth = newMaxWidth;
|
||||
}
|
||||
|
||||
float newMaxHeight = groupPositionY + curentHeight * signumY;
|
||||
if (Math.abs(currentMaxHeight) < Math.abs(newMaxHeight)) {
|
||||
currentMaxHeight = newMaxHeight;
|
||||
}
|
||||
}
|
||||
maxX = maxX < xPos ? xPos : maxX;
|
||||
minX = minX > xPos ? xPos : minX;
|
||||
}
|
||||
}
|
||||
|
||||
svgNode.setAttribute("viewBox", -Math.abs(currentMaxWidth) + " " + -Math.abs(currentMaxHeight) + " " + Math.abs(currentMaxWidth * 2) + " " + Math.abs(currentMaxHeight * 2));
|
||||
svgNode.setAttribute("width", Float.toString(mapWidth / 2));
|
||||
svgNode.setAttribute("height", Float.toString(mapHeight / 2));
|
||||
svgNode.setAttribute("preserveAspectRatio", "xMinYMin");
|
||||
// Add some extra margin ...
|
||||
maxX += MARGING;
|
||||
minX += -MARGING;
|
||||
|
||||
maxY += MARGING;
|
||||
minY += -MARGING;
|
||||
|
||||
// Calculate dimentions ...
|
||||
final double width = maxX + Math.abs(minX);
|
||||
final double height = maxY + Math.abs(minY);
|
||||
|
||||
// Finally, update centers ...
|
||||
final Element svgNode = (Element) document.getFirstChild();
|
||||
|
||||
svgNode.setAttribute("viewBox", minX + " " + minY + " " + width + " " + height);
|
||||
svgNode.setAttribute("width", Double.toString(width));
|
||||
svgNode.setAttribute("height", Double.toString(height));
|
||||
svgNode.setAttribute("preserveAspectRatio", "xMinYMin");
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new ExportException(e);
|
||||
} catch (ParseException e) {
|
||||
throw new ExportException(e);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ExportException(e);
|
||||
} catch (DOMException e) {
|
||||
throw new ExportException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String[] getTransformUnit(NamedNodeMap groupAttributes) {
|
||||
|
@@ -225,7 +225,7 @@ public class FreemindExporter
|
||||
private void addNote(com.wisemapping.jaxb.freemind.Node fnode, com.wisemapping.jaxb.wisemap.TopicType mindmapTopic) throws IOException, SAXException, ParserConfigurationException {
|
||||
final Note note = mindmapTopic.getNote();
|
||||
if (note != null) {
|
||||
final String noteStr = note.getText() != null ? note.getText() : note.getTextAttr();
|
||||
final String noteStr = note.getValue() != null ? note.getValue() : note.getTextAttr();
|
||||
if (noteStr != null) {
|
||||
final Richcontent richcontent = buildRichContent(noteStr, "NOTE");
|
||||
fnode.getArrowlinkOrCloudOrEdge().add(richcontent);
|
||||
|
@@ -42,6 +42,8 @@ public class RequestPropertiesInterceptor extends HandlerInterceptorAdapter {
|
||||
@Value("${site.baseurl}")
|
||||
private String siteUrl;
|
||||
|
||||
@Value("${security.type}")
|
||||
private String securityType;
|
||||
|
||||
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object object) throws Exception {
|
||||
|
||||
@@ -49,6 +51,8 @@ public class RequestPropertiesInterceptor extends HandlerInterceptorAdapter {
|
||||
request.setAttribute("google.analytics.account", analyticsAccount);
|
||||
request.setAttribute("google.ads.enabled", adsEnabled);
|
||||
request.setAttribute("site.homepage", siteHomepage);
|
||||
request.setAttribute("security.type", securityType);
|
||||
|
||||
|
||||
// If the property could not be resolved, try to infer one from the request...
|
||||
if ("${site.baseurl}".equals(siteUrl)) {
|
||||
|
@@ -18,12 +18,17 @@
|
||||
|
||||
package com.wisemapping.importer;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.xml.serialize.OutputFormat;
|
||||
import org.apache.xml.serialize.XMLSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class JaxbCDATAMarshaller {
|
||||
@@ -38,7 +43,7 @@ public class JaxbCDATAMarshaller {
|
||||
// When processing xml that doesn't use namespaces, simply omit the
|
||||
// namespace prefix as shown in the third CDataElement below.
|
||||
of.setCDataElements(
|
||||
new String[]{"^text"}); //
|
||||
new String[]{"^text","^note"}); //
|
||||
|
||||
// set any other options you'd like
|
||||
// of.setPreserveSpace(true);
|
||||
@@ -46,10 +51,106 @@ public class JaxbCDATAMarshaller {
|
||||
of.setEncoding("UTF-8");
|
||||
|
||||
// create the serializer
|
||||
XMLSerializer result = new XMLSerializer(of);
|
||||
XMLSerializer result = new XMLSerializer(of) {
|
||||
@Override
|
||||
public void startElement(String s, String s1, String s2, Attributes attributes) throws SAXException {
|
||||
super.startElement(s, s1, s2, new SortedAttributesDecorator(attributes));
|
||||
}
|
||||
};
|
||||
result.setOutputByteStream(out);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class SortedAttributesDecorator implements Attributes {
|
||||
|
||||
final Map<Integer, Integer> sortedToUnsorted = new HashMap<Integer, Integer>();
|
||||
final Map<Integer, Integer> unsortedToSorted = new HashMap<Integer, Integer>();
|
||||
|
||||
private Attributes delegated;
|
||||
|
||||
SortedAttributesDecorator(final Attributes delegated) {
|
||||
this.delegated = delegated;
|
||||
int length = this.getLength();
|
||||
|
||||
// Sort by local part ...
|
||||
final Map<String, Integer> sortedMap = new TreeMap<String, Integer>();
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String localName = delegated.getLocalName(i);
|
||||
sortedMap.put(localName, i);
|
||||
}
|
||||
|
||||
Set<String> keySet = sortedMap.keySet();
|
||||
int sortedIndex = 0;
|
||||
for (String key : keySet) {
|
||||
final Integer unsortedIndex = sortedMap.get(key);
|
||||
sortedToUnsorted.put(sortedIndex, unsortedIndex);
|
||||
unsortedToSorted.put(unsortedIndex, sortedIndex);
|
||||
sortedIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLength() {
|
||||
return delegated.getLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURI(int index) {
|
||||
return delegated.getURI(sortedToUnsorted.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalName(int index) {
|
||||
return delegated.getLocalName(sortedToUnsorted.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQName(int index) {
|
||||
return delegated.getQName(sortedToUnsorted.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(int index) {
|
||||
return delegated.getType(sortedToUnsorted.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(int index) {
|
||||
return delegated.getValue(sortedToUnsorted.get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(String uri, String localName) {
|
||||
int unsorted = delegated.getIndex(uri, localName);
|
||||
return unsortedToSorted.get(unsorted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndex(String qName) {
|
||||
int unsorted = delegated.getIndex(qName);
|
||||
return unsortedToSorted.get(unsorted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(String uri, String localName) {
|
||||
return delegated.getType(uri, localName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(String qName) {
|
||||
return delegated.getType(qName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(String uri, String localName) {
|
||||
return delegated.getValue(uri, localName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(String qName) {
|
||||
return delegated.getValue(qName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -298,7 +298,7 @@ public class FreemindImporter
|
||||
if (textNote == null) // It is not a note is a BlinkingNodeHook or AutomaticLayout Hook
|
||||
{
|
||||
textNote = EMPTY_NOTE;
|
||||
mindmapNote.setText(textNote);
|
||||
mindmapNote.setValue(textNote);
|
||||
currentWiseTopic.setNote(mindmapNote);
|
||||
}
|
||||
} else if (element instanceof Richcontent) {
|
||||
@@ -312,7 +312,7 @@ public class FreemindImporter
|
||||
String text = html2text(content);
|
||||
final com.wisemapping.jaxb.wisemap.Note mindmapNote = new com.wisemapping.jaxb.wisemap.Note();
|
||||
text = text != null ? text : EMPTY_NOTE;
|
||||
mindmapNote.setText(text);
|
||||
mindmapNote.setValue(text);
|
||||
currentWiseTopic.setNote(mindmapNote);
|
||||
|
||||
}
|
||||
|
@@ -19,37 +19,36 @@
|
||||
package com.wisemapping.model;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Calendar;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class Collaborator implements Serializable {
|
||||
public class Collaborator implements Serializable {
|
||||
private long id;
|
||||
private String email;
|
||||
private Calendar creationDate;
|
||||
private Set<Collaboration> collaborations = new HashSet<Collaboration>();
|
||||
|
||||
public Collaborator() {}
|
||||
public Collaborator() {
|
||||
}
|
||||
|
||||
public Collaborator(Set<Collaboration> collaborations) {
|
||||
public Collaborator(Set<Collaboration> collaborations) {
|
||||
this.collaborations = collaborations;
|
||||
}
|
||||
|
||||
public void setCollaborations(Set<Collaboration> collaborations)
|
||||
{
|
||||
public void setCollaborations(Set<Collaboration> collaborations) {
|
||||
this.collaborations = collaborations;
|
||||
}
|
||||
|
||||
public void addCollaboration(@NotNull Collaboration collaboration)
|
||||
{
|
||||
collaborations.add(collaboration);
|
||||
public void addCollaboration(@NotNull Collaboration collaboration) {
|
||||
collaborations.add(collaboration);
|
||||
}
|
||||
|
||||
public Set<Collaboration> getCollaborations()
|
||||
{
|
||||
public Set<Collaboration> getCollaborations() {
|
||||
return collaborations;
|
||||
}
|
||||
|
||||
@@ -76,4 +75,40 @@ public class Collaborator implements Serializable {
|
||||
public void setCreationDate(Calendar creationDate) {
|
||||
this.creationDate = creationDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Collaborator that = (Collaborator) o;
|
||||
|
||||
if (id != that.getId()) return false;
|
||||
if (email != null ? !email.equals(that.getEmail()) : that.getEmail() != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
long id = this.getId();
|
||||
String email = this.getEmail();
|
||||
|
||||
int result = (int) (id ^ (id >>> 32));
|
||||
result = 31 * result + (email != null ? email.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public boolean identityEquality(@Nullable Collaborator that) {
|
||||
if (this == that) return true;
|
||||
if (that == null) return false;
|
||||
|
||||
if (id != that.getId()) return false;
|
||||
if (email != null ? !email.equals(that.getEmail()) : that.getEmail() != null) return false;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -44,5 +44,7 @@ public enum IconFamily {
|
||||
BULLET,
|
||||
TAG,
|
||||
OBJECT,
|
||||
WEATHER;
|
||||
WEATHER,
|
||||
TASK,
|
||||
NUMBER
|
||||
}
|
||||
|
@@ -18,8 +18,10 @@
|
||||
|
||||
package com.wisemapping.model;
|
||||
|
||||
import com.wisemapping.util.ZipUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class MindMapHistory {
|
||||
@@ -71,7 +73,11 @@ public class MindMapHistory {
|
||||
return xml;
|
||||
}
|
||||
|
||||
public void setXml(byte[] xml) {
|
||||
this.xml = xml;
|
||||
public void setXml(byte[] value) {
|
||||
xml = value;
|
||||
}
|
||||
|
||||
public byte[] getUnzipXml() throws IOException {
|
||||
return ZipUtils.zipToBytes(xml);
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -83,14 +82,14 @@ public class Mindmap {
|
||||
throws IOException {
|
||||
byte[] result = this.xml;
|
||||
if (result != null) {
|
||||
result = ZipUtils.stringToZip(new String(result, UTF_8));
|
||||
result = ZipUtils.bytesToZip(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setZippedXml(byte[] xml)
|
||||
throws IOException {
|
||||
this.xml = ZipUtils.zipToString(xml).getBytes(UTF_8);
|
||||
this.xml = ZipUtils.zipToBytes(xml);
|
||||
}
|
||||
|
||||
public Set<Collaboration> getCollaborations() {
|
||||
@@ -111,7 +110,14 @@ public class Mindmap {
|
||||
|
||||
@Nullable
|
||||
public Collaboration findCollaboration(@NotNull Collaborator collaborator) {
|
||||
return this.findCollaboration(collaborator.getEmail());
|
||||
Collaboration result = null;
|
||||
for (Collaboration collaboration : collaborations) {
|
||||
if (collaboration.getCollaborator().identityEquality(collaborator)) {
|
||||
result = collaboration;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -167,11 +173,21 @@ public class Mindmap {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getXmlAsJsLiteral()
|
||||
throws IOException {
|
||||
String xml = this.getXmlStr();
|
||||
if (xml != null) {
|
||||
xml = StringEscapeUtils.escapeJavaScript(xml);
|
||||
xml = xml.replace("'", "\\'");
|
||||
xml = xml.replace("\n", "\\n");
|
||||
xml = xml.replace("\r", "");
|
||||
|
||||
xml = xml.replace("\\b", "\\\\b");
|
||||
xml = xml.replace("\\t", "\\\\t");
|
||||
xml = xml.replace("\\r", "\\\\r");
|
||||
xml = xml.replace("\\f", "\\\\f");
|
||||
|
||||
xml = xml.trim();
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
@@ -45,12 +45,6 @@ public class MindmapIcons {
|
||||
public static final MindmapIcon ARROW_LEFT = new MindmapIcon(IconFamily.ARROW, "left");
|
||||
public static final MindmapIcon ARROW_RIGHT = new MindmapIcon(IconFamily.ARROW, "right");
|
||||
|
||||
// public static final MindmapIcon TASK_ONE = new MindmapIcon(IconFamily.TASK, "one");
|
||||
// public static final MindmapIcon TASK_TWO = new MindmapIcon(IconFamily.TASK, "two");
|
||||
// public static final MindmapIcon TASK_THREE = new MindmapIcon(IconFamily.TASK, "three");
|
||||
// public static final MindmapIcon TASK_FOUR = new MindmapIcon(IconFamily.TASK, "four");
|
||||
// public static final MindmapIcon TASK_FIVE = new MindmapIcon(IconFamily.TASK, "five");
|
||||
|
||||
// public static final MindmapIcon ARROWC_UNDO = new MindmapIcon(IconFamily.ARROWC, "undo");
|
||||
public static final MindmapIcon ARROWC_ANTICLOCK_WISE = new MindmapIcon(IconFamily.ARROWC, "rotate_anticlockwise");
|
||||
public static final MindmapIcon ARROWC_CLOCK_WISE = new MindmapIcon(IconFamily.ARROWC, "rotate_clockwise");
|
||||
@@ -83,16 +77,23 @@ public class MindmapIcons {
|
||||
public static final MindmapIcon TAG_RED = new MindmapIcon(IconFamily.TAG, "red");
|
||||
public static final MindmapIcon TAG_PINK = new MindmapIcon(IconFamily.TAG, "pink");
|
||||
public static final MindmapIcon TAG_YELLOW = new MindmapIcon(IconFamily.TAG, "yellow");
|
||||
public static final MindmapIcon TAG_PURPLE = new MindmapIcon(IconFamily.TAG, "purple");
|
||||
|
||||
// public static final MindmapIcon NUMBER_ONE = new MindmapIcon(IconFamily.NUMBER, "one");
|
||||
// public static final MindmapIcon NUMBER_TWO = new MindmapIcon(IconFamily.NUMBER, "two");
|
||||
// public static final MindmapIcon NUMBER_THREE = new MindmapIcon(IconFamily.NUMBER, "three");
|
||||
// public static final MindmapIcon NUMBER_FOUR = new MindmapIcon(IconFamily.NUMBER, "four");
|
||||
// public static final MindmapIcon NUMBER_FIVE = new MindmapIcon(IconFamily.NUMBER, "five");
|
||||
// public static final MindmapIcon NUMBER_SIX = new MindmapIcon(IconFamily.NUMBER, "six");
|
||||
// public static final MindmapIcon NUMBER_SEVEN = new MindmapIcon(IconFamily.NUMBER, "seven");
|
||||
// public static final MindmapIcon NUMBER_EIGHT = new MindmapIcon(IconFamily.NUMBER, "eight");
|
||||
// public static final MindmapIcon NUMBER_NINE = new MindmapIcon(IconFamily.NUMBER, "nine");
|
||||
public static final MindmapIcon NUMBER_1 = new MindmapIcon(IconFamily.NUMBER, "1");
|
||||
public static final MindmapIcon NUMBER_2 = new MindmapIcon(IconFamily.NUMBER, "2");
|
||||
public static final MindmapIcon NUMBER_3 = new MindmapIcon(IconFamily.NUMBER, "3");
|
||||
public static final MindmapIcon NUMBER_4 = new MindmapIcon(IconFamily.NUMBER, "4");
|
||||
public static final MindmapIcon NUMBER_5 = new MindmapIcon(IconFamily.NUMBER, "5");
|
||||
public static final MindmapIcon NUMBER_6 = new MindmapIcon(IconFamily.NUMBER, "6");
|
||||
public static final MindmapIcon NUMBER_7 = new MindmapIcon(IconFamily.NUMBER, "7");
|
||||
public static final MindmapIcon NUMBER_8 = new MindmapIcon(IconFamily.NUMBER, "8");
|
||||
public static final MindmapIcon NUMBER_9 = new MindmapIcon(IconFamily.NUMBER, "9");
|
||||
|
||||
public static final MindmapIcon TASK_0 = new MindmapIcon(IconFamily.TASK, "0");
|
||||
public static final MindmapIcon TASK_25 = new MindmapIcon(IconFamily.TASK, "25");
|
||||
public static final MindmapIcon TASK_50 = new MindmapIcon(IconFamily.TASK, "50");
|
||||
public static final MindmapIcon TASK_75 = new MindmapIcon(IconFamily.TASK, "75");
|
||||
public static final MindmapIcon TASK_100 = new MindmapIcon(IconFamily.TASK, "100");
|
||||
|
||||
|
||||
public static final MindmapIcon FUNNY_ANGEL = new MindmapIcon(IconFamily.FUNY, "angel");
|
||||
|
@@ -20,10 +20,10 @@ package com.wisemapping.model;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.servlet.http.HttpSessionBindingEvent;
|
||||
import javax.servlet.http.HttpSessionBindingListener;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class User
|
||||
extends Collaborator
|
||||
@@ -106,28 +106,6 @@ public class User
|
||||
this.allowSendEmail = allowSendEmail;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
final User user = (User) o;
|
||||
|
||||
final String email = getEmail();
|
||||
if (email != null ? !email.equals(user.getEmail()) : user.getEmail() != null) return false;
|
||||
if (firstname != null ? !firstname.equals(user.firstname) : user.firstname != null) return false;
|
||||
return !(lastname != null ? !lastname.equals(user.lastname) : user.lastname != null);
|
||||
}
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
int result;
|
||||
result = (firstname != null ? firstname.hashCode() : 0);
|
||||
result = 29 * result + (lastname != null ? lastname.hashCode() : 0);
|
||||
result = 29 * result + (password != null ? password.hashCode() : 0);
|
||||
result = 29 * result + (getEmail() != null ? getEmail().hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
|
@@ -85,7 +85,7 @@ public class AdminController extends BaseController {
|
||||
}
|
||||
|
||||
// Finally create the user ...
|
||||
userService.createUser(delegated, false);
|
||||
userService.createUser(delegated, false,true);
|
||||
response.setHeader("Location", "/service/admin/users/" + user.getId());
|
||||
}
|
||||
|
||||
|
@@ -108,6 +108,6 @@ public class BaseController {
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
public RestErrors handleClientErrors(@NotNull ClientException ex) {
|
||||
final Locale locale = LocaleContextHolder.getLocale();
|
||||
return new RestErrors(ex.getMessage(messageSource, locale),ex.getSeverity());
|
||||
return new RestErrors(ex.getMessage(messageSource, locale),ex.getSeverity(),ex.getTechInfo());
|
||||
}
|
||||
}
|
||||
|
@@ -120,7 +120,7 @@ public class MindmapController extends BaseController {
|
||||
|
||||
@RequestMapping(value = "maps/{id}/history/{hid}", method = RequestMethod.POST)
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException {
|
||||
public void updateRevertMindmap(@PathVariable int id, @PathVariable String hid) throws WiseMappingException, IOException {
|
||||
final Mindmap mindmap = mindmapService.findMindmapById(id);
|
||||
final User user = Utils.getUser();
|
||||
|
||||
@@ -129,8 +129,8 @@ public class MindmapController extends BaseController {
|
||||
List<MindMapHistory> mindmapHistory = mindmapService.findMindmapHistory(id);
|
||||
if (mindmapHistory.size() > 0) {
|
||||
final MindMapHistory mindMapHistory = mindmapHistory.get(0);
|
||||
mindmap.setXml(mindMapHistory.getXml());
|
||||
saveMindmap(true, mindmap, user);
|
||||
mindmap.setZippedXml(mindMapHistory.getXml());
|
||||
saveMindmapDocument(true, mindmap, user);
|
||||
}
|
||||
} else {
|
||||
mindmapService.revertChange(mindmap, Integer.parseInt(hid));
|
||||
@@ -165,14 +165,33 @@ public class MindmapController extends BaseController {
|
||||
mindmap.setXmlStr(xml);
|
||||
|
||||
// Update map ...
|
||||
saveMindmap(minor, mindmap, user);
|
||||
saveMindmapDocument(minor, mindmap, user);
|
||||
|
||||
// Update edition timeout ...
|
||||
final LockManager lockManager = mindmapService.getLockManager();
|
||||
final LockInfo lockInfo = lockManager.updateExpirationTimeout(mindmap, user, session);
|
||||
final LockInfo lockInfo = lockManager.updateExpirationTimeout(mindmap, user);
|
||||
return lockInfo.getTimestamp();
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = { "/maps/{id}/document/xml","/maps/{id}/document/xml-pub"},consumes = {"text/plain"}, produces = {"application/xml"})
|
||||
@ResponseBody
|
||||
public byte[] retrieveDocument(@PathVariable int id, @NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
||||
// I should not return byte, but there is some encoding issue here. Further research needed.
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
final Mindmap mindmap = mindmapService.findMindmapById(id);
|
||||
return mindmap.getXmlStr().getBytes("UTF-8");
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET, value = { "/maps/{id}/{hid}/document/xml"},consumes = {"text/plain"}, produces = {"application/xml"})
|
||||
@ResponseBody
|
||||
public byte[] retrieveDocument(@PathVariable int id, @PathVariable int hid,@NotNull HttpServletResponse response) throws WiseMappingException, IOException {
|
||||
// I should not return byte, but there is some encoding issue here. Further research needed.
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
final MindMapHistory mindmapHistory = mindmapService.findMindmapHistory(id, hid);
|
||||
return mindmapHistory.getUnzipXml();
|
||||
}
|
||||
|
||||
|
||||
private void verifyLock(@NotNull Mindmap mindmap, @NotNull User user, long session, long timestamp) throws WiseMappingException {
|
||||
|
||||
// The lock was lost, reclaim as the ownership of it.
|
||||
@@ -183,20 +202,20 @@ public class MindmapController extends BaseController {
|
||||
}
|
||||
|
||||
final LockInfo lockInfo = lockManager.getLockInfo(mindmap);
|
||||
if (lockInfo.getUser().equals(user)) {
|
||||
if (lockInfo.getUser().identityEquality(user)) {
|
||||
final boolean outdated = mindmap.getLastModificationTime().getTimeInMillis() > timestamp;
|
||||
if (lockInfo.getSession() == session) {
|
||||
// Timestamp might not be returned to the client. This try to cover this case, ignoring the client timestamp check.
|
||||
final User lastEditor = mindmap.getLastEditor();
|
||||
if (outdated && (lockInfo.getPreviousTimestamp() != timestamp || lastEditor == null || !lastEditor.equals(user))) {
|
||||
throw new SessionExpiredException(lastEditor);
|
||||
boolean editedBySameUser = lastEditor == null || user.identityEquality(lastEditor);
|
||||
if (outdated && !editedBySameUser) {
|
||||
throw new SessionExpiredException("Map has been updated by " + (lastEditor.getEmail()) + ",Timestamp:" + timestamp + "," + mindmap.getLastModificationTime().getTimeInMillis() + ", User:" + lastEditor.getId() + ":" + user.getId() + ",Mail:'" + lastEditor.getEmail() + "':'" + user.getEmail(), lastEditor);
|
||||
}
|
||||
} else if (outdated) {
|
||||
throw new MultipleSessionsOpenException("The map has been updated and not by you. Session lost.");
|
||||
throw new MultipleSessionsOpenException("Sessions:" + session + ":" + lockInfo.getSession() + ",Timestamp: " + timestamp + ": " + lockInfo.getTimestamp() + ",User:");
|
||||
}
|
||||
} else {
|
||||
throw new SessionExpiredException(lockInfo.getUser());
|
||||
|
||||
throw new SessionExpiredException("Different Users.", lockInfo.getUser());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +262,7 @@ public class MindmapController extends BaseController {
|
||||
}
|
||||
|
||||
// Update map ...
|
||||
saveMindmap(minor, mindmap, user);
|
||||
saveMindmapDocument(minor, mindmap, user);
|
||||
}
|
||||
|
||||
|
||||
@@ -263,7 +282,7 @@ public class MindmapController extends BaseController {
|
||||
// Update map ...
|
||||
final Mindmap mindmap = mindmapService.findMindmapById(id);
|
||||
mindmap.setTitle(title);
|
||||
saveMindmap(true, mindMap, user);
|
||||
mindmapService.updateMindmap(mindMap, !true);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/collabs", consumes = {"application/json", "application/xml"}, produces = {"application/json", "text/html", "application/xml"})
|
||||
@@ -334,7 +353,7 @@ public class MindmapController extends BaseController {
|
||||
// Update map ...
|
||||
final Mindmap mindmap = mindmapService.findMindmapById(id);
|
||||
mindmap.setDescription(description);
|
||||
saveMindmap(true, mindMap, user);
|
||||
mindmapService.updateMindmap(mindMap, !true);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/maps/{id}/publish", consumes = {"text/plain"}, produces = {"application/json", "text/html", "application/xml"})
|
||||
@@ -350,13 +369,13 @@ public class MindmapController extends BaseController {
|
||||
|
||||
// Update map status ...
|
||||
mindMap.setPublic(Boolean.parseBoolean(value));
|
||||
saveMindmap(true, mindMap, user);
|
||||
mindmapService.updateMindmap(mindMap, !true);
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.DELETE, value = "/maps/{id}")
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void updateMap(@PathVariable int id) throws IOException, WiseMappingException {
|
||||
public void deleteMapById(@PathVariable int id) throws IOException, WiseMappingException {
|
||||
final User user = Utils.getUser();
|
||||
final Mindmap mindmap = mindmapService.findMindmapById(id);
|
||||
mindmapService.removeMindmap(mindmap, user);
|
||||
@@ -489,7 +508,7 @@ public class MindmapController extends BaseController {
|
||||
response.setHeader("ResourceId", Integer.toString(clonedMap.getId()));
|
||||
}
|
||||
|
||||
private void saveMindmap(boolean minor, @NotNull final Mindmap mindMap, @NotNull final User user) throws WiseMappingException {
|
||||
private void saveMindmapDocument(boolean minor, @NotNull final Mindmap mindMap, @NotNull final User user) throws WiseMappingException {
|
||||
final Calendar now = Calendar.getInstance();
|
||||
mindMap.setLastModificationTime(now);
|
||||
mindMap.setLastEditor(user);
|
||||
|
@@ -36,7 +36,7 @@ public enum MindmapFilter {
|
||||
MY_MAPS("my_maps") {
|
||||
@Override
|
||||
boolean accept(@NotNull Mindmap mindmap, @NotNull User user) {
|
||||
return mindmap.getCreator().equals(user);
|
||||
return mindmap.getCreator().identityEquality(user);
|
||||
}
|
||||
},
|
||||
STARRED("starred") {
|
||||
|
@@ -23,6 +23,7 @@ import org.codehaus.jackson.annotate.JsonAutoDetect;
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.validation.Errors;
|
||||
@@ -56,6 +57,10 @@ public class RestErrors {
|
||||
@JsonIgnore
|
||||
Severity gSeverity;
|
||||
|
||||
@Nullable
|
||||
@JsonIgnore
|
||||
private String _debugInfo;
|
||||
|
||||
public RestErrors() {
|
||||
|
||||
}
|
||||
@@ -64,17 +69,23 @@ public class RestErrors {
|
||||
|
||||
this.errors = errors;
|
||||
this.messageSource = messageSource;
|
||||
this.gErrors = this.processGlobalErrors(errors, messageSource);
|
||||
this.gErrors = this.processGlobalErrors(errors);
|
||||
this.gSeverity = Severity.WARNING;
|
||||
}
|
||||
|
||||
public RestErrors(@NotNull String errorMsg, @NotNull Severity severity) {
|
||||
gErrors = new ArrayList<String>();
|
||||
gErrors.add(errorMsg);
|
||||
|
||||
this(errorMsg, severity, null);
|
||||
}
|
||||
|
||||
public RestErrors(@NotNull String errorMsg, @NotNull Severity severity, @Nullable String debugInfo) {
|
||||
this._debugInfo = debugInfo;
|
||||
this.gErrors = new ArrayList<String>();
|
||||
this.gErrors.add(errorMsg);
|
||||
this.gSeverity = severity;
|
||||
}
|
||||
|
||||
private List<String> processGlobalErrors(@NotNull Errors errors, @NotNull MessageSource messageSource) {
|
||||
private List<String> processGlobalErrors(@NotNull Errors errors) {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
final List<ObjectError> globalErrors = errors.getGlobalErrors();
|
||||
for (ObjectError globalError : globalErrors) {
|
||||
@@ -83,10 +94,6 @@ public class RestErrors {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<String> getGlobalErrors() {
|
||||
return gErrors;
|
||||
}
|
||||
|
||||
public void setGlobalErrors(List<String> list) {
|
||||
// Implemented only for XML serialization contract ...
|
||||
}
|
||||
@@ -111,7 +118,23 @@ public class RestErrors {
|
||||
// Implemented only for XML serialization contract ...
|
||||
}
|
||||
|
||||
public void setDebugInfo(@Nullable String debugInfo) {
|
||||
// Implemented only for XML serialization contract ...
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String getGlobalSeverity() {
|
||||
return this.gSeverity.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getDebugInfo() {
|
||||
return _debugInfo;
|
||||
}
|
||||
|
||||
public List<String> getGlobalErrors() {
|
||||
return gErrors;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -68,7 +68,7 @@ public class RestLockInfo {
|
||||
}
|
||||
|
||||
public boolean isLockedByMe() {
|
||||
return isLocked() && lockInfo != null && lockInfo.getUser().equals(user);
|
||||
return isLocked() && lockInfo != null && lockInfo.getUser().identityEquality(user);
|
||||
}
|
||||
|
||||
public void setLockedByMe(boolean lockedForMe) {
|
||||
|
@@ -23,7 +23,6 @@ import com.wisemapping.model.User;
|
||||
import org.codehaus.jackson.annotate.JsonAutoDetect;
|
||||
import org.codehaus.jackson.annotate.JsonIgnore;
|
||||
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
|
||||
import org.codehaus.jackson.map.annotate.JsonSerialize;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
@@ -125,7 +124,7 @@ public class RestUser {
|
||||
}
|
||||
|
||||
RestUser restUser = (RestUser) o;
|
||||
return this.getDelegated().equals(restUser.getDelegated());
|
||||
return this.getDelegated().identityEquality(restUser.getDelegated());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -59,14 +59,8 @@ public class TransformView extends AbstractView {
|
||||
// Build format properties ...
|
||||
final ExportProperties properties = ExportProperties.create(exportFormat);
|
||||
if (properties instanceof ExportProperties.ImageProperties) {
|
||||
final String sizeStr = request.getParameter(IMG_SIZE_PARAMETER);
|
||||
final ExportProperties.ImageProperties imageProperties = (ExportProperties.ImageProperties) properties;
|
||||
if (sizeStr != null) {
|
||||
final ExportProperties.ImageProperties.Size size = ExportProperties.ImageProperties.Size.valueOf(sizeStr);
|
||||
imageProperties.setSize(size);
|
||||
} else {
|
||||
imageProperties.setSize(ExportProperties.ImageProperties.Size.MEDIUM);
|
||||
}
|
||||
imageProperties.setSize(ExportProperties.ImageProperties.Size.LARGE);
|
||||
}
|
||||
|
||||
// Set format content type...
|
||||
@@ -103,6 +97,4 @@ public class TransformView extends AbstractView {
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
private static final String IMG_SIZE_PARAMETER = "imgSize";
|
||||
}
|
||||
|
@@ -27,10 +27,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
public class UserDetails implements org.springframework.security.core.userdetails.UserDetails {
|
||||
private com.wisemapping.model.User user;
|
||||
private com.wisemapping.model.User user;
|
||||
private boolean isAdmin;
|
||||
|
||||
public UserDetails(@NotNull final com.wisemapping.model.User user, boolean isAdmin) {
|
||||
public UserDetails(@NotNull final com.wisemapping.model.User user, boolean isAdmin) {
|
||||
this.user = user;
|
||||
this.isAdmin = isAdmin;
|
||||
}
|
||||
|
@@ -18,13 +18,12 @@
|
||||
|
||||
package com.wisemapping.security;
|
||||
|
||||
import com.wisemapping.dao.UserManager;
|
||||
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.service.UserService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
@@ -37,7 +36,7 @@ public class UserDetailsService
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(@NotNull String email) throws UsernameNotFoundException, DataAccessException {
|
||||
final User user = userService.getUserBy(email);
|
||||
|
||||
|
||||
if (user != null) {
|
||||
return new UserDetails(user, isAdmin(email));
|
||||
} else {
|
||||
|
@@ -41,7 +41,7 @@ public abstract class BaseSecurityAdvice {
|
||||
isAllowed = isAllowed(user, ((Integer) argument));
|
||||
} else if (argument instanceof Collaborator) {
|
||||
// Read operation find on the user are allowed ...
|
||||
isAllowed = user.equals(argument);
|
||||
isAllowed = user.identityEquality((Collaborator) argument);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Argument " + argument);
|
||||
}
|
||||
|
@@ -0,0 +1,79 @@
|
||||
package com.wisemapping.security.ldap;
|
||||
|
||||
|
||||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.security.UserDetails;
|
||||
import com.wisemapping.service.UserService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.ldap.core.DirContextAdapter;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.ldap.userdetails.UserDetailsContextMapper;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
|
||||
public class LdapUserDetailsContextMapper implements UserDetailsContextMapper {
|
||||
|
||||
private UserService userService;
|
||||
private String adminUser;
|
||||
|
||||
|
||||
public UserService getUserService() {
|
||||
return userService;
|
||||
}
|
||||
|
||||
public void setUserService(UserService userService) {
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
|
||||
private boolean isAdmin(@Nullable String email) {
|
||||
return email != null && adminUser != null && email.trim().endsWith(adminUser);
|
||||
}
|
||||
|
||||
public String getAdminUser() {
|
||||
return adminUser;
|
||||
}
|
||||
|
||||
public void setAdminUser(String adminUser) {
|
||||
this.adminUser = adminUser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDetails mapUserFromContext(@NotNull DirContextOperations userData,
|
||||
String email, Collection<? extends GrantedAuthority> arg2) {
|
||||
User user = userService.getUserBy(email);
|
||||
if (user == null) {
|
||||
// If the user was not found in the database, create a new one ...
|
||||
user = new User();
|
||||
user.setEmail(email);
|
||||
|
||||
final String firstName = userData.getStringAttribute("givenName");
|
||||
user.setFirstname(firstName);
|
||||
|
||||
final String lastName = userData.getStringAttribute("sn");
|
||||
user.setLastname(lastName);
|
||||
|
||||
user.setPassword(email);
|
||||
final Calendar now = Calendar.getInstance();
|
||||
user.setActivationDate(now);
|
||||
|
||||
try {
|
||||
userService.createUser(user, false,false);
|
||||
} catch (WiseMappingException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
return new UserDetails(user, isAdmin(email));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapUserToContext(org.springframework.security.core.userdetails.UserDetails userDetails, DirContextAdapter dirContextAdapter) {
|
||||
// To be implemented ...
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -36,6 +36,7 @@ public class LockInfo {
|
||||
this.user = user;
|
||||
this.updateTimeout();
|
||||
this.updateTimestamp(mindmap);
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
|
@@ -30,13 +30,17 @@ public interface LockManager {
|
||||
|
||||
LockInfo getLockInfo(@NotNull Mindmap mindmap);
|
||||
|
||||
LockInfo updateExpirationTimeout(@NotNull Mindmap mindmap, @NotNull User user,long session);
|
||||
LockInfo updateExpirationTimeout(@NotNull Mindmap mindmap, @NotNull User user);
|
||||
|
||||
void unlock(@NotNull Mindmap mindmap, @NotNull User user) throws LockException, AccessDeniedSecurityException;
|
||||
|
||||
boolean isLockedBy(@NotNull Mindmap mindmap, @NotNull User collaborator);
|
||||
|
||||
@NotNull
|
||||
LockInfo lock(@NotNull Mindmap mindmap, @NotNull User user, long session) throws WiseMappingException;
|
||||
|
||||
@NotNull
|
||||
LockInfo lock(@NotNull Mindmap mindmap, @NotNull User user) throws WiseMappingException;
|
||||
|
||||
long generateSession();
|
||||
}
|
||||
|
@@ -63,20 +63,19 @@ class LockManagerImpl implements LockManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LockInfo updateExpirationTimeout(@NotNull Mindmap mindmap, @NotNull User user, long session) {
|
||||
public LockInfo updateExpirationTimeout(@NotNull Mindmap mindmap, @NotNull User user) {
|
||||
if (!this.isLocked(mindmap)) {
|
||||
throw new IllegalStateException("Lock lost for map. No update possible.");
|
||||
}
|
||||
|
||||
final LockInfo result = this.getLockInfo(mindmap);
|
||||
if (!result.getUser().equals(user)) {
|
||||
if (!result.getUser().identityEquality(user)) {
|
||||
throw new IllegalStateException("Could not update map lock timeout if you are not the locking user. User:" + result.getUser() + ", " + user);
|
||||
}
|
||||
|
||||
result.updateTimeout();
|
||||
result.setSession(session);
|
||||
result.updateTimestamp(mindmap);
|
||||
// logger.debug("Timeout updated for:" + mindmap.getId());
|
||||
logger.debug("Timeout updated for:" + mindmap.getId());
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -102,12 +101,24 @@ class LockManagerImpl implements LockManager {
|
||||
public boolean isLockedBy(@NotNull Mindmap mindmap, @NotNull User collaborator) {
|
||||
boolean result = false;
|
||||
final LockInfo lockInfo = this.getLockInfo(mindmap);
|
||||
if (lockInfo != null && lockInfo.getUser().equals(collaborator)) {
|
||||
if (lockInfo != null && lockInfo.getUser().identityEquality(collaborator)) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public LockInfo lock(@NotNull Mindmap mindmap, @NotNull User user) throws WiseMappingException {
|
||||
return this.lock(mindmap, user, System.nanoTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long generateSession() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public LockInfo lock(@NotNull Mindmap mindmap, @NotNull User user, long session) throws WiseMappingException {
|
||||
@@ -123,7 +134,8 @@ class LockManagerImpl implements LockManager {
|
||||
if (result != null) {
|
||||
// Update timeout only...
|
||||
logger.debug("Update timestamp:" + mindmap.getId());
|
||||
updateExpirationTimeout(mindmap, user, session);
|
||||
updateExpirationTimeout(mindmap, user);
|
||||
// result.setSession(session);
|
||||
} else {
|
||||
logger.debug("Lock map id:" + mindmap.getId());
|
||||
result = new LockInfo(user, mindmap, session);
|
||||
@@ -132,11 +144,6 @@ class LockManagerImpl implements LockManager {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long generateSession() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
|
||||
public LockManagerImpl() {
|
||||
lockInfoByMapId = new ConcurrentHashMap<Integer, LockInfo>();
|
||||
expirationTimer.schedule(new TimerTask() {
|
||||
|
@@ -23,6 +23,7 @@ import com.wisemapping.exceptions.WiseMappingException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public interface MindmapService {
|
||||
@@ -57,7 +58,7 @@ public interface MindmapService {
|
||||
|
||||
boolean hasPermissions(@Nullable User user, int mapId, CollaborationRole allowedRole);
|
||||
|
||||
void revertChange(@NotNull Mindmap map, int historyId) throws WiseMappingException;
|
||||
void revertChange(@NotNull Mindmap map, int historyId) throws WiseMappingException, IOException;
|
||||
|
||||
MindMapHistory findMindmapHistory(int id, int hid) throws WiseMappingException;
|
||||
|
||||
|
@@ -28,7 +28,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class MindmapServiceImpl
|
||||
@@ -114,18 +117,19 @@ public class MindmapServiceImpl
|
||||
final Mindmap mindMap = collaboration.getMindMap();
|
||||
final Set<Collaboration> collaborations = mindMap.getCollaborations();
|
||||
|
||||
if (mindMap.getCreator().getEmail().equals(collaboration.getCollaborator().getEmail())) {
|
||||
final User creator = mindMap.getCreator();
|
||||
if (creator.identityEquality(collaboration.getCollaborator())) {
|
||||
throw new CollaborationException("User is the creator and must have ownership permissions.Creator Email:" + mindMap.getCreator().getEmail() + ",Collaborator:" + collaboration.getCollaborator().getEmail());
|
||||
}
|
||||
|
||||
// When you delete an object from hibernate you have to delete it from *all* collections it exists in...
|
||||
mindmapManager.removeCollaboration(collaboration);
|
||||
collaborations.remove(collaboration);
|
||||
mindmapManager.removeCollaboration(collaboration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMindmap(@NotNull Mindmap mindmap, @NotNull User user) throws WiseMappingException {
|
||||
if (mindmap.getCreator().equals(user)) {
|
||||
if (mindmap.getCreator().identityEquality(user)) {
|
||||
mindmapManager.removeMindmap(mindmap);
|
||||
} else {
|
||||
final Collaboration collaboration = mindmap.findCollaboration(user);
|
||||
@@ -239,9 +243,9 @@ public class MindmapServiceImpl
|
||||
|
||||
@Override
|
||||
public void revertChange(@NotNull Mindmap mindmap, int historyId)
|
||||
throws WiseMappingException {
|
||||
throws WiseMappingException, IOException {
|
||||
final MindMapHistory history = mindmapManager.getHistory(historyId);
|
||||
mindmap.setXml(history.getXml());
|
||||
mindmap.setZippedXml(history.getXml());
|
||||
updateMindmap(mindmap, true);
|
||||
}
|
||||
|
||||
@@ -264,7 +268,7 @@ public class MindmapServiceImpl
|
||||
|
||||
@Override
|
||||
public void updateCollaboration(@NotNull Collaborator collaborator, @NotNull Collaboration collaboration) throws WiseMappingException {
|
||||
if (collaborator.equals(collaboration.getCollaborator())) {
|
||||
if (!collaborator.identityEquality(collaboration.getCollaborator())) {
|
||||
throw new WiseMappingException("No enough permissions for this operation.");
|
||||
}
|
||||
mindmapManager.updateCollaboration(collaboration);
|
||||
@@ -276,7 +280,7 @@ public class MindmapServiceImpl
|
||||
return this.lockManager;
|
||||
}
|
||||
|
||||
private Collaboration getCollaborationBy(String email, Set<Collaboration> collaborations) {
|
||||
private Collaboration getCollaborationBy(@NotNull final String email, @NotNull final Set<Collaboration> collaborations) {
|
||||
Collaboration collaboration = null;
|
||||
|
||||
for (Collaboration user : collaborations) {
|
||||
|
@@ -26,7 +26,7 @@ public interface UserService {
|
||||
|
||||
public void activateAccount(long code) throws InvalidActivationCodeException;
|
||||
|
||||
public User createUser(@NotNull User user, boolean emailConfirmEnabled) throws WiseMappingException;
|
||||
public User createUser(@NotNull User user, boolean emailConfirmEnabled,boolean welcomeEmail) throws WiseMappingException;
|
||||
|
||||
public void changePassword(@NotNull User user);
|
||||
|
||||
@@ -41,4 +41,6 @@ public interface UserService {
|
||||
public void deleteUser(@NotNull User user);
|
||||
|
||||
public void auditLogin(@NotNull User user);
|
||||
|
||||
public User getCasUserBy(String uid);
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ public class UserServiceImpl
|
||||
userManager.auditLogin(accessAuditory);
|
||||
}
|
||||
|
||||
public User createUser(@NotNull User user, boolean emailConfirmEnabled) throws WiseMappingException {
|
||||
public User createUser(@NotNull User user, boolean emailConfirmEnabled, boolean welcomeEmail) throws WiseMappingException {
|
||||
final UUID uuid = UUID.randomUUID();
|
||||
user.setCreationDate(Calendar.getInstance());
|
||||
user.setActivationCode(uuid.getLeastSignificantBits());
|
||||
@@ -120,6 +120,7 @@ public class UserServiceImpl
|
||||
}
|
||||
|
||||
Collaborator col = userManager.getCollaboratorBy(user.getEmail());
|
||||
|
||||
if (col != null) {
|
||||
userManager.createUser(user, col);
|
||||
} else {
|
||||
@@ -134,7 +135,7 @@ public class UserServiceImpl
|
||||
// Send registration email.
|
||||
if (emailConfirmEnabled) {
|
||||
notificationService.sendRegistrationEmail(user);
|
||||
} else {
|
||||
} else if (welcomeEmail) {
|
||||
// Send a welcome email ..
|
||||
notificationService.newAccountCreated(user);
|
||||
}
|
||||
@@ -205,4 +206,10 @@ public class UserServiceImpl
|
||||
public void setVelocityEngine(VelocityEngine velocityEngine) {
|
||||
this.velocityEngine = velocityEngine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getCasUserBy(String uid) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -18,67 +18,46 @@
|
||||
|
||||
package com.wisemapping.util;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
public class ZipUtils {
|
||||
|
||||
public static String zipToString(byte[] zip) throws IOException {
|
||||
public static byte[] zipToBytes(byte[] zip) throws IOException {
|
||||
|
||||
String result = null;
|
||||
if (zip != null)
|
||||
{
|
||||
byte[] result = null;
|
||||
if (zip != null) {
|
||||
final ByteArrayInputStream in = new ByteArrayInputStream(zip);
|
||||
final ZipInputStream zipIn = new ZipInputStream(in);
|
||||
zipIn.getNextEntry();
|
||||
|
||||
byte[] buffer = new byte[512];
|
||||
|
||||
int len;
|
||||
StringBuilder sb_result = new StringBuilder();
|
||||
|
||||
while ((len = zipIn.read(buffer)) > 0) {
|
||||
|
||||
|
||||
|
||||
sb_result.append(new String(buffer, 0, len, Charset.forName("UTF-8")));
|
||||
}
|
||||
result = IOUtils.toByteArray(zipIn);
|
||||
|
||||
zipIn.closeEntry();
|
||||
zipIn.close();
|
||||
result = sb_result.toString();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] stringToZip(String content) throws IOException {
|
||||
public static byte[] bytesToZip(@NotNull final byte[] content) throws IOException {
|
||||
ZipOutputStream zip = null;
|
||||
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
|
||||
|
||||
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes("UTF-8"));
|
||||
final ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
|
||||
try {
|
||||
zip = new ZipOutputStream(byteArray);
|
||||
|
||||
ZipEntry zEntry = new ZipEntry("content");
|
||||
zip.putNextEntry(zEntry);
|
||||
int bytesRead;
|
||||
byte[] buffer = new byte[8192];
|
||||
while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
|
||||
zip.write(buffer, 0, bytesRead);
|
||||
}
|
||||
IOUtils.write(content, zip);
|
||||
zip.closeEntry();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (zip != null)
|
||||
{
|
||||
} finally {
|
||||
if (zip != null) {
|
||||
zip.flush();
|
||||
zip.close();
|
||||
}
|
||||
|
@@ -26,8 +26,9 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MindMapBean {
|
||||
private Mindmap mindmap;
|
||||
@@ -124,10 +125,7 @@ public class MindMapBean {
|
||||
}
|
||||
|
||||
public String getXmlAsJsLiteral() throws IOException {
|
||||
final String xmlAsJsLiteral = this.mindmap.getXmlAsJsLiteral();
|
||||
|
||||
// Firefox is failing for this. Need to be reviewed ...
|
||||
return xmlAsJsLiteral.replace("\\u0000","");
|
||||
return this.mindmap.getXmlAsJsLiteral();
|
||||
}
|
||||
|
||||
public String getProperties() throws WiseMappingException {
|
||||
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright [2012] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.wisemapping.webmvc;
|
||||
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.env.PropertiesPropertySource;
|
||||
import org.springframework.core.env.PropertySourcesPropertyResolver;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.UrlResource;
|
||||
import org.springframework.core.io.support.ResourcePropertySource;
|
||||
import org.springframework.web.context.ConfigurableWebApplicationContext;
|
||||
import org.springframework.web.context.support.ServletContextResource;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
public class ApplicationContextInitializer implements org.springframework.context.ApplicationContextInitializer<ConfigurableWebApplicationContext> {
|
||||
|
||||
public void initialize(@NotNull ConfigurableWebApplicationContext ctx) {
|
||||
try {
|
||||
final Resource resource = new ServletContextResource(ctx.getServletContext(), "/WEB-INF/app.properties");
|
||||
final ResourcePropertySource resourcePropertySource = new ResourcePropertySource(resource);
|
||||
ctx.getEnvironment().getPropertySources().addFirst(resourcePropertySource);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -21,11 +21,10 @@ package com.wisemapping.webmvc;
|
||||
|
||||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.model.CollaborationRole;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.MindMapHistory;
|
||||
import com.wisemapping.model.Mindmap;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.security.Utils;
|
||||
import com.wisemapping.service.LockInfo;
|
||||
import com.wisemapping.service.LockManager;
|
||||
import com.wisemapping.service.MindmapService;
|
||||
import com.wisemapping.view.MindMapBean;
|
||||
@@ -36,9 +35,13 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -46,24 +49,21 @@ import java.util.Locale;
|
||||
public class MindmapController {
|
||||
|
||||
|
||||
public static final String LOCK_SESSION_ATTRIBUTE = "lockSession";
|
||||
@Qualifier("mindmapService")
|
||||
@Autowired
|
||||
private MindmapService mindmapService;
|
||||
|
||||
@Value("${site.baseurl}")
|
||||
String siteBaseUrl;
|
||||
|
||||
|
||||
@RequestMapping(value = "maps/import")
|
||||
public String showImportPage() {
|
||||
return "mindmapImport";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "maps/{id}/details")
|
||||
public String showDetails(@PathVariable int id, @NotNull Model model) {
|
||||
public String showDetails(@PathVariable int id, @NotNull Model model,@NotNull HttpServletRequest request) {
|
||||
final MindMapBean mindmap = findMindmapBean(id);
|
||||
model.addAttribute("mindmap", mindmap);
|
||||
model.addAttribute("baseUrl", siteBaseUrl);
|
||||
model.addAttribute("baseUrl", request.getAttribute("site.baseurl"));
|
||||
return "mindmapDetail";
|
||||
}
|
||||
|
||||
@@ -104,16 +104,16 @@ public class MindmapController {
|
||||
}
|
||||
|
||||
@RequestMapping(value = "maps/{id}/publish")
|
||||
public String showPublishPage(@PathVariable int id, @NotNull Model model) {
|
||||
public String showPublishPage(@PathVariable int id, @NotNull Model model,@NotNull HttpServletRequest request) {
|
||||
final Mindmap mindmap = findMindmap(id);
|
||||
model.addAttribute("mindmap", mindmap);
|
||||
model.addAttribute("baseUrl", siteBaseUrl);
|
||||
model.addAttribute("baseUrl", request.getAttribute("site.baseurl"));
|
||||
return "mindmapPublish";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "maps/{id}/publishf")
|
||||
public String showPublishPageFull(@PathVariable int id, @NotNull Model model) {
|
||||
showPublishPage(id, model);
|
||||
public String showPublishPageFull(@PathVariable int id, @NotNull Model model,@NotNull HttpServletRequest request) {
|
||||
showPublishPage(id, model,request);
|
||||
return "mindmapPublishFull";
|
||||
}
|
||||
|
||||
@@ -158,12 +158,10 @@ public class MindmapController {
|
||||
final LockManager lockManager = this.mindmapService.getLockManager();
|
||||
if (lockManager.isLocked(mindmap) && !lockManager.isLockedBy(mindmap, collaborator)) {
|
||||
readOnlyMode = true;
|
||||
model.addAttribute("mindmapLocked",true);
|
||||
model.addAttribute("mindmapLocked", true);
|
||||
} else {
|
||||
final long session = lockManager.generateSession();
|
||||
final LockInfo lock = lockManager.lock(mindmap, collaborator, session);
|
||||
model.addAttribute("lockTimestamp", lock.getTimestamp());
|
||||
model.addAttribute("lockSession", session);
|
||||
model.addAttribute("lockTimestamp", mindmap.getLastModificationTime().getTimeInMillis());
|
||||
model.addAttribute(LOCK_SESSION_ATTRIBUTE, lockManager.generateSession());
|
||||
}
|
||||
model.addAttribute("lockInfo", lockManager.getLockInfo(mindmap));
|
||||
}
|
||||
@@ -196,12 +194,7 @@ public class MindmapController {
|
||||
|
||||
final String result = showMindmapEditorPage(id, model);
|
||||
model.addAttribute("readOnlyMode", true);
|
||||
|
||||
// Change map XML ....
|
||||
final MindMapBean mindmapBean = (MindMapBean) model.asMap().get("mindmap");
|
||||
final MindMapHistory mindmapHistory = mindmapService.findMindmapHistory(id, hid);
|
||||
mindmapBean.getDelegated().setXml(mindmapHistory.getXml());
|
||||
|
||||
model.addAttribute("hid",String.valueOf(hid));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@@ -110,7 +110,7 @@ public class UsersController {
|
||||
user.setPassword(userBean.getPassword());
|
||||
|
||||
boolean confirmRegistrationByEmail = false;
|
||||
userService.createUser(user, confirmRegistrationByEmail);
|
||||
userService.createUser(user, confirmRegistrationByEmail,true);
|
||||
|
||||
// Forward to the success view ...
|
||||
result = new ModelAndView("userRegistrationSuccess");
|
||||
|
@@ -11,7 +11,7 @@
|
||||
</id>
|
||||
<property name="loginDate" column="login_Date"/>
|
||||
<many-to-one name="user"
|
||||
column="USER_ID"
|
||||
column="user_id"
|
||||
not-null="true"
|
||||
class="com.wisemapping.model.User"
|
||||
/>
|
||||
|
@@ -10,17 +10,17 @@
|
||||
<generator class="increment"/>
|
||||
</id>
|
||||
|
||||
<property name="roleId" column="ROLE_ID" unique="true" not-null="true"/>
|
||||
<property name="roleId" column="role_id" unique="true" not-null="true"/>
|
||||
|
||||
<!-- Read-only association property -->
|
||||
<many-to-one name="mindMap"
|
||||
column="MINDMAP_ID"
|
||||
column="mindmap_id"
|
||||
not-null="true"
|
||||
class="com.wisemapping.model.Mindmap"
|
||||
/>
|
||||
|
||||
<many-to-one name="collaborator"
|
||||
column="COLABORATOR_ID"
|
||||
column="colaborator_id"
|
||||
not-null="true"
|
||||
class="com.wisemapping.model.Collaborator"
|
||||
/>
|
||||
|
@@ -15,12 +15,12 @@
|
||||
<set name="collaborations"
|
||||
cascade="all, delete-orphan"
|
||||
inverse="true">
|
||||
<key column="COLABORATOR_ID" not-null="true"/>
|
||||
<key column="colaborator_id" not-null="true"/>
|
||||
<one-to-many class="com.wisemapping.model.Collaboration"/>
|
||||
</set>
|
||||
|
||||
<joined-subclass name="com.wisemapping.model.User" table="USER">
|
||||
<key column="COLABORATOR_ID"/>
|
||||
<key column="colaborator_id"/>
|
||||
<property name="firstname"/>
|
||||
<property name="lastname"/>
|
||||
<property name="password"/>
|
||||
|
@@ -11,7 +11,7 @@
|
||||
</id>
|
||||
|
||||
<property name="mindmapId" column="mindmap_id"/>
|
||||
<property name="xml" column="XML"/>
|
||||
<property name="xml" column="xml"/>
|
||||
<property name="creationTime" column="creation_date"/>
|
||||
<many-to-one name="editor" column="editor_id" unique="false" not-null="false" lazy="proxy"/>
|
||||
</class>
|
||||
|
@@ -22,7 +22,7 @@
|
||||
<set name="collaborations"
|
||||
cascade="all,delete-orphan,save-update"
|
||||
inverse="true">
|
||||
<key column="MINDMAP_ID" not-null="true"/>
|
||||
<key column="mindmap_id" not-null="true"/>
|
||||
<one-to-many class="com.wisemapping.model.Collaboration"/>
|
||||
</set>
|
||||
</class>
|
||||
|
261
wise-webapp/src/main/resources/messages_de.properties
Normal file
@@ -0,0 +1,261 @@
|
||||
# Default German Support.
|
||||
|
||||
NAME=Name
|
||||
DESCRIPTION=Beschreibung
|
||||
ADD=Hinzufügen
|
||||
VIEWERS=Betrachter
|
||||
USER_REGISTRATION=Benutzerregistrierung
|
||||
SEND_ME_A_NEW_PASSWORD=Schicke mir ein neues Passwort
|
||||
CANCEL=Abbrechen
|
||||
FIRSTNAME=Vorname
|
||||
LASTNAME=Nachname
|
||||
EMAIL=Email
|
||||
HELP=Hilfe
|
||||
LOGOUT=Abmelden
|
||||
PASSWORD=Passwort
|
||||
NEW_PASSWORD=Neues Passwort
|
||||
CONFIRM_NEW_PASSWORD=Bestätige neues Passwort
|
||||
MY_WISEMAPS=Meine Wisemaps
|
||||
RETYPE_PASSWORD=Schreibe Passwort nochmal
|
||||
REGISTER=Registrierung
|
||||
REMEMBER_ME=Bleibe angemeldet
|
||||
SIGN_IN=Anmelden
|
||||
SIGN_UP=Mitglied werden
|
||||
ACCOUNT=Benutzerkonto
|
||||
USERNAME=Benutzername
|
||||
CLOSE=Schliessen
|
||||
NOT_READY_A_USER=Noch kein Mitglied?
|
||||
NOT_READY_A_USER_MESSAGE=Die Mitgliedschaft ist frei und die Registrierung dauert nur einen kurzen Moment
|
||||
JOIN_NOW=Trete bei!
|
||||
YOUR_ROLE=Deine Rolle
|
||||
FORGOT_PASSWORD=Passwort vergessen ?
|
||||
CHANGE_PASSWORD=Ändere Passwort
|
||||
CHANGE_LANGUAGE=Ändere Sprache
|
||||
FAQ=Häufig gestellte Fragen
|
||||
SHORT_FAQ=FAQ
|
||||
LOGIN=Anmelden
|
||||
EXPORT=Exportieren
|
||||
SVG_EXPORT_FORMAT=Skalierbare Vektor Graphik (SVG)
|
||||
PDF_EXPORT_FORMAT=Portables Dokumenten Format (PDF)
|
||||
IMG_EXPORT_FORMAT=Bilddatei (PNG/JPEG)
|
||||
FREEMIND_EXPORT_FORMAT = Freemind (version 0.9.0)
|
||||
WISEMAPPING_EXPORT_FORMAT = WiseMapping
|
||||
LAST_UPDATE=Zuletzt geändert
|
||||
LAST_UPDATE_BY=Zuletzt geändert von
|
||||
DELETE=Löschen
|
||||
SITE.TITLE=WiseMapping
|
||||
SITE.SLOGAN=Evolution des Visuellen Denkens
|
||||
KEYBOARD=Tastaturkürzel
|
||||
KEYBOARD_MSG=Das sind die Tastaturkürzel, die im Editor benutzt werden können!
|
||||
HOME=Eingangsseite
|
||||
LOGIN_ERROR=Die eingegebene email Adresse oder das Passwort ist nicht korrekt.
|
||||
USER_INACTIVE=Ihr Benutzerkonto ist leider noch nicht aktiviert. Sie bekommen eine Benachrrichtigung in Form einer email sobald Ihr Benutzerkonto aktiv ist. Bitte haben Sie noch ein wenig Geduld!
|
||||
CREW=Die Mannschaft
|
||||
ALREADY_A_MEMBER=Bereits Mitglied?
|
||||
TERM_OF_THE_SERVICE=Geschäftsbedingungen
|
||||
FORGOT_PASSWORD_MESSAGE=Bitte geben Sie eine email Adresse an, damit wir Ihnen helfen können Ihr WiseMapping Konto ausfindig zu machen.
|
||||
FIELD_REQUIRED=Ein benötigtes Feld kann icht leer gelassen werden
|
||||
EMAIL_ALREADY_EXIST=Die email Adresse existiert bereits
|
||||
NO_VALID_EMAIL_ADDRESS=Ungültige email Adresse
|
||||
USERNAME_ALREADY_EXIST=Der Benutzername existiert bereits
|
||||
PASSWORD_MISSMATCH=Ihre Passwort Angaben sind nicht identisch
|
||||
CHANGE_PASSWORD_SUCCESS=Ihr Passwort wurde erfolgreich geändert
|
||||
WISEMAPPING_ACCOUNT_MESSAGE=Bitte überprüfen Sie die eingegebenen WiseMapping Benutzerkonto Informationen und Geschäftsbedingungen
|
||||
REGISTRATION_CLICK_ADVICE= Mit der Registrierung erklären Sie ihr Einverständnis mit den Geschäftsbedingungen und Datenschutzregeln von WiseMapping.
|
||||
REGISTRATION_TITLE_MSG=Bitte fülle die Felder aus, um ein Mitglied der WiseMapping Gemeinschaft zu werden. Die Registrierung is <b>kostenlos</b> und in wenigen Augenblicken erledigt.
|
||||
CAPTCHA_ERROR=Bitte geben Sie die Buchstaben wie auf dem Bild dargestellt ein.
|
||||
CREATOR=Urheber
|
||||
CREATION_TIME=Erstellungs Datum
|
||||
EDITORS=Verfasser
|
||||
PUBLIC=Öffentlich
|
||||
SHARED=Gemeinsam benutzt
|
||||
ONLY_VIEW_PRIVATE = Diese mindmap kann nur von Ihnen angeschaut werden.
|
||||
ALL_VIEW_PUBLIC = Diese mindamp können alle Benutzer anschauen.
|
||||
NEW_MAP_MSG=Erzeuge eine neue map
|
||||
PUBLISH=Veröffentlichen
|
||||
PUBLISH_DETAILS=Die Veröffentlichung dieser map macht sie für alle Benutzer im Internet sichtbar.
|
||||
ACCOUNT_DETAIL=Möchten Sie ihre Benutzereinstellungen ändern? Dann sind Sie hier richtig.
|
||||
SVG_EXPORT_FORMAT_DETAILS=Skalierbare Vektor Graphik (SVG) ist ein XML Format zur Beschreibung von zwei-dimensionalen Vektorgraphiken. Dieses Format erlaubt den Druck Ihrer maps ohne Verlust von Qualität bei egal welcher Auflösung.
|
||||
PDF_EXPORT_FORMAT_DETAILS=Exportieren Sie ihre map im Portablen Dokumenten Format (PDF) zur Verwendung in Präsentationen.
|
||||
IMG_EXPORT_FORMAT_DETAILS=Exportieren Sie eine graphische Repräsentation Ihrer map mit allen Farben und Formen zur Verwendung in Dokumenten oder zur Archivierung.
|
||||
FREEMIND_EXPORT_FORMAT_DETAILS = FreeMind ist eine schöne und frei erhältliche "Desktop" MindMapping Applikation.
|
||||
WISEMAPPING_EXPORT_FORMAT_DETAILS = Exportieren Sie ihre map im WiseMapping Dokumentenformat.
|
||||
TERMSOFUSE=Geschäftsbedingungen
|
||||
PRIVACYPOLICY= Datenschutzrichtlinien
|
||||
EXPORT_DETAILS=Exportieren Sie ihre map in einem von Ihnen gewünschtem Format zur Verwendung in Präsentationen oder Weiterleitung mittles elektronischer Post (email).
|
||||
HERE=hier
|
||||
WHO_ARE_WE=Wer sind wir?
|
||||
WELCOME=Willkommen
|
||||
RENAME=Umbenennen
|
||||
MAX_CHARACTER_SIZE= Maximal erlaubte Nachrichtenlänge von 512 Buchstaben.
|
||||
URL=URL
|
||||
DIRECT_LINK=Direkte Verbindung
|
||||
BLOG_INCLUSION=Sie können das Quelltextfragment zur Einbettung in Ihren Blog oder Internet Seite anpassen. Stellen Sie sicher, das die korrekten Dimensionen der Darstellungsfläche in ihrer Seite eingestellt sind damit Ihre map sich optimal in Ihre Seite einfügt.
|
||||
BLOG_SNIPPET=Kopieren Sie dieses Quelltextfragment zur Einbindung in Ihren Blog oder Internet Seite.
|
||||
ZOOM=Zoom
|
||||
HISTORY=Historie
|
||||
SHARE=Veröffentlichen
|
||||
UNEXPECTED_ERROR=Outch!!. Ein unerwarteter Fehler ist aufgetreten.
|
||||
UNEXPECTED_ERROR_DETAILS=Es tut uns Leid! Es ist ein Fehler aufgetreten der es uns nicht ermöglicht Ihre Anfrage zu bearbeiten. Bitte versuchen Sie es noch einmal oder gehen Sie zur Anfangsseite.
|
||||
UNEXPECTED_ERROR_SERVER_ERROR=Es tut uns Leid! Es ist ein Fehler aufgetreten der es uns nicht ermöglicht Ihre Anfrage zu bearbeiten. Aktualisieren Sie diese Seite und versuchen es erneut. Falls der Fehler wieder auftritt, kontaktieren Sie bitte support@wisemapping.com
|
||||
NO_ENOUGH_PERMISSIONS=Outch!!. Diese map ist nicht mehr verfügbar.
|
||||
NO_ENOUGH_PERMISSIONS_DETAILS=Sie haben nicht die erforderlichen Rechte, um sich diese map anzusehen. Diese map ist entweder privat oder wurde gelöscht.
|
||||
IMPORT_MINDMAP_INFO=Sie können FreeMind 0.9 und WiseMapping maps in Ihre List von maps importieren. Wählen Sie die Datei zum Import.
|
||||
PRINT=Drucken
|
||||
IMPORT_MAP_ERROR=FreeMind Datei konnte nicht importiert werden. {0}
|
||||
MAP_TITLE_ALREADY_EXISTS=Sie haben schon eine map mit identischem Namen.
|
||||
#####FOOTER
|
||||
COPYRIGHT=Powered by WiseMapping
|
||||
TERMS_AND_CONDITIONS=Allgemeine Geschäftsbedingungen
|
||||
CONTACT=Kontakt
|
||||
|
||||
ACCOUNT_ACTIVED= Ihr Benutzerkonto wurde aktiviert.
|
||||
ACCOUNT_ACTIVED_FAIL = Die Aktivierung Ihres Benutzerkonto ist fehlgeschlagen.
|
||||
NO_HISTORY_RESULTS= Keine Historie verfügbar.
|
||||
REVERT=rückgängig
|
||||
INVALID_EMAIL_ERROR = Die email wurde nicht verifiziert.
|
||||
NO_PRODUCTION_DATABASE_CONFIGURED=Obzwar HSQLDB mit WiseMapping in der Stadardinstallation gebündelt ist, empfehlen wir nicht die Benutzung von HSQLDB in Produktionsumgebungen. Anstatt, bitte verwenden Sie MySQL Version 5.5
|
||||
IMPORT=Importieren
|
||||
|
||||
EMBEDDED_MAP_SIZE=* Hinweis: Sie können die eingebettete Größe der map mit Hife der Parameter 'height' und 'width' einstellen. Sie können ausserdem den Zoom Faktor mit Hilfe des Parameters 'zoom' in der URL einstellen.
|
||||
EXPORT_FORMAT_RESTRICTIONS=Der Export als Bild, PDF oder SVG ist nur in der Editor Menüleiste verfügbar.
|
||||
STARRED=Favorit
|
||||
ALL_MAPS=Alle
|
||||
MY_MAPS=Meine Maps
|
||||
SHARED_WITH_ME=Gemeinsam mit mir genutzt
|
||||
PUBLIC_MAPS=Öffentliche Maps
|
||||
ACCEPT=Akzeptiert
|
||||
SAVING=Sichern ...
|
||||
INFO=Information
|
||||
DELETE_MINDMAP=Löschen
|
||||
DUPLICATE=Dulizieren
|
||||
CREATE=Anlegen
|
||||
LANGUAGE=Sprache
|
||||
FILTERS=Filter
|
||||
MORE=Mehr
|
||||
ADD_NEW_MAP=Füge neue Map hinzu
|
||||
IMPORTING=Importieren ...
|
||||
NEW=Neu
|
||||
MIND_FILE=Datei
|
||||
NO_SEARCH_RESULT=Keine map für das gewählte Filterkriterium gefunden.
|
||||
SEARCH=Suche
|
||||
GENERAL=Allgemein
|
||||
SECURITY=Sicherheit
|
||||
MAP_NAME_HINT=Name der zu erzeugenden map
|
||||
MAP_DESCRIPTION_HINT=Kurzbeschreibung der map
|
||||
WARNING=Warnung
|
||||
DELETE_MAPS_WARNING=Eine gelöschte mindmap kann nicht wieder hergestellt werden. Möchten Sie fortfahren?
|
||||
THANKS_FOR_SIGN_UP=Vielen Dank für die Registrierung!
|
||||
SIGN_UP_CONFIRMATION_EMAIL=\ Sie werden in kürze eine Bestätigungsnachricht von WiseMapping erhalten. Darin werden Sie gebeten, Ihr WiseMapping Benutzerkonto zu aktivieren.</br>Bitte wählen Sie die Verbindung in dieser email zur Aktivierung. Danach können Sie eigene maps anlegen und veröffentlichen.
|
||||
SIGN_UP_SUCCESS=Ihr Benutzerkonot wurde erfolgreich angelegt, drücken Sie <a href\="c/login">hier</a> um sich anzumelden und WiseMapping zu geniessen.
|
||||
ACCOUNT_DOES_NOT_EXISTS=Diese Nachricht ist nicht registriert oder Ihr Benutzerkonto ist noch nicht aktiviert.
|
||||
ACCOUNT_DOES_NOT_EXISTS_SUPPORT=Falls das Problem weiterhin auftritt dann senden Sie uns bitte eine Nachricht an <a href\="mailto\:support@wisemapping.com">support@wisemapping.com </a>
|
||||
SENDING=Senden ...
|
||||
SIGN_ING=Anmelden ...
|
||||
ENABLE_PUBLISHING=Mitbenutzung einschalten
|
||||
FRAME_HEIGHT=Rahmenhöhe
|
||||
FRAME_WIDTH=Rahmenbreite
|
||||
EMBED=Eingebettet
|
||||
PUBLIC_URL=Öffentliche URLs
|
||||
ADD_PEOPLE=Personen hinzufügen
|
||||
COLLABORATORS_SEPARATED_BY_COMA=Geben Sie die email Adresse der Mitbenutzer als Komma separierte Liste an
|
||||
CAN_EDIT=Kann Ändern
|
||||
CAN_VIEW=Kann Anschauen
|
||||
EMAIL_NOTIFICATION_MESSAGE=Email Benachrichtigung Einstellungen
|
||||
ADD_MESSAGE=Nachricht hinzufügen
|
||||
WHO_CAN_ACCESS=Wer hat Zugriff
|
||||
IS_OWNER=Ist Besitzer
|
||||
OPTIONAL_CUSTOM_MESSAGE=Optional\: Fügen Sie eine persönliche Nachricht ein
|
||||
VIEW=Ansicht
|
||||
YOU=Sie
|
||||
INFO_UPDATE_SUCCESS=Ihre Daten sind erfolgreich geändert worden
|
||||
OR_GREATER=oder größer
|
||||
IMPORTANT=Wichtig
|
||||
|
||||
BROWSER_RECOMMENDATION=Die Browser sind nach Geschwindigkeit und Ausführlichkeit der Tests durch das WiseMappig Team sortiert.
|
||||
BROWSER_NOT_SUPPORTED_TITLE=Ups\!\!\!. Ihr Browser ist momentan nicht unterstützt!
|
||||
BROWSER_NOT_SUPPORTED_MSG=Ihr Browser wurde nicht vollständig mit der WiseMapping Applikation getestet, s.d. manche Funktionen nicht zur Verfügung stehen. WiseMapping wurde optimiert für:
|
||||
BROWSER_NOT_SUPPORTED_TRY_AGAIN=Bitte versuchen Sie es nocheinmal mit einem von WiseMapping unterstützten Browser.
|
||||
|
||||
INSTALL_CFG=Tut uns Leid, Microsoft Internet Explorer 8 ist nur teilweise unterstützt.
|
||||
INSTALL_CFG_REASON = Microsoft Internet Explorer 8 hat keine Unterstützung für HTML 5 SVG. SVG ist die von WiseMapping benutzte Technologie, um mindmaps zu editieren und anzuzeigen. Wir empfehlen eine Aktualisierung auf Microsoft Internet Explorer 9 oder die Benutzung eines anderen Browser wie z.B. Google Chrome, Firefox oder Safari.
|
||||
INSTALL_CFG_CLICK_HERE=Falls Sie dennoch Microsoft Internet Explorer 8 benutzen möchten, drücken Sie hier, um das Gogle Chrome Frame Plugin zu instalieren. Das Google Chrome Frame Plugin erweitert Internet Explorer mit Unterstützung für HTML 5.
|
||||
SHOW_REGISTERS=Zeige _MENU_ Einträge
|
||||
LOADING=Laden ...
|
||||
NO_MATCHING_FOUND=Keine passenden Einträge gefunden
|
||||
TABLE_ROWS=_START_-_END_ von _TOTAL_
|
||||
ACTION=Aktion
|
||||
CREATE_SIBLING_TOPIC=Erzeuge ein Schwester Thema
|
||||
CREATE_CHILD_TOPIC=Eryeuge ein Unterthema
|
||||
DELETE_TOPIC=Lösche Thema
|
||||
EDIT_TOPIC_TEXT=Editiere Thematext
|
||||
JUST_START_TYPING=Einfach mit der Eingabe beginnen
|
||||
CANCEL_TEXT_CHANGES=Textänderungen abbrechen
|
||||
TOPIC_NAVIGATION=Themen Navigation
|
||||
ARROW_KEYS=Pfeiltasten
|
||||
SELECT_MULTIPLE_NODES=Wähle mehrfache Knoten aus
|
||||
UNDO_EDITION=Änderungen rückgängig machen
|
||||
REDO_EDITION=Änderung nochmal ausführen
|
||||
SELECT_ALL_TOPIC=Wähle alle Themen aus
|
||||
CHANGE_TEXT_BOLD=Ändere Text in fette Schrift
|
||||
SAVE_CHANGES=Änderungen sichern
|
||||
CHANGE_TEXT_ITALIC=Ändere Text in kursive Schrift
|
||||
DESELECT_ALL_TOPIC=Deselektiere alle Themen
|
||||
SHORTCUTS=Tastenkürzel
|
||||
COLLAPSE_CHILDREN=Kindknoten zusammenklappen
|
||||
KEYBOARD_SHORTCUTS_MSG=Tastenkürzel helfen Zeit zu sparen und erlauben die Arbeit nur mit der Tatstatur, s.d. Sie niemals die Hand von der Tastatur nehmen müßen, um die Maus zu bedienen.
|
||||
COPY_AND_PASTE_TOPICS=Kopieren und Einsetzen von Themen
|
||||
MULTIPLE_LINES=Füge mehrer Textzeilen hinzu
|
||||
TERM_OF_USE=Allgemeine Geschäftsbedingungen
|
||||
|
||||
# Properties used on the tutorial mindmap ....
|
||||
TUTORIAL.MULTIPLE_TEXT_STYLES=Mehrfache Textstile
|
||||
TUTORIAL.DIFFERENT_SHAPES=Verschiedene Formen
|
||||
TUTORIAL.FANCY_ICONS=Fantasievolle Szmbole
|
||||
TUTORIAL.MOVE_WITH_ARROWS=Mit Pfeiltasten zwischen Themen auswählen
|
||||
TUTORIAL.START_TYPING_TO_EDIT_TEXT=Einfach mit dem tippen beginnen, um Text zu editieren
|
||||
TUTORIAL.CTRL_TO_ADD_CHILD=Drücke Ctrl/Meta+Enter um ein Unterthema einzufügen
|
||||
TUTORIAL.ENTER_TO_ADD_SIBLING=Drücke Enter um ein Schwesterthema einzufügen
|
||||
TUTORIAL.MORE_KEY_TIPS=Mehr ?. Drücke auf obige Tastenkürzel
|
||||
TUTORIAL.DOUBLE_CLICK_TO_ADD=Doppelklick auf den Canvas, um Themen zu erzeugen
|
||||
TUTORIAL.DRAG_AND_DROP_TO_POSITION=Ziehen des Thema auf die Position
|
||||
TUTORIAL.DOUBLE_CLICK_TO_EDIT_TEXT=Doppelklic auf ein Thema, um Text zu editieren
|
||||
TUTORIAL.ADD_NOTES=Füge Notizen hinzu
|
||||
TUTORIAL.USER_THE_TOOLBAR=Benutze die Werkzeugleiste
|
||||
TUTORIAL.PUBLISH_YOUR_MAPS=Veröffentliche Ihre map
|
||||
TUTORIAL.EMBED_IN_BLOGS=In Blog einbinden
|
||||
TUTORIAL.INVITE_FRIEND=Freunde zur zusammenarbeit einladen
|
||||
TUTORIAL.SHARING=Mitbenutzung
|
||||
TUTORIAL.EDITION_USING_MOUSE=Editieren mit der Maus
|
||||
TUTORIAL.EDITION_USING_KEYBOARD=Editieren mit der Tastatur
|
||||
TUTORIAL.ADD_LINKS_WEBPAGES=Verbindungen auf Internetseiten hinzufügen
|
||||
TUTORIAL.TOPIC_PROPERTIES=Themen Eigenschaften
|
||||
TUTORIAL.HOW_TO_START=Wie fange ich an ?
|
||||
TUTORIAL.FONT_COLOR=Farbe
|
||||
TUTORIAL.FONT_STYLE=Stil
|
||||
TUTORIAL.FONT_TYPE=Typ
|
||||
TUTORIAL.SAMPLE_NOTE=Das ist eine einfache Notiz!
|
||||
SUPPORT=Unterstützung
|
||||
FEEDBACK=Resonanz
|
||||
CONTACT_US=Kontaktieren Sie uns
|
||||
|
||||
#Pending for translation ...
|
||||
CAPTCHA_LOADING_ERROR=ReCaptcha konnte nicht geladen werden. Sie müssen den Zugriff auf den Google ReCaptcha Dienst sicher stellen.
|
||||
ACCESS_HAS_BEEN_REVOKED= Upps. Ihre Zugriffsrechte auf diese map sind zurückgesetzt worden. Kontaktieren Sie den Besitzer dieser map.
|
||||
LICENSE=Lizenz
|
||||
WELCOME_TO_WISEMAPPING=Wilkommen zu WiseMapping
|
||||
WELCOME_DETAILS=WiseMapping erlaubt Ihnen das anlegen und anzeigen von maps von überall. Mit WiseMapping können sie: <ul><li>Einbinden von maps in Internetseiten und blogs</li><li>Verbinden von maps mit Dokumenten</li><li>Gemeinsame Nutzung von maps unter Freunden und Kollegen</li><li>Exportieren von maps in SVG,PNG,JPG und FreeMind</li></ul>.
|
||||
DIRECT_LINK_EXPLANATION=Kopieren und Einsetzen der unten stehenden Verbindung, um die Mitbenutzung der map mit Ihren Freunden und Kollegen zu ermöglichen
|
||||
TEMPORAL_PASSWORD_SENT=Ihr temporäres Passwort wurde angelegt
|
||||
TEMPORAL_PASSWORD_SENT_DETAILS=Wir haben Ihnen eine email gesendet, die es Ihnen erlaubt Ihr Passwort zurückzusetzen. Bitte prüfen Sie den Posteingang.
|
||||
TEMPORAL_PASSWORD_SENT_SUPPORT=Falls sie Probleme haben die email zu empfangen, kontaktieren Sie uns unter <a href\="mailto\:support@wisemapping.com">support@wisemapping.com </a>
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -151,7 +151,7 @@ SIGN_UP_SUCCESS=Your account has been created successfully, click <a href\="c/lo
|
||||
ACCOUNT_DOES_NOT_EXISTS=The email is not register or you account is not active yet.
|
||||
ACCOUNT_DOES_NOT_EXISTS_SUPPORT=If the problem persist please send us an email to <a href\="mailto\:support@wisemapping.com">support@wisemapping.com </a>
|
||||
SENDING=Sending ...
|
||||
SIGN_ING=Singing in ...
|
||||
SIGN_ING=Signing in ...
|
||||
ENABLE_PUBLISHING=Enable Sharing
|
||||
FRAME_HEIGHT=Frame height
|
||||
FRAME_WIDTH=Frame width
|
||||
@@ -183,7 +183,7 @@ INSTALL_CFG_CLICK_HERE=If you still want to use Microsoft Internet Explorer 8, c
|
||||
SHOW_REGISTERS=Show _MENU_ entries
|
||||
LOADING=Loading ...
|
||||
NO_MATCHING_FOUND=No matching records found
|
||||
TABLE_ROWS=\ _START_-_END_ of _TOTAL_
|
||||
TABLE_ROWS=_START_-_END_ of _TOTAL_
|
||||
ACTION=Action
|
||||
CREATE_SIBLING_TOPIC=Create Sibling Topic
|
||||
CREATE_CHILD_TOPIC=Create Child Topic
|
||||
@@ -250,7 +250,9 @@ TEMPORAL_PASSWORD_SENT=Your temporal password has been sent
|
||||
TEMPORAL_PASSWORD_SENT_DETAILS=We've sent you an email that will allow you to reset your password. Please check your email now.
|
||||
TEMPORAL_PASSWORD_SENT_SUPPORT=If you have any problem receiving the email, contact us to <a href\="mailto\:support@wisemapping.com">support@wisemapping.com </a>
|
||||
MINDMAP_TIMESTAMP_OUTDATED=It's not possible to save your changes because your mindmap has been modified by '{0}'. Refresh the page and try again.
|
||||
MINDMAP_OUTDATED_BY_YOU=It's not possible to save your changes because map is out of date. Do you have multiple tabs opened ?. Refresh the page and try again.
|
||||
MINDMAP_LOCKED=Map is being edited by {0} <{1}>. Map is opened in read only mode.
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|
||||
|
||||
|
@@ -250,6 +250,7 @@ TEMPORAL_PASSWORD_SENT_DETAILS=Se te ha enviado un mail con los detalles para ca
|
||||
TEMPORAL_PASSWORD_SENT=Tu contraseña temporal ha sido enviada
|
||||
MINDMAP_LOCKED=El mapa esta siendo editado por {0} <{1}>. Mapa sera abierto en modo lectura.
|
||||
MINDMAP_TIMESTAMP_OUTDATED=No es posible grabar sus cambios por que el mapa ha sido modificado por {0}'. Refresque la pagina y intentelo nuevamente.
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|
||||
|
||||
|
@@ -250,6 +250,7 @@ ACCESS_HAS_BEEN_REVOKED= Upps. your access permissions to this map has been revo
|
||||
LICENSE=License
|
||||
WELCOME_TO_WISEMAPPING=Welcome to WiseMapping
|
||||
WELCOME_DETAILS=WiseMapping will enable you to create and read your mind maps everywhere. With WiseMapping you can: <ul><li>Embed mind map it in web pages and blogs</li><li>Link mind map and documents</li><li>Share your maps with friend and colleagues</li><li>Export your maps SVG,PNG,JPG and FreeMind</li></ul>.
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|
||||
|
||||
|
@@ -235,6 +235,7 @@ TUTORIAL.FONT_COLOR=Colore
|
||||
TUTORIAL.FONT_STYLE=Stili
|
||||
TUTORIAL.FONT_TYPE=Font
|
||||
TUTORIAL.SAMPLE_NOTE=Questa è una semplice nota !.
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|
||||
|
||||
|
@@ -235,4 +235,5 @@ TUTORIAL.SAMPLE_NOTE=Esta é uma nota simples !.
|
||||
SUPPORT=Ajudar
|
||||
FEEDBACK=Feedback
|
||||
CONTACT_US=Contato
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|
@@ -210,4 +210,5 @@ TERM_OF_USE=条款和条件
|
||||
CONTACT_US=联系我们
|
||||
FEEDBACK=反馈
|
||||
SUPPORT=支援
|
||||
TUTORIAL_VIDEO=Tutorial Video
|
||||
|
||||
|