28 Commits

Author SHA1 Message Date
Paulo Gustavo Veiga
0cbe108910 Add added to the top. 2012-09-11 02:01:52 -03:00
Paulo Gustavo Veiga
3fb746f79b - Change to start using bootstrap grid 2012-09-11 01:47:23 -03:00
Paulo Gustavo Veiga
6efc068a6c Fix editor.js url location. 2012-09-10 14:45:44 -03:00
Paulo Gustavo Veiga
db49d96b97 - Fix image URL on sharing. 2012-09-10 13:16:52 -03:00
Paulo Gustavo Veiga
3fda0c9dab Fix better default for email notifications. 2012-09-10 09:50:56 -03:00
Paulo Gustavo Veiga
e83fa28ae8 Relax and add support for Firefox 10 and Chrome 18. 2012-09-09 19:13:53 -03:00
Paulo Gustavo Veiga
84fcad2688 Fix compilation. 2012-09-09 19:04:34 -03:00
Paulo Gustavo Veiga
3f2b343a06 Detect Google Mediapartners browser. 2012-09-09 19:02:41 -03:00
Paulo Gustavo Veiga
e76a2372d0 Fix minor french translation typos. 2012-09-09 13:34:33 -03:00
Paulo Gustavo Veiga
861d265891 - Fix MooDialog.Request.active is null 2012-09-08 14:32:43 -03:00
Paulo Gustavo Veiga
0b0cb960f7 Enable annotations driven. 2012-09-08 12:49:49 -03:00
Paulo Gustavo Veiga
c15c1824b3 Fix stack overflow 2012-09-08 12:27:50 -03:00
Paulo Gustavo Veiga
8321363333 Add freemind converted. 2012-09-08 12:01:26 -03:00
Paulo Gustavo Veiga
c950e68a27 - Bug Cannot call method 'trim' of undefined, line:2255 fixed. 2012-09-07 20:15:42 -03:00
Paulo Gustavo Veiga
8d9fb53741 Minor fix. 2012-09-07 19:49:36 -03:00
Paulo Gustavo Veiga
4cce432bb8 Add debug information on broken input streams. 2012-09-07 19:40:08 -03:00
Paulo Gustavo Veiga
337a67a8f6 Fix ReCaptha NPE
Improve error handling when permission are removed.
2012-09-06 23:52:53 -03:00
Paulo Gustavo Veiga
743164ade4 - Fix Uncaught Cilcular connection, line:8 error 2012-09-04 23:41:34 -03:00
Paulo Gustavo Veiga
9a94326469 - Minor improvement on relationship. Show arrow. 2012-09-04 23:29:24 -03:00
Paulo Gustavo Veiga
a86a38d157 - Fix character encodding issue on mysql 2012-09-04 22:12:52 -03:00
Paulo Gustavo Veiga
9ab4c4975c - Fix undo issues over features. 2012-09-04 01:06:50 -03:00
Paulo Gustavo Veiga
1efa24f2aa - Fix Uncaught Icon can no be found., line:3940 2012-09-04 00:50:12 -03:00
Paulo Gustavo Veiga
3f173ec2f1 - Fix Cannot call method 'set' of null. This occurs on zoomIn and zoomOut of print. 2012-09-03 22:16:36 -03:00
Paulo Gustavo Veiga
6008376ad5 - Add Mediapartners-Google add sense crawler 2012-09-03 21:39:40 -03:00
Paulo Gustavo Veiga
c4c3f30303 Bug TypeError: c is undefined, line:4491 fixed. 2012-09-03 21:13:35 -03:00
Paulo Gustavo Veiga
bcc5676b49 - Bug Cannot call method 'getChildren' of null, line:1955 fixed. 2012-09-03 20:54:18 -03:00
Paulo Gustavo Veiga
ca37d3f384 -Fix Uncaught RangeError: Maximum call stack size exceeded, line:114 2012-09-02 19:52:37 -03:00
Paulo Gustavo Veiga
04a221799a Add filter for avoiding multiple emails on error reporting. 2012-09-02 18:24:15 -03:00
48 changed files with 1214 additions and 996 deletions

View File

@@ -16,5 +16,6 @@ WISE_BIN_FILE_PATH=./target/${WISE_BIN_FILE_NAME}
scp ${WISE_BIN_FILE_PATH} thecrow@wisemapping.com:${SERVER_DOWNLOAD_DIR}
# It's there ?
cd target
wget -S http://downloads.wisemapping.org/stable/${WISE_BIN_FILE_NAME}
#wget -S http://downloads.wisemapping.org/stable/${WISE_SRC_FILE_NAME}

View File

@@ -20,7 +20,7 @@ mindplot.ConnectionLine = new Class({
initialize:function (sourceNode, targetNode, lineType) {
$assert(targetNode, 'parentNode node can not be null');
$assert(sourceNode, 'childNode node can not be null');
$assert(sourceNode != targetNode, 'Cilcular connection');
$assert(sourceNode != targetNode, 'Circular connection');
this._targetTopic = targetNode;
this._sourceTopic = sourceNode;

View File

@@ -335,39 +335,43 @@ mindplot.DesignerKeyboard = new Class({
},
_goToBrother:function (designer, node, direction) {
var brothers = node.getParent().getChildren();
var target = node;
var y = node.getPosition().y;
var x = node.getPosition().x;
var dist = null;
for (var i = 0; i < brothers.length; i++) {
var sameSide = (x * brothers[i].getPosition().x) >= 0;
if (brothers[i] != node && sameSide) {
var brother = brothers[i];
var brotherY = brother.getPosition().y;
if (direction == "DOWN" && brotherY > y) {
var distancia = y - brotherY;
if (distancia < 0) {
distancia = distancia * (-1);
var parent = node.getParent();
if (parent) {
var brothers = parent.getChildren();
var target = node;
var y = node.getPosition().y;
var x = node.getPosition().x;
var dist = null;
for (var i = 0; i < brothers.length; i++) {
var sameSide = (x * brothers[i].getPosition().x) >= 0;
if (brothers[i] != node && sameSide) {
var brother = brothers[i];
var brotherY = brother.getPosition().y;
if (direction == "DOWN" && brotherY > y) {
var distancia = y - brotherY;
if (distancia < 0) {
distancia = distancia * (-1);
}
if (dist == null || dist > distancia) {
dist = distancia;
target = brothers[i];
}
}
if (dist == null || dist > distancia) {
dist = distancia;
target = brothers[i];
}
}
else if (direction == "UP" && brotherY < y) {
var distance = y - brotherY;
if (distance < 0) {
distance = distance * (-1);
}
if (dist == null || dist > distance) {
dist = distance;
target = brothers[i];
else if (direction == "UP" && brotherY < y) {
var distance = y - brotherY;
if (distance < 0) {
distance = distance * (-1);
}
if (dist == null || dist > distance) {
dist = distance;
target = brothers[i];
}
}
}
}
this._goToNode(designer, target);
}
this._goToNode(designer, target);
},

View File

@@ -1,107 +1,112 @@
/*
* Copyright [2011] [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.
*/
mindplot.DragConnector = new Class({
initialize:function (designerModel, workspace) {
$assert(designerModel, 'designerModel can not be null');
$assert(workspace, 'workspace can not be null');
// this._layoutManager = layoutManager;
this._designerModel = designerModel;
this._workspace = workspace;
},
checkConnection:function (dragTopic) {
var topics = this._designerModel.getTopics();
// Must be disconnected from their current connection ?.
var candidates = this._searchConnectionCandidates(dragTopic);
var currentConnection = dragTopic.getConnectedToTopic();
if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) {
dragTopic.disconnect(this._workspace);
}
// Finally, connect nodes ...
if (!dragTopic.isConnected() && candidates.length > 0) {
dragTopic.connectTo(candidates[0]);
}
},
_searchConnectionCandidates:function (dragTopic) {
var topics = this._designerModel.getTopics();
var draggedNode = dragTopic.getDraggedTopic();
// Drag node connects to the border ...
var dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack...
var xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth;
var sPos = {x:dragTopic.getPosition().x - xMouseGap, y:dragTopic.getPosition().y};
// Perform a initial filter to discard topics:
// - Exclude dragged topic
// - Exclude dragTopic pivot
// - Nodes that are collapsed
topics = topics.filter(function (topic) {
return draggedNode != topic && topic != draggedNode && !topic.areChildrenShrunken() && !topic.isCollapsed();
});
// Filter all the nodes that are outside the vertical boundary:
// * The node is to out of the x scope
// * The x distance greater the vertical tolerated distance
topics = topics.filter(function (topic) {
var tpos = topic.getPosition();
// Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two...
var txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x);
var distance = (sPos.x - txborder) * Math.sign(sPos.x);
return distance > 0 && (distance < mindplot.DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE);
});
// Assign a priority based on the distance:
// - Alignment with the targetNode
// - Vertical distance
// - Horizontal proximity
// - It's already connected.
var currentConnection = dragTopic.getConnectedToTopic();
topics = topics.sort(function (a, b) {
var aPos = a.getPosition();
var bPos = b.getPosition();
var av = this._isVerticallyAligned(a.getSize(), aPos, sPos);
var bv = this._isVerticallyAligned(b.getSize(), bPos, sPos);
return this._proximityWeight(av, a, sPos, currentConnection) - this._proximityWeight(bv, b, sPos, currentConnection);
}.bind(this));
return topics;
},
_proximityWeight:function (isAligned, target, sPos, currentConnection) {
var tPos = target.getPosition();
return (isAligned ? 0 : 200 ) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100);
},
_isVerticallyAligned:function (targetSize, targetPosition, sourcePosition) {
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
}
});
mindplot.DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80;
/*
* Copyright [2011] [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.
*/
mindplot.DragConnector = new Class({
initialize:function (designerModel, workspace) {
$assert(designerModel, 'designerModel can not be null');
$assert(workspace, 'workspace can not be null');
// this._layoutManager = layoutManager;
this._designerModel = designerModel;
this._workspace = workspace;
},
checkConnection:function (dragTopic) {
var topics = this._designerModel.getTopics();
// Must be disconnected from their current connection ?.
var candidates = this._searchConnectionCandidates(dragTopic);
var currentConnection = dragTopic.getConnectedToTopic();
if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) {
dragTopic.disconnect(this._workspace);
}
// Finally, connect nodes ...
if (!dragTopic.isConnected() && candidates.length > 0) {
dragTopic.connectTo(candidates[0]);
}
},
_searchConnectionCandidates:function (dragTopic) {
var topics = this._designerModel.getTopics();
var draggedNode = dragTopic.getDraggedTopic();
// Drag node connects to the border ...
var dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack...
var xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth;
var sPos = {x:dragTopic.getPosition().x - xMouseGap, y:dragTopic.getPosition().y};
// Perform a initial filter to discard topics:
// - Exclude dragged topic
// - Exclude dragTopic pivot
// - Nodes that are collapsed
// - It's not part of the branch dragged itself
topics = topics.filter(function (topic) {
var result = draggedNode != topic;
result = result && topic != draggedNode;
result = result && !topic.areChildrenShrunken() && !topic.isCollapsed();
result = result && !draggedNode.isChildTopic(topic);
return result;
});
// Filter all the nodes that are outside the vertical boundary:
// * The node is to out of the x scope
// * The x distance greater the vertical tolerated distance
topics = topics.filter(function (topic) {
var tpos = topic.getPosition();
// Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two...
var txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x);
var distance = (sPos.x - txborder) * Math.sign(sPos.x);
return distance > 0 && (distance < mindplot.DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE);
});
// Assign a priority based on the distance:
// - Alignment with the targetNode
// - Vertical distance
// - Horizontal proximity
// - It's already connected.
var currentConnection = dragTopic.getConnectedToTopic();
topics = topics.sort(function (a, b) {
var aPos = a.getPosition();
var bPos = b.getPosition();
var av = this._isVerticallyAligned(a.getSize(), aPos, sPos);
var bv = this._isVerticallyAligned(b.getSize(), bPos, sPos);
return this._proximityWeight(av, a, sPos, currentConnection) - this._proximityWeight(bv, b, sPos, currentConnection);
}.bind(this));
return topics;
},
_proximityWeight:function (isAligned, target, sPos, currentConnection) {
var tPos = target.getPosition();
return (isAligned ? 0 : 200 ) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100);
},
_isVerticallyAligned:function (targetSize, targetPosition, sourcePosition) {
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
}
});
mindplot.DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80;

View File

@@ -39,13 +39,24 @@ mindplot.RelationshipPivot = new Class({
this._workspace.enableWorkspaceEvents(false);
var sourcePos = sourceTopic.getPosition();
var strokeColor = mindplot.Relationship.getStrokeColor();
this._pivot = new web2d.CurvedLine();
this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE);
this._pivot.setDashed(2, 2);
this._pivot.setFrom(sourcePos.x, sourcePos.y);
this._pivot.setTo(targetPos.x, targetPos.y);
this._workspace.appendChild(this._pivot);
this._pivot.setTo(targetPos.x, targetPos.y);
this._pivot.setStroke(2, 'solid', strokeColor);
this._pivot.setDashed(4, 2);
this._startArrow = new web2d.Arrow();
this._startArrow.setStrokeColor(strokeColor);
this._startArrow.setStrokeWidth(2);
this._startArrow.setFrom(sourcePos.x, sourcePos.y);
this._workspace.appendChild(this._pivot);
this._workspace.appendChild(this._startArrow);
this._workspace.addEvent('mousemove', this._mouseMoveEvent);
this._workspace.addEvent('click', this._onClickEvent);
@@ -74,10 +85,12 @@ mindplot.RelationshipPivot = new Class({
}.bind(this));
workspace.removeChild(this._pivot);
workspace.removeChild(this._startArrow);
workspace.enableWorkspaceEvents(true);
this._sourceTopic = null;
this._pivot = null;
this._startArrow = null;
}
},
@@ -85,7 +98,15 @@ mindplot.RelationshipPivot = new Class({
var screen = this._workspace.getScreenManager();
var pos = screen.getWorkspaceMousePosition(event);
this._pivot.setTo(pos.x - 1, pos.y - 1);
// Leave the arrow a couple of pixels away from the cursor.
var gapDistance = Math.sign(pos.x - this._sourceTopic.getPosition().x) * 5;
this._pivot.setTo(pos.x - gapDistance, pos.y);
var controlPoints = this._pivot.getControlPoints();
this._startArrow.setFrom(pos.x - gapDistance, pos.y);
this._startArrow.setControlPoint(controlPoints[1]);
event.stopPropagation();
return false;
},
@@ -100,8 +121,12 @@ mindplot.RelationshipPivot = new Class({
_connectOnFocus:function (targetTopic) {
var sourceTopic = this._sourceTopic;
var mindmap = this._designer.getMindmap();
var relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
this._designer._actionDispatcher.addRelationship(relModel);
// Avoid circular connections ...
if (targetTopic.getId() != sourceTopic.getId()) {
var relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
this._designer._actionDispatcher.addRelationship(relModel);
}
this.dispose();
},

View File

@@ -45,7 +45,8 @@ mindplot.RESTPersistenceManager = new Class({
events.onError();
},
onFailure:function (xhr) {
events.onError();
var responseText = xhr.responseText;
events.onError(JSON.decode(responseText));
},
headers:{"Content-Type":"application/json", "Accept":"application/json"},
emulation:false,
@@ -60,7 +61,6 @@ mindplot.RESTPersistenceManager = new Class({
async:false,
method:'post',
onSuccess:function () {
console.log("Revert success ....");
},
onException:function () {
},

View File

@@ -274,7 +274,7 @@ mindplot.Topic = new Class({
return result;
},
addFeature:function (type, attributes) {
addFeature:function (type, attributes, featureId) {
var iconGroup = this.getOrBuildIconGroup();
this.closeEditors();
@@ -282,8 +282,12 @@ mindplot.Topic = new Class({
// Update model ...
var feature = model.createFeature(type, attributes);
if ($defined(featureId)) {
feature.setId(featureId);
}
model.addFeature(feature);
var result = mindplot.TopicFeature.createIcon(this, feature, this.isReadOnly());
iconGroup.addIcon(result, type == mindplot.TopicFeature.Icon.id && !this.isReadOnly());
@@ -464,7 +468,7 @@ mindplot.Topic = new Class({
setText:function (text) {
// Avoid empty nodes ...
if (text.trim().length == 0) {
if (!text || text.trim().length == 0) {
text = null;
}
@@ -669,7 +673,6 @@ mindplot.Topic = new Class({
showNoteEditor:function () {
var topicId = this.getId();
var model = this.getModel();
var editorModel = {
@@ -1022,7 +1025,7 @@ mindplot.Topic = new Class({
connectTo:function (targetTopic, workspace, isVisible) {
$assert(!this._outgoingLine, 'Could not connect an already connected node');
$assert(targetTopic != this, 'Cilcular connection are not allowed');
$assert(targetTopic != this, 'Circular connection are not allowed');
$assert(targetTopic, 'Parent Graph can not be null');
$assert(workspace, 'Workspace can not be null');
@@ -1198,8 +1201,22 @@ mindplot.Topic = new Class({
result = result.concat(innerChilds);
}
return result;
}
},
isChildTopic:function (childTopic) {
var result = (this.getId() == childTopic.getId());
if (!result) {
var children = this.getChildren();
for (var i = 0; i < children.length; i++) {
var parent = children[i];
result = parent.isChildTopic(childTopic);
if (result) {
break;
}
}
}
return result;
}
});

View File

@@ -18,7 +18,7 @@
mindplot.commands.RemoveFeatureFromTopicCommand = new Class({
Extends:mindplot.Command,
initialize: function(topicId, featureId) {
initialize:function (topicId, featureId) {
$assert($defined(topicId), 'topicId can not be null');
$assert(featureId, 'iconModel can not be null');
@@ -28,7 +28,7 @@ mindplot.commands.RemoveFeatureFromTopicCommand = new Class({
this._oldFeature = null;
},
execute: function(commandContext) {
execute:function (commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
var feature = topic.findFeatureById(this._featureId);
@@ -36,11 +36,11 @@ mindplot.commands.RemoveFeatureFromTopicCommand = new Class({
this._oldFeature = feature;
},
undoExecute: function(commandContext) {
undoExecute:function (commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
var feature = this._oldFeature;
topic.addFeature(feature.getType(), feature.getAttributes());
topic.addFeature(feature.getType(), feature.getAttributes(), this._featureId);
this._oldFeature = null;
}
});

View File

@@ -55,6 +55,10 @@ mindplot.model.FeatureModel = new Class({
return this._id;
},
setId : function(id) {
this._id = id;
},
getType:function() {
return this._type;
}

View File

@@ -17,33 +17,37 @@
*/
mindplot.model.LinkModel = new Class({
Extends: mindplot.model.FeatureModel,
initialize : function(attributes) {
Extends:mindplot.model.FeatureModel,
initialize:function (attributes) {
this.parent(mindplot.model.LinkModel.FEATURE_TYPE);
this.setUrl(attributes.url);
},
getUrl : function() {
getUrl:function () {
return this.getAttribute('url');
},
setUrl : function(url) {
setUrl:function (url) {
$assert(url, 'url can not be null');
var fixedUrl = this._fixUrl(url);
this.setAttribute('url', fixedUrl);
var type = fixedUrl.contains('mailto:') ? 'mail' : 'url';
this.setAttribute('type', type);
this.setAttribute('urlType', type);
},
_fixUrl : function(url) {
_fixUrl:function (url) {
var result = url;
if (!result.contains('http://') && !result.contains('https://') && !result.contains('mailto://')) {
result = "http://" + result;
}
return result;
},
setUrlType:function (urlType) {
$assert(urlType, 'urlType can not be null');
this.setAttribute('urlType', urlType);
}
});

View File

@@ -78,10 +78,14 @@ mindplot.widget.IMenu = new Class({
}
menu.setRequireChange(false);
},
onError:function () {
onError:function (error) {
if (saveHistory) {
saveElem.setStyle('cursor', 'pointer');
$notify($msg('SAVE_COULD_NOT_BE_COMPLETED'));
var msg = error ? error.globalErrors : null;
if (!msg) {
msg = $msg('SAVE_COULD_NOT_BE_COMPLETED');
}
$notify(msg);
}
}
});

View File

@@ -1,76 +1,83 @@
/*
* Copyright [2011] [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.
*/
mindplot.widget.ToolbarNotifier = new Class({
initialize:function () {
var container = $('headerNotifier');
this._effect = new Fx.Elements(container, {
onComplete:function () {
container.setStyle('display', 'none');
}.bind(this),
link:'cancel',
duration:8000,
transition:Fx.Transitions.Expo.easeInOut
});
},
logError:function (userMsg) {
this.logMessage(userMsg, mindplot.widget.ToolbarNotifier.MsgKind.ERROR);
},
hide:function () {
},
logMessage:function (msg, fade) {
$assert(msg, 'msg can not be null');
var container = $('headerNotifier');
container.set('text', msg);
container.setStyle('display', 'block');
container.position({
relativeTo:$('header'),
position:'upperCenter',
edge:'centerTop'
});
if (!$defined(fade) || fade) {
this._effect.start({
0:{
opacity:[1, 0]
}
});
} else {
container.setStyle('opacity', '1');
this._effect.pause();
}
}
});
mindplot.widget.ToolbarNotifier.MsgKind = {
INFO:1,
WARNING:2,
ERROR:3,
FATAL:4
};
var toolbarNotifier = new mindplot.widget.ToolbarNotifier();
/*
* Copyright [2011] [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.
*/
mindplot.widget.ToolbarNotifier = new Class({
initialize:function () {
var container = $('headerNotifier');
// In case of print,embedded no message is displayed ....
if (container) {
this._effect = new Fx.Elements(container, {
onComplete:function () {
container.setStyle('display', 'none');
}.bind(this),
link:'cancel',
duration:8000,
transition:Fx.Transitions.Expo.easeInOut
});
}
},
logError:function (userMsg) {
this.logMessage(userMsg, mindplot.widget.ToolbarNotifier.MsgKind.ERROR);
},
hide:function () {
},
logMessage:function (msg, fade) {
$assert(msg, 'msg can not be null');
var container = $('headerNotifier');
// In case of print,embedded no message is displayed ....
if (container) {
container.set('text', msg);
container.setStyle('display', 'block');
container.position({
relativeTo:$('header'),
position:'upperCenter',
edge:'centerTop'
});
if (!$defined(fade) || fade) {
this._effect.start({
0:{
opacity:[1, 0]
}
});
} else {
container.setStyle('opacity', '1');
this._effect.pause();
}
}
}
});
mindplot.widget.ToolbarNotifier.MsgKind = {
INFO:1,
WARNING:2,
ERROR:3,
FATAL:4
};
var toolbarNotifier = new mindplot.widget.ToolbarNotifier();
$notify = toolbarNotifier.logMessage.bind(toolbarNotifier);

View File

@@ -1,4 +1,6 @@
# traduction française René Amberg 2012-08-20
# release b 2012/09/03 - release notes :
# (21) 'lien' replaced by 'noeud' (only this one change ...)
ZOOM_IN=Agrandir affichage
ZOOM_OUT=Réduire affichage
@@ -8,7 +10,7 @@ TOPIC_DELETE=Supprimer le noeud
TOPIC_ICON=Ajouter une icône
TOPIC_LINK=Ajouter un lien
TOPIC_RELATIONSHIP=Relation du noeud
TOPIC_COLOR=Couleur du lien
TOPIC_COLOR=Couleur du noeud
TOPIC_BORDER_COLOR=Couleur de bordure du noeud
TOPIC_NOTE=Ajouter une note
FONT_FAMILY=Type de police

View File

@@ -0,0 +1,11 @@
REST Services
---------------
Obtaining user information by email:
curl "http://localhost:8080/service/admin/users/email/{user.email}.json" --get --basic -u "admin@wisemapping.org:admin"
Deleting a based on the user id:
curl "http://localhost:8080/service/admin/users/{userId}" --request delete --basic -u "admin@wisemapping.org:admin"

View File

@@ -18,11 +18,21 @@
package com.wisemapping.exceptions;
import org.jetbrains.annotations.NotNull;
public class AccessDeniedSecurityException
extends Exception
extends ClientException
{
public AccessDeniedSecurityException(String msg)
public static final String MSG_KEY = "ACCESS_HAS_BEEN_REVOKED";
public AccessDeniedSecurityException(@NotNull String msg)
{
super(msg);
}
@NotNull
@Override
protected String getMsgBundleKey() {
return MSG_KEY;
}
}

View File

@@ -0,0 +1,20 @@
package com.wisemapping.exceptions;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.MessageSource;
import java.util.Locale;
abstract public class ClientException extends WiseMappingException {
public ClientException(@NotNull String message) {
super(message);
}
protected abstract
@NotNull
String getMsgBundleKey();
public String getMessage(@NotNull final MessageSource messageSource, final @NotNull Locale locale) {
return messageSource.getMessage(this.getMsgBundleKey(), null, locale);
}
}

View File

@@ -1,343 +1,350 @@
/*
* Copyright [2011] [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.filter;
import org.apache.commons.logging.LogFactory;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
public class UserAgent implements Serializable {
public static final String USER_AGENT_HEADER = "User-Agent";
private int versionMajor = -1;
private int versionVariation = -1;
private Product product;
private OS os;
private final org.apache.commons.logging.Log logger = LogFactory.getLog(UserAgent.class.getName());
private boolean hasGCFInstalled = false;
public static void main(final String argv[]) {
UserAgent explorer = UserAgent.create("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6");
UserAgent safari = UserAgent.create("iCab/2.9.5 (Macintosh; U; PPC; Mac OS X)");
UserAgent opera = UserAgent.create("Opera/9.21 (Windows NT 5.1; U; en)");
UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/1.9.6");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)");
assert firefox.isBrowserSupported();
}
public boolean isVersionGreatedOrEqualThan(final int mayor, final int variation) {
return this.versionMajor > mayor || (mayor == this.versionMajor && this.versionVariation >= variation);
}
public boolean isVersionLessThan(final int mayor) {
return this.versionMajor < mayor;
}
public int getVersionMajor() {
return versionMajor;
}
public int getVersionVariation() {
return versionVariation;
}
public Product getProduct() {
return product;
}
public OS getOs() {
return os;
}
public enum Product {
EXPLORER, FIREFOX, CAMINO, NETSCAPE, OPERA, SAFARI, CHROME, KONQUEOR, KMELEON, MOZILLA, LYNX, ROBOT, WEB_CRAWLER
}
public enum OS {
WINDOWS, LINUX, MAC, KNOWN
}
private UserAgent(final String header) {
parse(header);
}
private void parse(String userAgentHeader) {
// Format ApplicationName/ApplicationVersion ();
try {
int detailStart = userAgentHeader.indexOf('(');
int detailEnd = userAgentHeader.indexOf(')');
// Parse base format = application (productDetails) productAddition
String application = userAgentHeader.substring(0, detailStart);
application = application.trim();
String productDetails = userAgentHeader.substring(detailStart + 1, detailEnd);
productDetails = productDetails.trim();
String productAddition = userAgentHeader.substring(detailEnd + 1, userAgentHeader.length());
productAddition = productAddition.trim();
this.os = parseOS(productDetails);
if (userAgentHeader.contains("Googlebot")) {
//"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
this.product = Product.WEB_CRAWLER;
} else if (userAgentHeader.contains("MSIE")) {
// Explorer Browser : http://msdn2.microsoft.com/en-us/library/ms537503.aspx
// Format: Mozilla/MozVer (compatible; MSIE IEVer[; Provider]; Platform[; Extension]*) [Addition]
// SampleTest: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;)
// Parse version ...
int index = productDetails.indexOf("MSIE") + 4;
int lastIndex = productDetails.indexOf(';', index);
final String versionStr = productDetails.substring(index + 1, lastIndex);
parseVersion(versionStr);
// Explorer Parse ...
this.product = Product.EXPLORER;
this.hasGCFInstalled = productDetails.contains("chromeframe");
} else if (userAgentHeader.contains("iCab") || userAgentHeader.contains("Safari")) {
// Safari:
//Formats: Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/522.13.1 (KHTML, like Gecko) Version/3.0.2 Safari/522.13.1
//Chrome:
//Formats: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7"
String versionStr = "";
if (userAgentHeader.contains("Chrome")) {
this.product = Product.CHROME;
versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Chrome") + 7, userAgentHeader.lastIndexOf(" "));
} else {
this.product = Product.SAFARI;
versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Version") + 8, userAgentHeader.lastIndexOf(" "));
}
parseVersion(versionStr);
} else if (userAgentHeader.contains("Konqueror")) {
this.product = Product.KONQUEOR;
} else if (userAgentHeader.contains("KMeleon")) {
this.product = Product.KMELEON;
} else if (userAgentHeader.contains("Gecko")) {
// Firefox/Mozilla/Camino:
// Mozilla/MozVer (Platform; Security; SubPlatform; Language; rv:Revision[; Extension]*) Gecko/GeckVer [Product/ProdVer]
// SampleTest: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6
// Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13
// 'Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.12) Gecko/20050915'
// 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'
// 'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.6) Gecko/20060601 Firefox/2.0.0.6 (Ubuntu-edgy)'
// 'Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'
// "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)
// Remove gecko string
// Debian Firefox is remamed to iceweasel.
productAddition = productAddition.replace("Iceweasel", "firefox");
productAddition = productAddition.substring(productAddition.indexOf(' ') + 1);
productAddition = productAddition.toLowerCase();
String prodDesc = null;
if (productAddition.contains("firefox")) {
this.product = Product.FIREFOX;
prodDesc = "firefox";
} else if (productAddition.contains("netscape")) {
this.product = Product.NETSCAPE;
prodDesc = "netscape";
} else if (productAddition.contains("camino")) {
this.product = Product.CAMINO;
prodDesc = "camino";
} else {
this.product = Product.MOZILLA;
// @todo: How it can get the mozilla vesion?
}
// Now, parse product version ...
if (prodDesc != null) {
int sI = productAddition.indexOf(prodDesc) + prodDesc.length() + 1;
int eI = productAddition.indexOf(' ', sI);
if (eI == -1) {
eI = productAddition.length();
}
final String productVersion = productAddition.substring(sI, eI);
parseVersion(productVersion);
}
} else if (userAgentHeader.contains("Opera")) {
// Opera:
// Samples: Opera/9.0 (Windows NT 5.1; U; en)
// Opera/8.5 (Macintosh; PPC Mac OS X; U; en)
// Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.5
// Mozilla/4.0 (compatible; MSIE 6.0; Mac_PowerPC Mac OS X; en) Opera 8.5
// Opera/9.21 (Windows NT 5.1; U; en)
this.product = Product.OPERA;
String productVersion;
if (application.startsWith("Opera")) {
productVersion = application.substring(application.indexOf('/') + 1, application.length());
} else {
productVersion = productAddition.substring(application.lastIndexOf(' ') + 1, application.length());
}
parseVersion(productVersion);
} else if (userAgentHeader.contains("4.7")) {
this.product = Product.NETSCAPE;
} else if (userAgentHeader.contains("Lynx")) {
this.product = Product.LYNX;
} else {
// It's a robot ..
for (String botAgent : botAgents) {
if (userAgentHeader.contains(botAgent)) {
// set a key in the session, so the next time we don't have to manually
// detect the robot again
this.product = Product.ROBOT;
break;
}
}
logger.info("UserAgent could not be detected: '" + userAgentHeader + "'");
}
} catch (Throwable e) {
logger.error("Could not detect the browser based on the user agent: '" + userAgentHeader + "'");
// Mark as an unsupported browser...
this.product = Product.ROBOT;
}
}
private OS parseOS(String details) {
OS result;
if (details.contains("Windows"))
result = OS.WINDOWS;
else if (details.contains("Mac") || details.contains("Macintosh"))
result = OS.MAC;
else if (details.contains("X11"))
result = OS.LINUX;
else
result = OS.KNOWN;
return result;
}
public static UserAgent create(final HttpServletRequest request) {
final String userAgent = request.getHeader(USER_AGENT_HEADER);
return new UserAgent(userAgent);
}
public static UserAgent create(final String userAgent) {
return new UserAgent(userAgent);
}
private void parseVersion(final String version) {
final int index = version.indexOf('.');
final String vm = version.substring(0, index);
final String vv = version.substring(index + 1, version.length());
this.versionMajor = Integer.parseInt(vm);
char c = vv.charAt(0);
this.versionVariation = Integer.valueOf(String.valueOf(c));
}
/**
* All known robot user-agent headers (list can be found
* <a href="http://www.robotstxt.org/wc/activel">here</a>).
* <p/>
* <p>NOTE: To avoid bad detection:</p>
* <p/>
* <ul>
* <li>Robots with ID of 2 letters only were removed</li>
* <li>Robot called "webs" were removed</li>
* <li>directhit was changed in direct_hit (its real id)</li>
* </ul>
*/
private static final String[] botAgents = {
"acme.spider", "ahoythehomepagefinder", "alkaline", "appie", "arachnophilia",
"architext", "aretha", "ariadne", "aspider", "atn.txt", "atomz", "auresys",
"backrub", "bigbrother", "bjaaland", "blackwidow", "blindekuh", "bloodhound",
"brightnet", "bspider", "cactvschemistryspider", "calif", "cassandra",
"cgireader", "checkbot", "churl", "cmc", "collective", "combine", "conceptbot",
"core", "cshkust", "cusco", "cyberspyder", "deweb", "dienstspider", "diibot",
"direct_hit", "dnabot", "download_express", "dragonbot", "dwcp", "ebiness",
"eit", "emacs", "emcspider", "esther", "evliyacelebi", "fdse", "felix",
"ferret", "fetchrover", "fido", "finnish", "fireball", "fish", "fouineur",
"francoroute", "freecrawl", "funnelweb", "gazz", "gcreep", "getbot", "geturl",
"golem", "googlebot", "grapnel", "griffon", "gromit", "gulliver", "hambot",
"harvest", "havindex", "hometown", "wired-digital", "htdig", "htmlgobble",
"hyperdecontextualizer", "ibm", "iconoclast", "ilse", "imagelock", "incywincy",
"informant", "infoseek", "infoseeksidewinder", "infospider", "inspectorwww",
"intelliagent", "iron33", "israelisearch", "javabee", "jcrawler", "jeeves",
"jobot", "joebot", "jubii", "jumpstation", "katipo", "kdd", "kilroy",
"ko_yappo_robot", "labelgrabber.txt", "larbin", "legs", "linkscan",
"linkwalker", "lockon", "logo_gif", "lycos", "macworm", "magpie", "mediafox",
"merzscope", "meshexplorer", "mindcrawler", "moget", "momspider", "monster",
"motor", "muscatferret", "mwdsearch", "myweb", "netcarta", "netmechanic",
"netscoop", "newscan-online", "nhse", "nomad", "northstar", "nzexplorer",
"occam", "octopus", "orb_search", "packrat", "pageboy", "parasite", "patric",
"perignator", "perlcrawler", "phantom", "piltdownman", "pioneer", "pitkow",
"pjspider", "pka", "plumtreewebaccessor", "poppi", "portalb", "puu", "python",
"raven", "rbse", "resumerobot", "rhcs", "roadrunner", "robbie", "robi",
"roverbot", "safetynetrobot", "scooter", "search_au", "searchprocess",
"senrigan", "sgscout", "shaggy", "shaihulud", "sift", "simbot", "site-valet",
"sitegrabber", "sitetech", "slurp", "smartspider", "snooper", "solbot",
"spanner", "speedy", "spider_monkey", "spiderbot", "spiderman", "spry",
"ssearcher", "suke", "sven", "tach_bw", "tarantula", "tarspider", "tcl",
"techbot", "templeton", "titin", "titan", "tkwww", "tlspider", "ucsd",
"udmsearch", "urlck", "valkyrie", "victoria", "visionsearch", "voyager",
"vwbot", "w3index", "w3m2", "wanderer", "webbandit", "webcatcher", "webcopy",
"webfetcher", "webfoot", "weblayers", "weblinker", "webmirror", "webmoose",
"webquest", "webreader", "webreaper", "websnarf", "webspider", "webvac",
"webwalk", "webwalker", "webwatch", "wget", "whowhere", "wmir", "wolp",
"wombat", "worm", "wwwc", "wz101", "xget", "nederland.zoek"
};
public boolean isBrowserSupported() {
// Is it a supported browser ?.
final UserAgent.Product product = this.getProduct();
boolean result = product == UserAgent.Product.FIREFOX && this.isVersionGreatedOrEqualThan(12, 0);
result = result || product == UserAgent.Product.EXPLORER && this.isVersionGreatedOrEqualThan(7, 0) && this.getOs() == UserAgent.OS.WINDOWS;
result = result || product == UserAgent.Product.OPERA && this.isVersionGreatedOrEqualThan(11, 0);
result = result || product == UserAgent.Product.CHROME && this.isVersionGreatedOrEqualThan(19, 0);
result = result || product == UserAgent.Product.SAFARI && this.isVersionGreatedOrEqualThan(5, 0);
result = result || product == Product.WEB_CRAWLER;
return result;
}
public boolean needsGCF() {
final UserAgent.Product product = this.getProduct();
return product == UserAgent.Product.EXPLORER && this.isVersionLessThan(9) && this.getOs() == UserAgent.OS.WINDOWS && !this.hasGCFInstalled;
}
}
/*
* Copyright [2011] [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.filter;
import org.apache.commons.logging.LogFactory;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
public class UserAgent implements Serializable {
public static final String USER_AGENT_HEADER = "User-Agent";
private int versionMajor = -1;
private int versionVariation = -1;
private Product product;
private OS os;
private final org.apache.commons.logging.Log logger = LogFactory.getLog(UserAgent.class.getName());
private boolean hasGCFInstalled = false;
public static void main(final String argv[]) {
UserAgent explorer = UserAgent.create("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6");
UserAgent safari = UserAgent.create("iCab/2.9.5 (Macintosh; U; PPC; Mac OS X)");
UserAgent opera = UserAgent.create("Opera/9.21 (Windows NT 5.1; U; en)");
UserAgent firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/1.9.6");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'");
assert firefox.isBrowserSupported();
firefox = UserAgent.create("Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)");
assert firefox.isBrowserSupported();
}
public boolean isVersionGreatedOrEqualThan(final int mayor, final int variation) {
return this.versionMajor > mayor || (mayor == this.versionMajor && this.versionVariation >= variation);
}
public boolean isVersionLessThan(final int mayor) {
return this.versionMajor < mayor;
}
public int getVersionMajor() {
return versionMajor;
}
public int getVersionVariation() {
return versionVariation;
}
public Product getProduct() {
return product;
}
public OS getOs() {
return os;
}
public enum Product {
EXPLORER, FIREFOX, CAMINO, NETSCAPE, OPERA, SAFARI, CHROME, KONQUEOR, KMELEON, MOZILLA, LYNX, ROBOT, WEB_CRAWLER
}
public enum OS {
WINDOWS, LINUX, MAC, KNOWN
}
private UserAgent(final String header) {
parse(header);
}
private void parse(String userAgentHeader) {
// Format ApplicationName/ApplicationVersion ();
try {
// Mediapartners-Google -> Add sense robot
if(userAgentHeader.equals("Mediapartners-Google")){
this.product = Product.WEB_CRAWLER;
return;
}
int detailStart = userAgentHeader.indexOf('(');
int detailEnd = userAgentHeader.indexOf(')');
// Parse base format = application (productDetails) productAddition
String application = userAgentHeader.substring(0, detailStart);
application = application.trim();
String productDetails = userAgentHeader.substring(detailStart + 1, detailEnd);
productDetails = productDetails.trim();
String productAddition = userAgentHeader.substring(detailEnd + 1, userAgentHeader.length());
productAddition = productAddition.trim();
this.os = parseOS(productDetails);
if (userAgentHeader.contains("Googlebot") ) {
//"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
this.product = Product.WEB_CRAWLER;
} else if (userAgentHeader.contains("MSIE")) {
// Explorer Browser : http://msdn2.microsoft.com/en-us/library/ms537503.aspx
// Format: Mozilla/MozVer (compatible; MSIE IEVer[; Provider]; Platform[; Extension]*) [Addition]
// SampleTest: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Google Wireless Transcoder;)
// Parse version ...
int index = productDetails.indexOf("MSIE") + 4;
int lastIndex = productDetails.indexOf(';', index);
final String versionStr = productDetails.substring(index + 1, lastIndex);
parseVersion(versionStr);
// Explorer Parse ...
this.product = Product.EXPLORER;
this.hasGCFInstalled = productDetails.contains("chromeframe");
} else if (userAgentHeader.contains("iCab") || userAgentHeader.contains("Safari")) {
// Safari:
//Formats: Mozilla/5.0 (Windows; U; Windows NT 5.1; en) AppleWebKit/522.13.1 (KHTML, like Gecko) Version/3.0.2 Safari/522.13.1
//Chrome:
//Formats: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.44 Safari/534.7"
String versionStr = "";
if (userAgentHeader.contains("Chrome")) {
this.product = Product.CHROME;
versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Chrome") + 7, userAgentHeader.lastIndexOf(" "));
} else {
this.product = Product.SAFARI;
versionStr = userAgentHeader.substring(userAgentHeader.indexOf("Version") + 8, userAgentHeader.lastIndexOf(" "));
}
parseVersion(versionStr);
} else if (userAgentHeader.contains("Konqueror")) {
this.product = Product.KONQUEOR;
} else if (userAgentHeader.contains("KMeleon")) {
this.product = Product.KMELEON;
} else if (userAgentHeader.contains("Gecko")) {
// Firefox/Mozilla/Camino:
// Mozilla/MozVer (Platform; Security; SubPlatform; Language; rv:Revision[; Extension]*) Gecko/GeckVer [Product/ProdVer]
// SampleTest: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.5) Gecko/20050302 Firefox/0.9.6
// Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7 Creative ZENcast v1.02.08 FirePHP/0.0.5.13
// 'Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.7.12) Gecko/20050915'
// 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.7) Gecko/20070914 firefox 2.0'
// 'Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.6) Gecko/20060601 Firefox/2.0.0.6 (Ubuntu-edgy)'
// 'Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'
// "Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.12) Gecko/20080129 Iceweasel/2.0.0.12 (Debian-2.0.0.12-0etch1)
// Remove gecko string
// Debian Firefox is remamed to iceweasel.
productAddition = productAddition.replace("Iceweasel", "firefox");
productAddition = productAddition.substring(productAddition.indexOf(' ') + 1);
productAddition = productAddition.toLowerCase();
String prodDesc = null;
if (productAddition.contains("firefox")) {
this.product = Product.FIREFOX;
prodDesc = "firefox";
} else if (productAddition.contains("netscape")) {
this.product = Product.NETSCAPE;
prodDesc = "netscape";
} else if (productAddition.contains("camino")) {
this.product = Product.CAMINO;
prodDesc = "camino";
} else {
this.product = Product.MOZILLA;
// @todo: How it can get the mozilla vesion?
}
// Now, parse product version ...
if (prodDesc != null) {
int sI = productAddition.indexOf(prodDesc) + prodDesc.length() + 1;
int eI = productAddition.indexOf(' ', sI);
if (eI == -1) {
eI = productAddition.length();
}
final String productVersion = productAddition.substring(sI, eI);
parseVersion(productVersion);
}
} else if (userAgentHeader.contains("Opera")) {
// Opera:
// Samples: Opera/9.0 (Windows NT 5.1; U; en)
// Opera/8.5 (Macintosh; PPC Mac OS X; U; en)
// Mozilla/5.0 (Macintosh; PPC Mac OS X; U; en) Opera 8.5
// Mozilla/4.0 (compatible; MSIE 6.0; Mac_PowerPC Mac OS X; en) Opera 8.5
// Opera/9.21 (Windows NT 5.1; U; en)
this.product = Product.OPERA;
String productVersion;
if (application.startsWith("Opera")) {
productVersion = application.substring(application.indexOf('/') + 1, application.length());
} else {
productVersion = productAddition.substring(application.lastIndexOf(' ') + 1, application.length());
}
parseVersion(productVersion);
} else if (userAgentHeader.contains("4.7")) {
this.product = Product.NETSCAPE;
} else if (userAgentHeader.contains("Lynx")) {
this.product = Product.LYNX;
} else {
// It's a robot ..
for (String botAgent : botAgents) {
if (userAgentHeader.contains(botAgent)) {
// set a key in the session, so the next time we don't have to manually
// detect the robot again
this.product = Product.ROBOT;
break;
}
}
logger.info("UserAgent could not be detected: '" + userAgentHeader + "'");
}
} catch (Throwable e) {
logger.error("Could not detect the browser based on the user agent: '" + userAgentHeader + "'");
// Mark as an unsupported browser...
this.product = Product.ROBOT;
}
}
private OS parseOS(String details) {
OS result;
if (details.contains("Windows"))
result = OS.WINDOWS;
else if (details.contains("Mac") || details.contains("Macintosh"))
result = OS.MAC;
else if (details.contains("X11"))
result = OS.LINUX;
else
result = OS.KNOWN;
return result;
}
public static UserAgent create(final HttpServletRequest request) {
final String userAgent = request.getHeader(USER_AGENT_HEADER);
return new UserAgent(userAgent);
}
public static UserAgent create(final String userAgent) {
return new UserAgent(userAgent);
}
private void parseVersion(final String version) {
final int index = version.indexOf('.');
final String vm = version.substring(0, index);
final String vv = version.substring(index + 1, version.length());
this.versionMajor = Integer.parseInt(vm);
char c = vv.charAt(0);
this.versionVariation = Integer.valueOf(String.valueOf(c));
}
/**
* All known robot user-agent headers (list can be found
* <a href="http://www.robotstxt.org/wc/activel">here</a>).
* <p/>
* <p>NOTE: To avoid bad detection:</p>
* <p/>
* <ul>
* <li>Robots with ID of 2 letters only were removed</li>
* <li>Robot called "webs" were removed</li>
* <li>directhit was changed in direct_hit (its real id)</li>
* </ul>
*/
private static final String[] botAgents = {
"acme.spider", "ahoythehomepagefinder", "alkaline", "appie", "arachnophilia",
"architext", "aretha", "ariadne", "aspider", "atn.txt", "atomz", "auresys",
"backrub", "bigbrother", "bjaaland", "blackwidow", "blindekuh", "bloodhound",
"brightnet", "bspider", "cactvschemistryspider", "calif", "cassandra",
"cgireader", "checkbot", "churl", "cmc", "collective", "combine", "conceptbot",
"core", "cshkust", "cusco", "cyberspyder", "deweb", "dienstspider", "diibot",
"direct_hit", "dnabot", "download_express", "dragonbot", "dwcp", "ebiness",
"eit", "emacs", "emcspider", "esther", "evliyacelebi", "fdse", "felix",
"ferret", "fetchrover", "fido", "finnish", "fireball", "fish", "fouineur",
"francoroute", "freecrawl", "funnelweb", "gazz", "gcreep", "getbot", "geturl",
"golem", "googlebot", "grapnel", "griffon", "gromit", "gulliver", "hambot",
"harvest", "havindex", "hometown", "wired-digital", "htdig", "htmlgobble",
"hyperdecontextualizer", "ibm", "iconoclast", "ilse", "imagelock", "incywincy",
"informant", "infoseek", "infoseeksidewinder", "infospider", "inspectorwww",
"intelliagent", "iron33", "israelisearch", "javabee", "jcrawler", "jeeves",
"jobot", "joebot", "jubii", "jumpstation", "katipo", "kdd", "kilroy",
"ko_yappo_robot", "labelgrabber.txt", "larbin", "legs", "linkscan",
"linkwalker", "lockon", "logo_gif", "lycos", "macworm", "magpie", "mediafox",
"merzscope", "meshexplorer", "mindcrawler", "moget", "momspider", "monster",
"motor", "muscatferret", "mwdsearch", "myweb", "netcarta", "netmechanic",
"netscoop", "newscan-online", "nhse", "nomad", "northstar", "nzexplorer",
"occam", "octopus", "orb_search", "packrat", "pageboy", "parasite", "patric",
"perignator", "perlcrawler", "phantom", "piltdownman", "pioneer", "pitkow",
"pjspider", "pka", "plumtreewebaccessor", "poppi", "portalb", "puu", "python",
"raven", "rbse", "resumerobot", "rhcs", "roadrunner", "robbie", "robi",
"roverbot", "safetynetrobot", "scooter", "search_au", "searchprocess",
"senrigan", "sgscout", "shaggy", "shaihulud", "sift", "simbot", "site-valet",
"sitegrabber", "sitetech", "slurp", "smartspider", "snooper", "solbot",
"spanner", "speedy", "spider_monkey", "spiderbot", "spiderman", "spry",
"ssearcher", "suke", "sven", "tach_bw", "tarantula", "tarspider", "tcl",
"techbot", "templeton", "titin", "titan", "tkwww", "tlspider", "ucsd",
"udmsearch", "urlck", "valkyrie", "victoria", "visionsearch", "voyager",
"vwbot", "w3index", "w3m2", "wanderer", "webbandit", "webcatcher", "webcopy",
"webfetcher", "webfoot", "weblayers", "weblinker", "webmirror", "webmoose",
"webquest", "webreader", "webreaper", "websnarf", "webspider", "webvac",
"webwalk", "webwalker", "webwatch", "wget", "whowhere", "wmir", "wolp",
"wombat", "worm", "wwwc", "wz101", "xget", "nederland.zoek"
};
public boolean isBrowserSupported() {
// Is it a supported browser ?.
final UserAgent.Product product = this.getProduct();
boolean result = product == UserAgent.Product.FIREFOX && this.isVersionGreatedOrEqualThan(10, 0);
result = result || product == UserAgent.Product.EXPLORER && this.isVersionGreatedOrEqualThan(7, 0) && this.getOs() == UserAgent.OS.WINDOWS;
result = result || product == UserAgent.Product.OPERA && this.isVersionGreatedOrEqualThan(11, 0);
result = result || product == UserAgent.Product.CHROME && this.isVersionGreatedOrEqualThan(18, 0);
result = result || product == UserAgent.Product.SAFARI && this.isVersionGreatedOrEqualThan(5, 0);
result = result || product == Product.WEB_CRAWLER;
return result;
}
public boolean needsGCF() {
final UserAgent.Product product = this.getProduct();
return product == UserAgent.Product.EXPLORER && this.isVersionLessThan(9) && this.getOs() == UserAgent.OS.WINDOWS && !this.hasGCFInstalled;
}
}

View File

@@ -20,6 +20,7 @@ package com.wisemapping.mail;
import com.wisemapping.filter.UserAgent;
import com.wisemapping.model.Collaboration;
import com.wisemapping.model.CollaborationRole;
import com.wisemapping.model.Mindmap;
import com.wisemapping.model.User;
import org.apache.commons.io.IOUtils;
@@ -41,9 +42,10 @@ final public class NotificationService {
@Autowired
private Mailer mailer;
private String baseUrl;
private NotifierFilter notificationFilter;
public NotificationService() {
this.notificationFilter = new NotifierFilter();
}
public void newCollaboration(@NotNull Collaboration collaboration, @NotNull Mindmap mindmap, @NotNull User user, @Nullable String message) {
@@ -64,7 +66,7 @@ final public class NotificationService {
model.put("message", "message");
model.put("ownerName", user.getFirstname());
model.put("mapEditUrl", baseUrl + "/c/maps/" + mindmap.getId() + "/edit");
model.put("baseUrl", formMail);
model.put("baseUrl", baseUrl);
model.put("senderMail", user.getEmail());
model.put("message", message);
model.put("supportEmail", mailer.getSupportEmail());
@@ -141,14 +143,14 @@ final public class NotificationService {
}
public void sendRegistrationEmail(@NotNull User user) {
throw new UnsupportedOperationException("Not implemented yet");
// throw new UnsupportedOperationException("Not implemented yet");
// try {
// final Map<String, Object> model = new HashMap<String, Object>();
// model.put("user", user);
// final String activationUrl = "http://wisemapping.com/c/activation?code=" + user.getActivationCode();
// model.put("emailcheck", activationUrl);
// mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), "Welcome to Wisemapping!", model,
// "confirmationMail.vm");
// final Map<String, String> model = new HashMap<String, String>();
// model.put("email", user.getEmail());
//// final String activationUrl = "http://wisemapping.com/c/activation?code=" + user.getActivationCode();
//// model.put("emailcheck", activationUrl);
//// mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), "Welcome to Wisemapping!", model,
//// "confirmationMail.vm");
// } catch (Exception e) {
// handleException(e);
// }
@@ -156,22 +158,24 @@ final public class NotificationService {
public void reportJavascriptException(@NotNull Mindmap mindmap, @Nullable User user, @Nullable String jsErrorMsg, @NotNull HttpServletRequest request) {
final Map<String, Object> model = new HashMap<String, Object>();
final Map<String, String> model = new HashMap<String, String>();
model.put("errorMsg", jsErrorMsg);
try {
model.put("mapXML", StringEscapeUtils.escapeXml(mindmap.getXmlStr()));
} catch (UnsupportedEncodingException e) {
// Ignore ...
}
model.put("mapId", mindmap.getId());
model.put("mapId", Integer.toString(mindmap.getId()));
model.put("mapTitle", mindmap.getTitle());
sendNotification(model, user, request);
}
private void sendNotification(@NotNull Map<String, Object> model, @Nullable User user, @NotNull HttpServletRequest request) {
private void sendNotification(@NotNull Map<String, String> model, @Nullable User user, @NotNull HttpServletRequest request) {
model.put("fullName", (user != null ? user.getFullName() : "'anonymous'"));
model.put("email", (user != null ? user.getEmail() : "'anonymous'"));
final String userEmail = user != null ? user.getEmail() : "'anonymous'";
model.put("email", userEmail);
model.put("userAgent", request.getHeader(UserAgent.USER_AGENT_HEADER));
model.put("server", request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort());
model.put("requestURI", request.getRequestURI());
@@ -181,8 +185,11 @@ final public class NotificationService {
try {
final String errorReporterEmail = mailer.getErrorReporterEmail();
if (errorReporterEmail != null && !errorReporterEmail.isEmpty()) {
mailer.sendEmail(mailer.getServerSenderEmail(), errorReporterEmail, "[WiseMapping] Bug from '" + (user != null ? user.getEmail() + "'" : "'anonymous'"), model,
"errorNotification.vm");
if (!notificationFilter.hasBeenSend(userEmail, model)) {
mailer.sendEmail(mailer.getServerSenderEmail(), errorReporterEmail, "[WiseMapping] Bug from '" + (user != null ? user.getEmail() + "'" : "'anonymous'"), model,
"errorNotification.vm");
}
}
} catch (Exception e) {
handleException(e);
@@ -190,7 +197,7 @@ final public class NotificationService {
}
public void reportJavaException(@NotNull Throwable exception, @Nullable User user, @NotNull String content, @NotNull HttpServletRequest request) {
final Map<String, Object> model = new HashMap<String, Object>();
final Map<String, String> model = new HashMap<String, String>();
model.put("errorMsg", stackTraceToString(exception));
model.put("mapXML", StringEscapeUtils.escapeXml(content));
@@ -198,7 +205,7 @@ final public class NotificationService {
}
public void reportJavaException(@NotNull Throwable exception, @Nullable User user, @NotNull HttpServletRequest request) {
final Map<String, Object> model = new HashMap<String, Object>();
final Map<String, String> model = new HashMap<String, String>();
model.put("errorMsg", stackTraceToString(exception));
sendNotification(model, user, request);

View File

@@ -0,0 +1,35 @@
package com.wisemapping.mail;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.DigestUtils;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
public class NotifierFilter {
public static final int MAX_CACHE_ENTRY = 500;
private final Map<String, String> emailByMd5 = Collections.synchronizedMap(new LinkedHashMap<String, String>() {
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_CACHE_ENTRY;
}
});
public boolean hasBeenSend(@NotNull final String email, @NotNull final Map<String, String> model) {
final StringBuilder buff = new StringBuilder();
for (String key : model.keySet()) {
buff.append(key);
buff.append("=");
buff.append(model.get(key));
}
final String digest = DigestUtils.md5DigestAsHex(buff.toString().getBytes());
boolean result = emailByMd5.containsKey(digest);
if (!result) {
emailByMd5.put(digest, email);
}
return result;
}
}

View File

@@ -29,7 +29,7 @@ public class NotifyingExceptionResolver extends SimpleMappingExceptionResolver {
}
private void sendNotification(@NotNull Exception ex, @NotNull HttpServletRequest request) {
final User user = Utils.getUser();
final User user = Utils.getUser(false);
notificationService.reportJavaException(ex, user, request);
}

View File

@@ -18,6 +18,7 @@
package com.wisemapping.model;
import com.wisemapping.exceptions.AccessDeniedSecurityException;
import com.wisemapping.exceptions.WiseMappingException;
import com.wisemapping.util.ZipUtils;
import org.apache.commons.lang.StringEscapeUtils;
@@ -233,7 +234,7 @@ public class Mindmap {
final Collaboration collaboration = this.findCollaboration(collaborator);
if (collaboration == null) {
throw new WiseMappingException("User is not collaborator");
throw new AccessDeniedSecurityException("Collaborator " + collaborator.getEmail() + " could not access " + this.getId());
}
return collaboration.getCollaborationProperties();
}

View File

@@ -137,10 +137,16 @@ public class UsersController {
final String challenge = request.getParameter("recaptcha_challenge_field");
final String uresponse = request.getParameter("recaptcha_response_field");
final String remoteAddr = request.getRemoteAddr();
final ReCaptchaResponse reCaptchaResponse = captchaService.checkAnswer(remoteAddr, challenge, uresponse);
if (!reCaptchaResponse.isValid()) {
bindingResult.rejectValue("captcha", Messages.CAPTCHA_ERROR);
if (challenge != null && uresponse != null) {
final String remoteAddr = request.getRemoteAddr();
final ReCaptchaResponse reCaptchaResponse = captchaService.checkAnswer(remoteAddr, challenge, uresponse);
if (!reCaptchaResponse.isValid()) {
bindingResult.rejectValue("captcha", Messages.CAPTCHA_ERROR);
}
} else {
bindingResult.rejectValue("captcha", Messages.CAPTCHA_LOADING_ERROR);
}
}
return bindingResult;

View File

@@ -60,7 +60,7 @@ public class AdminController extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = "admin/users", consumes = {"application/xml", "application/json"}, produces = {"application/json", "text/html", "application/xml"})
@ResponseStatus(value = HttpStatus.CREATED)
public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws IOException, WiseMappingException {
public void createUser(@RequestBody RestUser user, HttpServletResponse response) throws WiseMappingException {
if (user == null) {
throw new IllegalArgumentException("User could not be found");
}
@@ -90,7 +90,7 @@ public class AdminController extends BaseController {
@RequestMapping(method = RequestMethod.PUT, value = "admin/users/{id}/password", consumes = {"text/plain"})
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void changePassword(@RequestBody String password, @PathVariable long id) throws IOException, WiseMappingException {
public void changePassword(@RequestBody String password, @PathVariable long id) throws WiseMappingException {
if (password == null) {
throw new IllegalArgumentException("Password can not be null");
}
@@ -105,7 +105,7 @@ public class AdminController extends BaseController {
@RequestMapping(method = RequestMethod.DELETE,value = "admin/users/{id}")
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void getUserByEmail(@PathVariable long id) throws IOException, WiseMappingException {
public void getUserByEmail(@PathVariable long id) throws WiseMappingException {
final User user = userService.getUserBy(id);
if (user == null) {
throw new IllegalArgumentException("User '" + id + "' could not be found");

View File

@@ -18,8 +18,7 @@
package com.wisemapping.rest;
import com.wisemapping.exceptions.AccessDeniedSecurityException;
import com.wisemapping.filter.UserAgent;
import com.wisemapping.exceptions.ClientException;
import com.wisemapping.mail.NotificationService;
import com.wisemapping.model.User;
import com.wisemapping.rest.model.RestErrors;
@@ -27,6 +26,7 @@ import com.wisemapping.security.Utils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -36,6 +36,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Locale;
public class BaseController {
@@ -66,22 +67,30 @@ public class BaseController {
return ex.getMessage();
}
@ExceptionHandler(ValidationException.class)
@ExceptionHandler(JsonHttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public RestErrors handleValidationErrors(@NotNull ValidationException ex) {
return new RestErrors(ex.getErrors(), messageSource);
public String handleValidationErrors(@NotNull JsonHttpMessageNotReadableException ex) {
return "Request could not be saved. Message is not valid";
}
@ExceptionHandler(java.lang.reflect.UndeclaredThrowableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public RestErrors handleSecurityErrors(@NotNull UndeclaredThrowableException ex) {
return new RestErrors(ex.getMessage());
final Throwable cause = ex.getCause();
RestErrors result;
if (cause instanceof ClientException) {
result = handleClientErrors((ClientException) cause);
} else {
result = new RestErrors(ex.getMessage());
}
return result;
}
@ExceptionHandler(com.wisemapping.exceptions.AccessDeniedSecurityException.class)
@ExceptionHandler(ClientException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public RestErrors handleSecurityException(@NotNull AccessDeniedSecurityException ex) {
return new RestErrors(ex.getMessage());
public RestErrors handleClientErrors(@NotNull ClientException ex) {
final Locale locale = LocaleContextHolder.getLocale();
return new RestErrors(ex.getMessage(messageSource, locale));
}
}

View File

@@ -0,0 +1,51 @@
package com.wisemapping.rest;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class DebugMappingJacksonHttpMessageConverter extends MappingJacksonHttpMessageConverter {
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, JsonHttpMessageNotReadableException {
final byte[] bytes = IOUtils.toByteArray(inputMessage.getBody());
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
final WrapHttpInputMessage wrap = new WrapHttpInputMessage(bais, inputMessage.getHeaders());
try {
return super.readInternal(clazz, wrap);
} catch (org.springframework.http.converter.HttpMessageNotReadableException e) {
throw new JsonHttpMessageNotReadableException("Request Body:\n" + new String(bytes, "UTF-8"), e);
}
catch (IOException e) {
throw new JsonHttpMessageNotReadableException("Request Body:\n" + new String(bytes, "UTF-8"), e);
}
}
}
class WrapHttpInputMessage implements HttpInputMessage {
private InputStream body;
private HttpHeaders headers;
WrapHttpInputMessage(InputStream is, HttpHeaders headers) {
this.body = is;
this.headers = headers;
}
@Override
public InputStream getBody() throws IOException {
return body;
}
@Override
public HttpHeaders getHeaders() {
return headers;
}
}

View File

@@ -0,0 +1,8 @@
package com.wisemapping.rest;
class JsonHttpMessageNotReadableException extends org.springframework.http.converter.HttpMessageNotReadableException {
public JsonHttpMessageNotReadableException(String msg, Exception cause) {
super(msg, cause);
}
}

View File

@@ -30,7 +30,7 @@ public class RestErrors {
private Errors errors;
@JsonIgnore
private List<String> globalErrors;
private List<String> gErrors;
@JsonIgnore
MessageSource messageSource;
@@ -43,12 +43,12 @@ public class RestErrors {
this.errors = errors;
this.messageSource = messageSource;
this.globalErrors = this.processGlobalErrors(errors, messageSource);
this.gErrors = this.processGlobalErrors(errors, messageSource);
}
public RestErrors(@NotNull String errorMsg) {
globalErrors = new ArrayList<String>();
globalErrors.add(errorMsg);
gErrors = new ArrayList<String>();
gErrors.add(errorMsg);
}
private List<String> processGlobalErrors(@NotNull Errors errors, @NotNull MessageSource messageSource) {
@@ -61,7 +61,7 @@ public class RestErrors {
}
public List<String> getGlobalErrors() {
return globalErrors;
return gErrors;
}
public void setGlobalErrors(List<String> list) {

View File

@@ -26,4 +26,5 @@ public interface Messages {
String MAP_TITLE_ALREADY_EXISTS = "MAP_TITLE_ALREADY_EXISTS";
String PASSWORD_MISSMATCH = "PASSWORD_MISSMATCH";
String CAPTCHA_ERROR = "CAPTCHA_ERROR";
String CAPTCHA_LOADING_ERROR = "CAPTCHA_LOADING_ERROR";
}

View File

@@ -145,8 +145,6 @@ MAP_NAME_HINT=Name of the new map to create
MAP_DESCRIPTION_HINT=Some description for your map
WARNING=Warning
DELETE_MAPS_WARNING=Deleted mindmap can not be recovered. Do you want to continue ?.
WHAT_IS_NEW=What is New
WHAT_IS_NEW_DETAILS=<ul><li>New User Interface</li><li>FreeMind 0.9 Update</li><li>Improved HTML 5.0 Support</li><li>Firefox 12 officially supported</li></ul>
THANKS_FOR_SIGN_UP=Thanks for signing up\!
SIGN_UP_CONFIRMATION_EMAIL=\ You will receive a confirmation message shortly from WiseMapping. This message will ask you to activate your WiseMapping account.</br>Please select the link to activate and start creating and sharing maps.
SIGN_UP_SUCCESS=Your account has been created successfully, click <a href\="c/login">here</a> to sign in and start enjoying WiseMapping.
@@ -241,6 +239,13 @@ SUPPORT=Support
FEEDBACK=Feedback
CONTACT_US=Contact Us
#Pending for translation ...
CAPTCHA_LOADING_ERROR=ReCaptcha could not be loaded. You must have access to Google ReCaptcha service.
ACCESS_HAS_BEEN_REVOKED= Upps. your access permissions to this map has been revoked. Contact map owner.
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>.

View File

@@ -29,7 +29,7 @@ FORGOT_PASSWORD=Se olvidó la contraseña ?
CHANGE_PASSWORD=Cambiar la Contraseña
FAQ=Preguntas Frecuentes
SHORT_FAQ=FAQ
LOGIN=Entrar
LOGIN=Ingresar
MIND_FILE=Archivo
EXPORT=Exportar
SVG_EXPORT_FORMAT=Scalable Vector Graphics (SVG)
@@ -142,8 +142,6 @@ MAP_NAME_HINT=El nombre del nuevo mapa
MAP_DESCRIPTION_HINT=Una descripción de tu mapa
WARNING=Cuidado
DELETE_MAPS_WARNING=Una vez borrado de un mapa no puede ser recuperado. Desea continuar ?
WHAT_IS_NEW=Novedades
WHAT_IS_NEW_DETAILS=<ul><li>Nueva interfaz</li><li>Soporte de FreeMind 0.9</li><li>Soporte HTML 5.0</li><li>Soporte de Firefox 12</li></ul>
THANKS_FOR_SIGN_UP=Graciar por registarse !
SIGN_UP_CONFIRMATION_EMAIL=You will receive a confirmation message shortly from WiseMapping. This message will ask you to activate your WiseMapping account.</br>Please select the link to activate and start creating and sharing maps.
SIGN_UP_SUCCESS=Su cuenta ha sido creada exitosamente,haga click <a href\="c/login">acá</a> para ingresar y empezar a disfrutar de WiseMapping.
@@ -241,3 +239,11 @@ FEEDBACK=Feedback
CONTACT_US=Contáctenos
ACCESS_HAS_BEEN_REVOKED=Los permisos de acceso al mapa han sido revocados. No es posible grabar sus cambios.
CAPTCHA_LOADING_ERROR=ReCaptcha no pudo ser cargado. Debes tener accesso al servicio de Google ReCaptcha.
LICENSE=Licencia
WELCOME_TO_WISEMAPPING=Bienvenido a WiseMapping
WELCOME_DETAILS=WiseMapping te permite crear y leer tus mapas mentales en cualquier lugar. Con WiseMapping tu puedes: <ul><li>Embeber tus mapas en páginas o blogs</li><li>Crear vinculos a documentos</li><li>Compartir tus mapas mentales con amigos y colegas</li><li>Exportar tus mapas a SVG,PNG,JPG and FreeMind</li></ul>.

View File

@@ -1,4 +1,10 @@
# Default french Support. Traduction René Amberg 2012/08/31
# Default french Support. Traduction René Amberg 2012/08/31 - release b 2012/09/03
# release b notes :
# (159) 'misae' replaced by 'mise' , 'de 5.0' replaced by 'de HTML 5.0';
# (195) 'Show _MENU_ entries' original english text (= script ?) replaces translated text 'Montrer les entrées de MENU'(meaningless...)
# (223) 'mMdalités' replaced by 'Modalités'
# (221) 'neouds' replaced by 'noeuds'
# (201-219) all texts translated : these lines are items of 'shortcuts' list (and not scripts)
NAME=Nom
DESCRIPTION=Description
@@ -90,7 +96,7 @@ RENAME=Renommer
MAX_CHARACTER_SIZE= Longueur maximale des messages 512 caractères.
URL=URL
DIRECT_LINK=Lien direct
BLOG_INCLUSION=Vous pouvez personnaliser ce morceau de code pour incruster cette carte sur votre blog ou votre site. Vérifiez les dimensions de la zone de contenu, de manière à obtenir une bonne mise enpage de la carte.
BLOG_INCLUSION=Vous pouvez personnaliser ce morceau de code pour incruster cette carte sur votre blog ou votre site. Vérifiez les dimensions de la zone de contenu, de manière à obtenir une bonne mise en page de la carte.
BLOG_SNIPPET=Copier ce morceau de code pour incruster cette carte sur votre blog ou votre page
ZOOM=Zoom
HISTORY=Historique
@@ -98,12 +104,12 @@ SHARE=Partager
UNEXPECTED_ERROR=Aïe!!. Une erreur inattendue est survenue.
UNEXPECTED_ERROR_DETAILS=Désolé, une erreur s'est produite et nous ne pouvons pas exécuter votre demande. Essayez à nouveau, ou retournez à la page d'accueil.
UNEXPECTED_ERROR_SERVER_ERROR=Désolé, une erreur s'est produite et nous ne pouvons pas exécuter votre demande. Rafraîchissez la page et essayez à nouveau. Si le problème persiste, contactez-nous à support@wisemapping.com
NO_ENOUGH_PERMISSIONS=Aïe!!. Cette carte n'est plus accessible.
NO_ENOUGH_PERMISSIONS=Aïe!!. Cette carte n'est plus accessible.
NO_ENOUGH_PERMISSIONS_DETAILS=Vous n'avez pas les droits d'accès suffisants pour voir cette carte. Cette carte est devenue privée, ou a été détruite.
IMPORT_MINDMAP_INFO=Vous pouvez importer des cartes FreeMind 0.9 et WiseMapping dans votre liste de cartes. Choisissez le fichier à importer.
PRINT=Imprimer
IMPORT_MAP_ERROR=Le fichier FreeMind n'a pas pu être importé. {0}
MAP_TITLE_ALREADY_EXISTS=Vous avez déjà une carte portant le même nom.
MAP_TITLE_ALREADY_EXISTS=Vous avez déjà une carte portant le même nom.
#####FOOTER
COPYRIGHT=Propulsé par WiseMapping
TERMS_AND_CONDITIONS=Clauses et Conditions
@@ -114,12 +120,12 @@ ACCOUNT_ACTIVED_FAIL = L'activation du compte a échoué
NO_HISTORY_RESULTS= Pas d'historique disponible.
REVERT=Inverser
INVALID_EMAIL_ERROR = L'email n'a pas été confirmé
NO_PRODUCTION_DATABASE_CONFIGURED=Bin que HSQLDB soit inclus avec WiseMapping par défaut durant l'installation, nous ne recommendons pas cette base de données en production. Nevisagez plutôt MySQL 5.5. Vous pouvez trouver comment configurer MySQL.
NO_PRODUCTION_DATABASE_CONFIGURED=Bien que HSQLDB soit inclus avec WiseMapping par défaut durant l'installation, nous ne recommendons pas cette base de données en production. Nevisagez plutôt MySQL 5.5. Vous pouvez trouver comment configurer MySQL.
IMPORT=Importer
EMBEDDED_MAP_SIZE=* Note: vous pouvez changer le format de la carte encapsulée en modifiant les propriétés de style 'height' et 'width'. Vous pouvez aussi modifier le facteur de zoom par le paramètre 'zoom' de l'URL.
EXPORT_FORMAT_RESTRICTIONS=Exporter vers Image, PDF ou SVG n'est possible que depuis la barre d'outils de l'éditeur.
STARRED=Etoilé (*)
STARRED=Favoris
ALL_MAPS=Toutes les cartes
MY_MAPS=Mes cartes
SHARED_WITH_ME=Partagées avec moi
@@ -130,7 +136,7 @@ INFO=Info
DELETE_MINDMAP=Effacer la carte
DUPLICATE=Dupliquer
CREATE=Créer
LANGUAGE=Language
LANGUAGE=Langue
FILTERS=Filtre
MORE=Plus
ADD_NEW_MAP=Ajouter nouvelle carte
@@ -145,8 +151,6 @@ MAP_NAME_HINT=Nom de la nouvelle carte à créer
MAP_DESCRIPTION_HINT=Brève description de votre carte
WARNING=Avertissement
DELETE_MAPS_WARNING=Une carte effacée ne peut pas être récupérée. Voulez-vous continuer ?
WHAT_IS_NEW=Quoi de neuf
WHAT_IS_NEW_DETAILS=<ul><li>Nouvel interface utilisateur </li><li>Misae à jour FreeMind 0.9 </li><li> Support amélioré de 5.0 </li><li>Firefox 12 officiellement supporté</li></ul>
THANKS_FOR_SIGN_UP=Merci de vous inscrire \!
SIGN_UP_CONFIRMATION_EMAIL=\ Vous recevrez prochainement un bref message de confirmation de WiseMapping. Ce message vous demandera d'activer votre compte WiseMapping. </br> SVP suivez le lien pour activer commencer à créer et partager vos cartes.
SIGN_UP_SUCCESS=Votre compte a été créé, cliquez <a href\="c/login">here</a> pour vous connecter et commencer à apprécier WiseMapping.
@@ -182,41 +186,41 @@ BROWSER_NOT_SUPPORTED_TRY_AGAIN=Essayez à nouveau avec un des navigateurs séle
INSTALL_CFG=Désloé, Microsoft Internet Explorer 8 n'est que partiellement compatible
INSTALL_CFG_REASON = Microsoft Internet Explorer 8 n'est pas compatible avec le format SVG HTML 5. SVG est le format utilisé par WiseMapping pour afficher et éditer les cartes. Nous recommandons fortement, soit de mettre à jour vers Microsoft Internet Explorer 9, ou d'utiliser plutôt un navigateur comme Google Chrome, Firefox ou Safari.
INSTALL_CFG_CLICK_HERE=Si vous continuez à utiliser votre vieux Microsoft Internet Explorer 8, cliquez ici pour installer l'extension Google Chrome Frame Plugin, qui va étendre les capacités de Internet Explorer à fonctionner avec HTML 5.
SHOW_REGISTERS=Montrer les entrées de MENU
SHOW_REGISTERS=Show _MENU_ entries
LOADING=Chargement ...
NO_MATCHING_FOUND=Pas d'enregistrements conformes
# BEGIN Translator interrogations : lines below might be scripting parameters or instructions ?
TABLE_ROWS=\ _START_-_END_ of _TOTAL_
ACTION=Action
CREATE_SIBLING_TOPIC=Create Sibling Topic
CREATE_CHILD_TOPIC=Create Child Topic
DELETE_TOPIC=Delete Topic
EDIT_TOPIC_TEXT=Edit Topic Text
JUST_START_TYPING=Just start typing
CANCEL_TEXT_CHANGES=Cancel Text Changes
TOPIC_NAVIGATION=Topic Navigation
ARROW_KEYS=Arrow Keys
SELECT_MULTIPLE_NODES=Select Multiple Nodes
UNDO_EDITION=Undo Edition
REDO_EDITION=Redo Edition
SELECT_ALL_TOPIC=Select All Topic
CHANGE_TEXT_BOLD=Change Text Bold Type
SAVE_CHANGES=Save Changes
CHANGE_TEXT_ITALIC=Change Text Italic
DESELECT_ALL_TOPIC=Deselect All Topic
SHORTCUTS=Shortcuts
COLLAPSE_CHILDREN=Collapse Children
# END Translator interrogations
ACTION=Action
CREATE_SIBLING_TOPIC=Créer noeud même niveau
CREATE_CHILD_TOPIC=Créer noeud enfant
DELETE_TOPIC=Détruire noeud
EDIT_TOPIC_TEXT=Editer texte du noeud
JUST_START_TYPING=Commencer saisie
CANCEL_TEXT_CHANGES=Annuler changement texte
TOPIC_NAVIGATION=Navigation sur les noeuds
ARROW_KEYS=Touches flèches
SELECT_MULTIPLE_NODES=Selection multiple de noeuds
UNDO_EDITION=Annuler édition
REDO_EDITION=Refaire édition
SELECT_ALL_TOPIC=Sélection tous noeuds
CHANGE_TEXT_BOLD=Caractères en gras
SAVE_CHANGES=Enregistrer changements
CHANGE_TEXT_ITALIC=Caractères en italique
DESELECT_ALL_TOPIC=Deselection tous noeuds
SHORTCUTS=Raccourcis
COLLAPSE_CHILDREN=Fermer enfants
KEYBOARD_SHORTCUTS_MSG=Les raccourcis clavier vous font gagner du temps, en vous permettant de garder les mains sur le clavier sans utiliser la souris.
COPY_AND_PASTE_TOPICS=Copier et coller les neouds
COPY_AND_PASTE_TOPICS=Copier et coller les noeuds
MULTIPLE_LINES=Ajouter plusieurs lignes de texte
TERM_OF_USE=mMdalités et conditions
TERM_OF_USE=Modalités et conditions
# Properties used on the tutorial mindmap ....
TUTORIAL.MULTIPLE_TEXT_STYLES=Multiples Styles de Texte
TUTORIAL.DIFFERENT_SHAPES=Differentes Formes
TUTORIAL.FANCY_ICONS=Icônes fantaisie
TUTORIAL.MOVE_WITH_ARROWS=Se déplacer entre les oeuds avec les flèches
TUTORIAL.MOVE_WITH_ARROWS=Se déplacer entre les noeuds avec les flèches
TUTORIAL.START_TYPING_TO_EDIT_TEXT=Pour éditer, commencer à taper du texte
TUTORIAL.CTRL_TO_ADD_CHILD=Appuyer sur Ctrl/Meta+Enter pour ajouter un noeud enfant
TUTORIAL.ENTER_TO_ADD_SIBLING=Appuyer sur Enter pour ajouter un noeud de même niveau
@@ -239,12 +243,14 @@ TUTORIAL.FONT_COLOR=Couleurs de caractères
TUTORIAL.FONT_STYLE=Styles de caractères
TUTORIAL.FONT_TYPE=Types de caractères
TUTORIAL.SAMPLE_NOTE=Ceci est une simple note !.
SUPPORT=Aider
FEEDBACK=Réaction
CONTACT_US=Contactez-nous
CAPTCHA_LOADING_ERROR=ReCaptcha could not be loaded. You must have access to Google ReCaptcha service.
ACCESS_HAS_BEEN_REVOKED= Upps. your access permissions to this map has been revoked. Contact map owner.
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>.

View File

@@ -145,8 +145,6 @@ MAP_NAME_HINT=Nome della nuova mappa da creare
MAP_DESCRIPTION_HINT=Una descrizione della nuova mappa
WARNING=Attenzione
DELETE_MAPS_WARNING=Eliminando la mappa, non può essere più recuperata. Si desidera continuare?
WHAT_IS_NEW=Cosa c'è di nuovo
WHAT_IS_NEW_DETAILS=<ul><li>Nuova interfaccia utente</li><li>Aggiornamento FreeMind 0.9</li><li>Migliore Supporto HTML 5.0</li><li>Firefox 12 ufficialmente supportato</li></ul>
THANKS_FOR_SIGN_UP=Grazie per esserti registrato\!
SIGN_UP_CONFIRMATION_EMAIL=\ Riceverete un messaggio di conferma da WiseMapping. Questo messaggio vi chiederà di attivare il nuovo account WiseMapping.</br>Selezionare il link per attivare l'account ed iniziare a creare e condividere le tue mappe.
SIGN_UP_SUCCESS=Il tuo account è stato creato correttamente, clicca <a href\="c/login">qui</a> per entrare ed iniziare ad usare WiseMapping.

View File

@@ -143,8 +143,6 @@ MAP_NAME_HINT=Nome do novo mapa para criar
MAP_DESCRIPTION_HINT=Alguma descrição para o seu mapa
WARNING=Alerta
DELETE_MAPS_WARNING=Mapa mental deletado não poderá ser recuperado. Quer continuar?
WHAT_IS_NEW=O que há de Novo
WHAT_IS_NEW_DETAILS=<ul><li>Nova Interface com o Usuário</li><li>Atualização para o FreeMind 0.9</li><li>Suporte a HTML 5.0 Melhorado</li><li>Firefox 12 é oficialmente suportado</li></ul>
THANKS_FOR_SIGN_UP=Obrigado por acessar\!
SIGN_UP_CONFIRMATION_EMAIL=\ Você receberá uma mensagem de confirmação do WiseMapping em breve. Esta mensagem vai pedir que você ative sua conta WiseMapping.</br>SElecione o link para ativar e comece criando e compartilhando mapas.
SIGN_UP_SUCCESS=Sua conta foi criada com sucesso, clique <a href\="c/login">aqui</a> para acessar e comece a desfrutar do WiseMapping.

View File

@@ -145,8 +145,6 @@ MAP_NAME_HINT=新思路图的名字
MAP_DESCRIPTION_HINT=一些有关你的图的描述
WARNING=警告
DELETE_MAPS_WARNING=删除思维导图后无法恢复,是否继续?
WHAT_IS_NEW=新特性是什么
WHAT_IS_NEW_DETAILS=<ul><li>新用户界面</li><li>FreeMind 0.9 更新</li><li>改进HTML 5.0 支持</li><li>Firefox 12 正式支持</li></ul>
THANKS_FOR_SIGN_UP=感谢注册!
SIGN_UP_CONFIRMATION_EMAIL=\ 你不久将收到从WiseMapping发来的一封确认信息. 这个消息将询问你是否激活你的WiseMapping 账户。</br>请选择链接激活账户,开始创建思路图并分享它们吧。
SIGN_UP_SUCCESS=你的帐户已成功建立, 点击 <a href\="c/login">这里</a> 登录使用WiseMapping.

View File

@@ -145,8 +145,6 @@ MAP_NAME_HINT=新思路圖的名字
MAP_DESCRIPTION_HINT=一些有關你的圖的描述
WARNING=警告
DELETE_MAPS_WARNING=刪除思維導圖後無法恢復,是否繼續?
WHAT_IS_NEW=新特性是什麼
WHAT_IS_NEW_DETAILS=<ul><li>新用戶介面</li><li>FreeMind 0.9 更新</li><li>改進HTML 5.0 支持</li><li>Firefox 12 正式支持</li></ul>
THANKS_FOR_SIGN_UP=感謝註冊!
SIGN_UP_CONFIRMATION_EMAIL=\ 你不久將收到從WiseMapping發來的一封確認資訊. 這個消息將詢問你是否啟動你的WiseMapping 帳戶。</br>請選擇鏈接啟動帳戶,開始創建思路圖並分享它們吧。
SIGN_UP_SUCCESS=你的帳戶已成功建立, 點擊 <a href\="c/login">這裏</a> 登錄使用WiseMapping.

View File

@@ -4,7 +4,7 @@
##################################################################################
# MySQL 5.X configuration properties
#database.url=jdbc:mysql://localhost/wisemapping
#database.url=jdbc:mysql://localhost/wisemapping?useUnicode=yes&characterEncoding=UTF-8
#database.driver=com.mysql.jdbc.Driver
#database.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
#database.username=wisemapping
@@ -80,7 +80,7 @@ google.recaptcha.publicKey = 6LeQ4tISAAAAALzCGKNgRv8UqsDx7Cb0vq4wbJBr
admin.user = admin@wisemapping.org
# Site URL. This url will be used during sharing emails and public views.
site.baseurl = http://localhost:8080
site.baseurl = http://localhost:8080/wisemapping
# Site Homepage URL. This will be used as URL for homepage location.
site.homepage = c/home

View File

@@ -14,7 +14,12 @@
<context:component-scan base-package="com.wisemapping.rest"/>
<context:annotation-config/>
<mvc:annotation-driven/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="com.wisemapping.rest.DebugMappingJacksonHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
@@ -98,7 +103,6 @@
<constructor-arg ref="notificationService"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>

View File

@@ -137,10 +137,6 @@ input#selectAll {
/* ----------------------------- Misc ----------------------------------- */
.messagesPanel {
width: @body-width;
}
.dataTables_empty {
text-align: center;
}
@@ -149,13 +145,13 @@ input#selectAll {
background-color: #f5f5f5;
}
#buttonsToolbar {
margin: 30px 0px 10px 0px
.buttonsToolbar {
margin: 40px 0px 10px 0px
}
#tableActions {
float: right;
width: 350px;
padding-bottom: 10px;
white-space: nowrap;
}
@@ -171,16 +167,13 @@ input#selectAll {
}
#tableFooter {
width: 100%;
height: 50px;
white-space: nowrap;
}
#foldersContainer {
width: 15%;
float: left;
margin-right: 2%;
margin-top: 80px
padding-top: 60px;
}
span.starredOff {
@@ -205,8 +198,4 @@ span.starredOn:hover {
abbr[title] {
cursor: default;
}
#footer {
border-top: 0px;
}

View File

@@ -83,7 +83,6 @@ div#headerTitle {
margin-left: 5px;
}
span#headerSubTitle {
font-weight: lighter;
font-size: 12px;
@@ -100,31 +99,20 @@ div#headerButtons activelink a, div#headerButtons activelink a:hover {
border-bottom: 0;
}
#footer {
width: 100%;
border-top: 1px solid #8e9181;
text-align: center;
font-size: 90%;
padding-top:5px;
min-height:40px;
border-top: 1px black solid;
padding-top: 15px;
}
#footer > div{
display: inline-block;
}
div#paypal {
float: left;
margin: -29px;
}
#headerLogo {
cursor: pointer;
}
div#headerActions {
padding-right: 8px;
padding-top: 4px;
@@ -135,7 +123,7 @@ div#headerActions {
}
#headerActions span {
border-bottom: 3px solid #F7C931;
border-bottom: 3px solid #F7C931;
}
div#headerActions a:hover, div#headerActions a:active, div#headerActions a:link, div#headerActions a:visited {

View File

@@ -1,131 +1,111 @@
@import "../bootstrap/css/bootstrap.min.css";
@import "../bootstrap/css/bootstrap-responsive.min.css";
@import "pageHeaders.css";
#loginContent .loginNews {
float: left;
width: 300px;
}
div#login {
float: right;
width: 300px;
}
div#loginContent {
width: 100%;
min-height: 340px;
}
div#register {
position: relative;
margin: 10px auto;
width: 800px;
text-align: center;
white-space: nowrap;
}
div#register a {
color: #003399;
font-weight: bold;
}
div.pageBodyContent ol {
margin-left: 12px;
}
div.pageBodyContent ul {
list-style-position: outside;
}
div.pageBodyContent ol li {
list-style-type: decimal;
}
div.pageBody {
margin: 10px auto;
width: 800px;
min-height: 500px;
}
div.pageBodyContent {
padding-top: 30px;
}
div.pageBodyContent h1 {
color: #093A9D;
font-size: 150%;
margin-bottom: 5px;
font-weight: bold;
}
div.pageBodyContent h2 {
color: gray;
font-size: 150%;
border-bottom: 1px dashed #BBB4D6;
margin: 20px 0;
}
div.pageBodyContent ul {
padding: 5px;
}
div.pageBodyContent li {
list-style-type: disc;
margin-left: 12px;
}
/*-- End Main Page Style -- */
/* Share Styles */
#userEmails {
float: left;
width: 50%;
padding: 5px;
}
#userEmails textarea {
width: 100%;
}
#currentUsers {
float: left;
width: 40%;
height: 400px;
padding: 5px;
padding-left: 15px;
margin-left: 15px;
border-left: 1px dotted gray;
}
#currentUsers table {
width: 100%;
}
#invitation {
border: 1px dotted gray;
}
span.errorMsg{
color: red;
}
div.fform {
background: #eeeeee;
border: 1px solid #cfcfcf;
padding: 5px 25px;
-moz-border-radius: 8px;
-khtml-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
div.fform label {
font-weight: bold;
}
@import "../bootstrap/css/bootstrap.min.css";
@import "../bootstrap/css/bootstrap-responsive.min.css";
@import "pageHeaders.css";
div#register {
margin: 40px auto;
text-align: center;
white-space: nowrap;
}
div#register a {
color: #003399;
font-weight: bold;
}
div.pageBodyContent ol {
margin-left: 12px;
}
div.pageBodyContent ul {
list-style-position: outside;
}
div.pageBodyContent ol li {
list-style-type: decimal;
}
div.pageBody {
min-height: 500px;
}
div.pageBodyContent {
padding-top: 30px;
}
div.pageBodyContent h1 {
color: #093A9D;
font-size: 150%;
margin-bottom: 5px;
font-weight: bold;
}
div.pageBodyContent h2 {
color: gray;
font-size: 150%;
border-bottom: 1px dashed #BBB4D6;
margin: 20px 0;
}
div.pageBodyContent ul {
padding: 5px;
}
div.pageBodyContent li {
list-style-type: disc;
margin-left: 12px;
}
/*-- End Main Page Style -- */
/* Share Styles */
#userEmails {
float: left;
width: 50%;
padding: 5px;
}
#userEmails textarea {
width: 100%;
}
#currentUsers {
float: left;
width: 40%;
height: 400px;
padding: 5px;
padding-left: 15px;
margin-left: 15px;
border-left: 1px dotted gray;
}
#currentUsers table {
width: 100%;
}
#invitation {
border: 1px dotted gray;
}
span.errorMsg{
color: red;
}
div.fform {
background: #eeeeee;
border: 1px solid #cfcfcf;
padding: 5px 25px;
-moz-border-radius: 8px;
-khtml-border-radius: 8px;
-webkit-border-radius: 8px;
border-radius: 8px;
}
div.fform label {
font-weight: bold;
}

View File

@@ -142,7 +142,8 @@ jQuery.fn.dialogForm = function (options) {
console.log(errorThrown);
console.log(jqXHR);
dialogElem.modal('hide');
$('#messagesPanel div').text(errorThrown).parent().show();
$('#messagesPanel div div').text(errorThrown);
$('#messagesPanel').show()
}
var acceptBtn = $('#' + containerId + ' .btn-accept');
acceptBtn.button('reset');
@@ -168,22 +169,22 @@ function updateStatusToolbar() {
$("#mindmapListTable tbody input:checked").parent().parent().addClass('row-selected');
$("#mindmapListTable tbody input:not(:checked)").parent().parent().removeClass('row-selected');
$('#buttonsToolbar').find('.act-single').hide().end().find('.act-multiple').hide();
$('.buttonsToolbar').find('.act-single').hide().end().find('.act-multiple').hide();
var tableElem = $('#mindmapListTable');
var selectedRows = tableElem.dataTableExt.getSelectedRows();
if (selectedRows.length > 0) {
if (selectedRows.length == 1) {
$('#buttonsToolbar').find('.act-single').show().end().find('.act-multiple').show();
$('.buttonsToolbar').find('.act-single').show().end().find('.act-multiple').show();
// Can be executed by the owner ?
var rowData = tableElem.dataTable().fnGetData(selectedRows[0]);
if (rowData.role != 'owner') {
$("#buttonsToolbar").find('#publishBtn').hide().end().find('#shareBtn').hide().end().find('#renameBtn').hide();
$(".buttonsToolbar").find('#publishBtn').hide().end().find('#shareBtn').hide().end().find('#renameBtn').hide();
}
} else {
$("#buttonsToolbar .act-multiple").show();
$(".buttonsToolbar .act-multiple").show();
}
}
}

View File

@@ -1,9 +1,10 @@
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<div id="footer">
<div><a href="https://twitter.com/share" class="twitter-share-button" data-via="wisemapping"
data-related="wisemapping">Tweet</a>
<div class="row" id="footer">
<div class="span1 offset3">
<a href="https://twitter.com/share" class="twitter-share-button" data-via="wisemapping"
data-related="wisemapping">Tweet</a>
<script>!function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (!d.getElementById(id)) {
@@ -13,8 +14,8 @@
fjs.parentNode.insertBefore(js, fjs);
}
}(document, "script", "twitter-wjs");</script>
<!-- Place this tag in your head or just before your close body tag -->
</div>
<div class="span1">
<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
{
parsetags: 'explicit'
@@ -27,17 +28,17 @@
<!-- Place this render call where appropriate -->
<script type="text/javascript">gapi.plusone.go();</script>
</div>
<div style="width: 240px; padding: 0 40px;">
<p>
<div class="span4">
<p style="text-align: center;">
<a href="https://groups.google.com/d/forum/wisemapping-support"><spring:message code="SUPPORT"/></a> |
<a href="mailto:feedback@wisemapping.com"><spring:message code="FEEDBACK"/></a> |
<a href="mailto:dev@wisemapping.com"><spring:message code="CONTACT_US"/></a>
<a href="mailto:dev@wisemapping.com"><spring:message code="CONTACT_US"/></a> |
<a href="http://www.wisemapping.org/license"><spring:message code="LICENSE"/></a><br/>
<a href="http://www.wisemapping.org/"><spring:message code="COPYRIGHT"/></a>
</p>
</div>
<div style="padding: 0 20px">
<div class="span1">
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" name="submit"
@@ -47,30 +48,30 @@
value="-----BEGIN PKCS7-----MIIHwQYJKoZIhvcNAQcEoIIHsjCCB64CAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYBvLN5PRNvfylLOCDCi65JktD2se3FdTyRH1+Ptw+OrhDWUX76pT8qt89aCzRjroJikwKfgmiyLHSOw4rDF5xGbzesCdAjpkrv5KwMRxiaf/FEdXDHHufv2pwP591+h7mY36I0+nDdwVykq7KteiQRsfFQeLkHikRsZ6Gtw3eRuBjELMAkGBSsOAwIaBQAwggE9BgkqhkiG9w0BBwEwFAYIKoZIhvcNAwcECNad8bwThZeKgIIBGEkN7nh0XMYn8N6aOZm9Dqtnty8qTW42ACmxf9llJ1wzj4SRT9SEpHfq4tMG3hRRjAhJ6DRW8k+0QacC5exvzddGo1bIFGvNxWnXF3CEUy2yc2Dw/YaUlsZsSYcyChi9yxjmNnrH7YYDgnpAq7V1fcKN89t8gnNA2+KAPENtT6yF8eNzrzf5ckfFBOJXawLW4lACk5h1jrCmF5oWL/SicDsjLMFvXkD6P7tHsxOlLHj1Oe6k+Ejb1xsFpagsiU5/CWyTpP0sjgXyY/z08sJXk9HBYNJOwTXd7u6h9h6mjHKuCb1p5vCQbFY0yDV881ILsnpzguAOGHbMTzmYSenDcdj6JnzQDQxYUQTNYfLgtKgO1Xy3M63UA9mgggOHMIIDgzCCAuygAwIBAgIBADANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYw FAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20wHhcNMDQwMjEzMTAxMzE1WhcNMzUwMjEzMTAxMzE1WjCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMFHTt38RMxLXJyO2SmS+Ndl72T7oKJ4u4uw+6awntALWh03PewmIJuzbALScsTS4sZoS1fKciBGoh11gIfHzylvkdNe/hJl66/RGqrj5rFb08sAABNTzDTiqqNpJeBsYs/c2aiGozptX2RlnBktH+SUNpAajW724Nv2Wvhif6sFAgMBAAGjge4wgeswHQYDVR0OBBYEFJaffLvGbxe9WT9S1wob7BDWZJRrMIG7BgNVHSMEgbMwgbCAFJaffLvGbxe9WT9S1wob7BDWZJRroYGUpIGRMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAIFfOlaagFrl71+jq6OKidbWFSE+Q4FqROvdgIONth +8kSK//Y/4ihuE4Ymvzn5ceE3S/iBSQQMjyvb+s2TWbQYDwcp129OPIbD9epdr4tJOUNiSojw7BHwYRiPh58S1xGlFgHFXwrEBb3dgNbMUa+u4qectsMAXpVHnD9wIyfmHMYIBmjCCAZYCAQEwgZQwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tAgEAMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0wNzA5MDQxMTMyMTNaMCMGCSqGSIb3DQEJBDEWBBTF2vsxwMzHX7TQrdpdCFCp3Rk6TDANBgkqhkiG9w0BAQEFAASBgJS4fx+wCQaPzs3wvgaJOvbgub23AuGbaMc3fYKGxJf5JTxUVsSkQY9t6itXUr2llwc/GprbKaCvcOnOBXT8NkZ6gWqNX9iwDq83rblm3XI7yrjRUCQrvIkhJ80xKGrhBn48V61FawASYdpE1AmhZoga9XAIZruO0NrnT2QXxe2p-----END PKCS7-----"/>
</form>
</div>
<div>
<div class="span1">
<a href="http://www.w3.org/html/logo/">
<img src="http://www.w3.org/html/logo/badge/html5-badge-h-graphics.png" width="66" height="32"
alt="HTML5 Powered with Graphics, 3D &amp; Effects"
title="HTML5 Powered with Graphics, 3D &amp; Effects">
</a>
</div>
</div>
<c:if test="${requestScope['google.analytics.enabled']}">
<script type="text/javascript">
<c:if test="${requestScope['google.analytics.enabled']}">
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '${requestScope['google.analytics.account']}']);
_gaq.push(['_setDomainName', 'wisemapping.com']);
_gaq.push(['_trackPageview']);
var _gaq = _gaq || [];
_gaq.push(['_setAccount', '${requestScope['google.analytics.account']}']);
_gaq.push(['_setDomainName', 'wisemapping.com']);
_gaq.push(['_trackPageview']);
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
</c:if>
</div>
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
</c:if>

View File

@@ -28,7 +28,9 @@
$('download').setAttribute('value', context.formatType);
iframeForm.submit();
}
MooDialog.Request.active.close();
if (MooDialog.Request.active) {
MooDialog.Request.active.close();
}
}
});

View File

@@ -4,20 +4,21 @@
<%--@elvariable id="isHsql" type="boolean"--%>
<script type="text/javascript" language="javascript">
$(function() {
$('.btn-primary').click(function() {
$(function () {
$('.btn-primary').click(function () {
$(this).button("loading");
});
});
</script>
<div id="loginContent">
<div class="loginNews">
<h1><spring:message code="WHAT_IS_NEW"/>: </h1>
<spring:message code="WHAT_IS_NEW_DETAILS"/>
<div id="row-fluid">
<div class="span1"></div>
<div class="span5" style="margin-top: 20px">
<h1><spring:message code="WELCOME_TO_WISEMAPPING"/></h1>
<spring:message code="WELCOME_DETAILS"/>
</div>
<div id="login" class="fform">
<div class="span1"></div>
<div id="login" class="fform span4">
<h1>
<spring:message code="SIGN_IN"/>
</h1>
@@ -54,17 +55,22 @@
</div>
</div>
<div id="register">
<b><spring:message code="NOT_READY_A_USER"/></b>
<spring:message code="NOT_READY_A_USER_MESSAGE"/>
<a href="c/user/registration">
<spring:message code="JOIN_NOW"/>
</a>
<div class="row-fluid">
<div id="register" class="span12">
<b><spring:message code="NOT_READY_A_USER"/></b>
<spring:message code="NOT_READY_A_USER_MESSAGE"/>
<a href="c/user/registration">
<spring:message code="JOIN_NOW"/>
</a>
</div>
</div>
<c:if test="${isHsql== 'true'}">
<div class="alert alert-info">
<span class="label label-important"><spring:message code="WARNING"/></span> <spring:message code="NO_PRODUCTION_DATABASE_CONFIGURED"/>&nbsp;<a
href="http://www.wisemapping.org/documentation/configu"><spring:message code="HERE"/></a>.
<div class="row-fluid">
<div class="alert alert-info span offset12">
<span class="label label-important"><spring:message code="WARNING"/></span> <spring:message
code="NO_PRODUCTION_DATABASE_CONFIGURED"/>&nbsp;<a
href="http://www.wisemapping.org/documentation/configu"><spring:message code="HERE"/></a>.
</div>
</div>
</c:if>

View File

@@ -83,7 +83,7 @@
</div>
</div>
</div>
<script type="text/javascript" src="../js/editor.js"></script>
<script type="text/javascript" src="js/editor.js"></script>
<%@ include file="/jsp/mindmapEditorFooter.jsf" %>
</body>
</html>

View File

@@ -3,7 +3,7 @@
<!DOCTYPE HTML>
<html>
<html lang="en">
<head>
<base href="${baseURL}/">
<title><spring:message code="SITE.TITLE"/> - <spring:message code="MY_WISEMAPS"/></title>
@@ -99,7 +99,7 @@
// Re-arrange pagination actions ...
$("#tableFooter").appendTo("#mindmapListTable_wrapper");
$("#mindmapListTable_length").appendTo("#tableFooter");
$('#mindmapListTable_length select').addClass('span1');
$('#mindmapListTable_length select').attr("style", "width:60px;");
$('input:checkbox[id="selectAll"]').click(function () {
@@ -122,99 +122,114 @@
<jsp:param name="showLogout" value="true"/>
</jsp:include>
<div style="min-height: 500px">
<div id="mindmapListContainer">
<div id="messagesPanel" class="alert alert-error alert-block fade in hide" style="margin-top: 10px">
<strong><spring:message code="UNEXPECTED_ERROR"/></strong>
<div class="row-fluid hide" id="messagesPanel" style="margin-top: 20px">
<div class="span2"></div>
<div class="alert alert-error alert-block fade in span8">
<strong><spring:message code="UNEXPECTED_ERROR"/></strong>
<p><spring:message code="UNEXPECTED_ERROR_SERVER_ERROR"/></p>
<p><spring:message code="UNEXPECTED_ERROR_SERVER_ERROR"/></p>
<div></div>
<div></div>
</div>
</div>
<div class="row-fluid" style="min-height: 500px">
<div class="span1"></div>
<div class="span2" id="foldersContainer">
<ul class="nav nav-list">
<li class="nav-header"><spring:message code="FILTERS"/></li>
<li data-filter="all" class="active"><a href="#"><i class="icon-inbox icon-white"></i> <spring:message
code="ALL_MAPS"/></a></li>
<li data-filter="my_maps"><a href="#"><i class="icon-user"></i> <spring:message code="MY_MAPS"/></a>
</li>
<li data-filter="shared_with_me"><a href="#"><i class="icon-share"></i> <spring:message
code="SHARED_WITH_ME"/></a></li>
<li data-filter="starred"><a href="#"><i class="icon-star"></i> <spring:message code="STARRED"/></a>
</li>
<li data-filter="public"><a href="#"><i class="icon-globe"></i> <spring:message code="PUBLIC_MAPS"/></a>
</li>
</ul>
</div>
<div class="buttonsToolbar btn-toolbar ${requestScope['google.ads.enabled']?'span7':'span8'}">
<div id="tableActions">
<div id="pageInfo"></div>
<div class="btn-group" id="pageButtons">
<button class="btn" id="pPageBtn"><strong>&lt;</strong></button>
<button class="btn" id="nPageBtn"><strong>&gt;</strong></button>
</div>
</div>
<div id="foldersContainer">
<ul class="nav nav-list">
<li class="nav-header"><spring:message code="FILTERS"/></li>
<li data-filter="all" class="active"><a href="#"><i class="icon-inbox icon-white"></i> <spring:message
code="ALL_MAPS"/></a></li>
<li data-filter="my_maps"><a href="#"><i class="icon-user"></i> <spring:message code="MY_MAPS"/></a>
<div class="btn-group">
<button id="newBtn" class="btn btn-primary"><i class="icon-file icon-white"></i> <spring:message
code="NEW"/></button>
<button id="importBtn" class="btn btn-primary"><i class="icon-upload icon-white"></i>
<spring:message code="IMPORT"/>
</button>
</div>
<div class="btn-group act-multiple" id="deleteBtn" style="display:none">
<button class="btn btn-primary"><i class="icon-trash icon-white"></i> <spring:message
code="DELETE"/></button>
</div>
<div id="infoBtn" class="btn-group act-single" style="display:none">
<button class="btn btn-primary"><i class="icon-exclamation-sign icon-white"></i> <spring:message
code="INFO"/></button>
</div>
<div id="actionsBtn" class="btn-group act-single" style="display:none">
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<i class="icon-asterisk icon-white"></i> <spring:message code="MORE"/>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li id="duplicateBtn"><a href="#" onclick="return false"><i class="icon-plus-sign"></i>
<spring:message code="DUPLICATE"/></a></li>
<li id="renameBtn"><a href="#" onclick="return false"><i class="icon-edit"></i> <spring:message
code="RENAME"/></a></li>
<li id="publishBtn"><a href="#" onclick="return false"><i class="icon-globe"></i>
<spring:message code="PUBLISH"/></a>
</li>
<li data-filter="shared_with_me"><a href="#"><i class="icon-share"></i> <spring:message
code="SHARED_WITH_ME"/></a></li>
<li data-filter="starred"><a href="#"><i class="icon-star"></i> <spring:message code="STARRED"/></a>
<li id="shareBtn"><a href="#" onclick="return false"><i class="icon-share"></i> <spring:message
code="SHARE"/></a></li>
<li id="exportBtn"><a href="#" onclick="return false"><i class="icon-download"></i>
<spring:message
code="EXPORT"/></a>
</li>
<li data-filter="public"><a href="#"><i class="icon-globe"></i> <spring:message code="PUBLIC_MAPS"/></a>
<li id="printBtn"><a href="#" onclick="return false"><i class="icon-print"></i> <spring:message
code="PRINT"/></a></li>
<li id="historyBtn"><a href="#" onclick="return false"><i class="icon-time"></i> <spring:message
code="HISTORY"/></a>
</li>
</ul>
</div>
<div style="width: 78%;float: left;">
<div id="buttonsToolbar" class="btn-toolbar">
<div class="btn-group">
<button id="newBtn" class="btn btn-primary"><i class="icon-file icon-white"></i> <spring:message
code="NEW"/></button>
<button id="importBtn" class="btn btn-primary"><i class="icon-upload icon-white"></i>
<spring:message code="IMPORT"/>
</button>
</div>
<div class="btn-group act-multiple" id="deleteBtn" style="display:none">
<button class="btn btn-primary"><i class="icon-trash icon-white"></i> <spring:message
code="DELETE"/></button>
</div>
<div id="infoBtn" class="btn-group act-single" style="display:none">
<button class="btn btn-primary"><i class="icon-exclamation-sign icon-white"></i> <spring:message
code="INFO"/></button>
</div>
<div id="actionsBtn" class="btn-group act-single" style="display:none">
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
<i class="icon-asterisk icon-white"></i> <spring:message code="MORE"/>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li id="duplicateBtn"><a href="#" onclick="return false"><i class="icon-plus-sign"></i>
<spring:message code="DUPLICATE"/></a></li>
<li id="renameBtn"><a href="#" onclick="return false"><i class="icon-edit"></i> <spring:message
code="RENAME"/></a></li>
<li id="publishBtn"><a href="#" onclick="return false"><i class="icon-globe"></i>
<spring:message code="PUBLISH"/></a>
</li>
<li id="shareBtn"><a href="#" onclick="return false"><i class="icon-share"></i> <spring:message
code="SHARE"/></a></li>
<li id="exportBtn"><a href="#" onclick="return false"><i class="icon-download"></i>
<spring:message
code="EXPORT"/></a>
</li>
<li id="printBtn"><a href="#" onclick="return false"><i class="icon-print"></i> <spring:message
code="PRINT"/></a></li>
<li id="historyBtn"><a href="#" onclick="return false"><i class="icon-time"></i> <spring:message
code="HISTORY"/></a>
</li>
</ul>
</div>
<div id="tableActions" class="btn-toolbar">
<div class="btn-group" id="pageButtons">
<button class="btn" id="pPageBtn"><strong>&lt;</strong></button>
<button class="btn" id="nPageBtn"><strong>&gt;</strong></button>
</div>
<div id="pageInfo"></div>
</div>
</div>
<div id="map-table">
<table class="table" id="mindmapListTable"></table>
<div id="tableFooter" class="form-inline"></div>
</div>
<div id="map-table">
<table class="table" id="mindmapListTable"></table>
<div id="tableFooter" class="form-inline"></div>
</div>
</div>
<div class="span1" style="padding-top:25px">
<c:if test="${requestScope['google.ads.enabled']}">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-7564778578019285";
/* WiseMapping Mindmap List */
google_ad_slot = "4071968444";
google_ad_width = 120;
google_ad_height = 440;
//-->
</script>
<div style="margin-top:5px;">
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</c:if>
</div>
</div>
<div style="border-top: 1px solid #000000">
<jsp:include page="footer.jsp"/>
</div>
<jsp:include page="footer.jsp"/>
<div id="dialogsContainer">
<!-- New map dialog -->
@@ -421,22 +436,5 @@
</div>
</div>
</div>
<c:if test="${requestScope['google.ads.enabled']}">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-7564778578019285";
/* WiseMapping Mindmap List */
google_ad_slot = "4071968444";
google_ad_width = 120;
google_ad_height = 460;
//-->
</script>
<div style="position:absolute;right: 9px;top: 90px">
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</c:if>
</body>
</html>

View File

@@ -118,7 +118,7 @@
</div>
</div>
</div>
<script type="text/javascript" src="../js/editor.js"></script>
<script type="text/javascript" src="js/editor.js"></script>
<%@ include file="/jsp/mindmapEditorFooter.jsf" %>
</body>
</html>

View File

@@ -34,8 +34,9 @@
<jsp:include page="header.jsp"/>
<div class="pageBody">
<div class="pageBodyContent">
<div class="pageBody row-fluid">
<div class="span2"></div>
<div class="pageBodyContent span8">
<tiles:insertAttribute name="body"/>
</div>
</div>