diff --git a/src/wirecloud/commons/static/js/StyledElements/CodeArea.js b/src/wirecloud/commons/static/js/StyledElements/CodeArea.js
index 164a133b1..dcc4bae4c 100644
--- a/src/wirecloud/commons/static/js/StyledElements/CodeArea.js
+++ b/src/wirecloud/commons/static/js/StyledElements/CodeArea.js
@@ -148,6 +148,7 @@
if (!window.monaco) {
// If monaco is not available, use the TextArea class
se.CodeArea = se.TextArea;
+ se.__Testing__CodeArea = CodeAreaClass; // For testing purposes
} else {
se.CodeArea = CodeAreaClass;
}
diff --git a/src/wirecloud/commons/utils/template/parsers/json.py b/src/wirecloud/commons/utils/template/parsers/json.py
index 0c1fe5af6..c2723d892 100644
--- a/src/wirecloud/commons/utils/template/parsers/json.py
+++ b/src/wirecloud/commons/utils/template/parsers/json.py
@@ -242,16 +242,35 @@ def _init(self):
self._check_string_fields(('title',), place=tab, required=False)
self._check_array_fields(('resources',), place=tab)
for widget in tab['resources']:
- rendering = widget.get('rendering', {})
- self._check_integer_fields(('layout',), place=rendering, default=0, allow_cast=True)
- layout = rendering['layout']
- self._check_boolean_fields(('relwidth',), place=rendering, default=True)
- self._check_boolean_fields(('relheight',), place=rendering, default=(layout != 1))
-
- position = widget.get('position', {})
- self._check_string_fields(('anchor',), place=position, default="top-left")
- self._check_boolean_fields(('relx',), place=position, default=True)
- self._check_boolean_fields(('rely',), place=position, default=(layout != 1))
+ screenSizes = widget.get('screenSizes', None)
+ if screenSizes is None:
+ screenSizes = [
+ {
+ 'moreOrEqual': 0,
+ 'lessOrEqual': -1,
+ 'id': 0,
+ 'rendering': widget.get('rendering', {}),
+ 'position': widget.get('position', {})
+ }
+ ]
+
+ layout = screenSizes[0]['rendering'].get('layout', 0)
+ widget['layout'] = layout
+ else:
+ layout = widget.get('layout', 0)
+
+ for screenSize in screenSizes:
+ self._check_integer_fields(('moreOrEqual', 'lessOrEqual', 'id'), place=screenSize, required=True)
+
+ rendering = screenSize.get('rendering', {})
+ self._check_integer_fields(('layout',), place=rendering, default=0, allow_cast=True)
+ self._check_boolean_fields(('relwidth',), place=rendering, default=True)
+ self._check_boolean_fields(('relheight',), place=rendering, default=(layout != 1))
+
+ position = screenSize.get('position', {})
+ self._check_string_fields(('anchor',), place=position, default="top-left")
+ self._check_boolean_fields(('relx',), place=position, default=True)
+ self._check_boolean_fields(('rely',), place=position, default=(layout != 1))
for preference in self._info['params']:
self._check_string_fields(('name', 'type'), place=preference, required=True)
diff --git a/src/wirecloud/commons/utils/template/parsers/xml.py b/src/wirecloud/commons/utils/template/parsers/xml.py
index 62d31d175..e69d674ea 100644
--- a/src/wirecloud/commons/utils/template/parsers/xml.py
+++ b/src/wirecloud/commons/utils/template/parsers/xml.py
@@ -75,6 +75,7 @@
TAB_XPATH = 't:tab'
RESOURCE_XPATH = 't:resource'
POSITION_XPATH = 't:position'
+SCREEN_SIZES_XPATH = 't:screensizes'
RENDERING_XPATH = 't:rendering'
PARAM_XPATH = 't:preferences/t:preference'
EMBEDDEDRESOURCE_XPATH = 't:embedded/t:resource'
@@ -568,10 +569,21 @@ def _parse_workspace_info(self):
}
for widget in self._xpath(RESOURCE_XPATH, tab):
- position = self.get_xpath(POSITION_XPATH, widget)
- rendering = self.get_xpath(RENDERING_XPATH, widget)
+ position = self.get_xpath(POSITION_XPATH, widget, required=False)
+ screenSizes = self.get_xpath(SCREEN_SIZES_XPATH, widget, required=False)
+ rendering = self.get_xpath(RENDERING_XPATH, widget, required=False)
+
+ if (position is None or rendering is None) and screenSizes is None:
+ raise TemplateParseException(_("Missing position/rendering or screensizes element"))
+
+ if (rendering is None and not widget.get('layout')):
+ raise TemplateParseException(_("Missing layout in resource or rendering element"))
+
+ if rendering is None:
+ layout = int(str(widget.get('layout')))
+ else:
+ layout = int(str(rendering.get('layout')))
- layout = int(str(rendering.get('layout')))
widget_info = {
'id': str(widget.get('id')),
'name': str(widget.get('name')),
@@ -579,28 +591,67 @@ def _parse_workspace_info(self):
'version': str(widget.get('version')),
'title': str(widget.get('title')),
'readonly': widget.get('readonly', '').lower() == 'true',
+ 'layout': layout,
'properties': {},
- 'preferences': {},
- 'position': {
- 'anchor': str(position.get('anchor', 'top-left')),
- 'relx': position.get('relx', 'true').lower() == 'true',
- 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true',
- 'x': str(position.get('x')),
- 'y': str(position.get('y')),
- 'z': str(position.get('z')),
- },
- 'rendering': {
- 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true',
- 'minimized': rendering.get('minimized', 'false').lower() == 'true',
- 'relwidth': rendering.get('relwidth', 'true').lower() == 'true',
- 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true',
- 'width': str(rendering.get('width')),
- 'height': str(rendering.get('height')),
- 'layout': layout,
- 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true',
- },
+ 'preferences': {}
}
+ if screenSizes is not None:
+ widget_info['screenSizes'] = []
+ for screenSize in screenSizes:
+ position = self.get_xpath(POSITION_XPATH, screenSize)
+ rendering = self.get_xpath(RENDERING_XPATH, screenSize)
+ screen_size_info = {
+ 'moreOrEqual': int(screenSize.get('moreOrEqual')),
+ 'lessOrEqual': int(screenSize.get('lessOrEqual')),
+ 'id': int(screenSize.get('id')),
+ 'position': {
+ 'anchor': str(position.get('anchor', 'top-left')),
+ 'relx': position.get('relx', 'true').lower() == 'true',
+ 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true',
+ 'x': int(float(position.get('x'))),
+ 'y': int(float(position.get('y'))),
+ 'z': int(float(position.get('z'))),
+ },
+ 'rendering': {
+ 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true',
+ 'minimized': rendering.get('minimized', 'false').lower() == 'true',
+ 'relwidth': rendering.get('relwidth', 'true').lower() == 'true',
+ 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true',
+ 'width': int(float(rendering.get('width'))),
+ 'height': int(float(rendering.get('height'))),
+ 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true',
+ }
+ }
+
+ widget_info['screenSizes'].append(screen_size_info)
+ else:
+ widget_info['screenSizes'] = [
+ {
+ 'moreOrEqual': 0,
+ 'lessOrEqual': -1,
+ 'id': 0,
+ 'position': {
+ 'anchor': str(position.get('anchor', 'top-left')),
+ 'relx': position.get('relx', 'true').lower() == 'true',
+ 'rely': position.get('rely', 'true' if layout != 1 else 'false').lower() == 'true',
+ 'x': str(position.get('x')),
+ 'y': str(position.get('y')),
+ 'z': str(position.get('z')),
+ },
+ 'rendering': {
+ 'fulldragboard': rendering.get('fulldragboard', 'false').lower() == 'true',
+ 'minimized': rendering.get('minimized', 'false').lower() == 'true',
+ 'relwidth': rendering.get('relwidth', 'true').lower() == 'true',
+ 'relheight': rendering.get('relheight', 'true' if layout != 1 else 'false').lower() == 'true',
+ 'width': str(rendering.get('width')),
+ 'height': str(rendering.get('height')),
+ 'layout': layout,
+ 'titlevisible': rendering.get('titlevisible', 'true').lower() == 'true',
+ }
+ }
+ ]
+
for prop in self._xpath(PROPERTIES_XPATH, widget):
prop_value = prop.get('value')
widget_info['properties'][str(prop.get('name'))] = {
diff --git a/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd b/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd
index 0d292c03c..6ea79f0f8 100644
--- a/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd
+++ b/src/wirecloud/commons/utils/template/schemas/xml_schema.xsd
@@ -51,6 +51,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -762,19 +791,25 @@
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -792,6 +827,7 @@
+
diff --git a/src/wirecloud/commons/utils/template/writers/xml.py b/src/wirecloud/commons/utils/template/writers/xml.py
index 241a2b26a..d49c878dc 100644
--- a/src/wirecloud/commons/utils/template/writers/xml.py
+++ b/src/wirecloud/commons/utils/template/writers/xml.py
@@ -78,7 +78,7 @@ def addPreferenceValues(resource, preferences):
addAttribute(pref, element, 'value', type='string', default=None, required=False)
addAttributes(pref, element, ('readonly', 'hidden'), default='false', type='boolean')
-
+# TODO Adrian handle multiple screen sizes
def write_mashup_tree(doc, resources, options):
# Params
@@ -122,24 +122,35 @@ def write_mashup_tree(doc, resources, options):
if iwidget.get('readonly', False):
resource.set('readonly', 'true')
- layout = iwidget['rendering']['layout']
-
- position = etree.SubElement(
- resource,
- 'position',
- anchor=str(iwidget['position']['anchor']),
- x=str(iwidget['position']['x']),
- y=str(iwidget['position']['y']),
- z=str(iwidget['position']['z'])
- )
- addAttributes(iwidget['position'], position, ('relx',), default='true', type='boolean')
- addAttributes(iwidget['position'], position, ('rely',), default=('true' if layout != 1 else 'false'), type='boolean')
-
- rendering = etree.SubElement(resource, 'rendering')
- addAttributes(iwidget['rendering'], rendering, ('height', 'width', 'layout'), required=True)
- addAttributes(iwidget['rendering'], rendering, ('minimized', 'fulldragboard'), default='false', type='boolean')
- addAttributes(iwidget['rendering'], rendering, ('relwidth', 'titlevisible'), default='true', type='boolean')
- addAttributes(iwidget['rendering'], rendering, ('relheight',), default=('true' if layout != 1 else 'false'), type='boolean')
+ layout = iwidget['layout']
+
+ addAttributes(iwidget, resource, ('layout',), required=True)
+
+ screenSizesElem = etree.SubElement(resource, 'screensizes')
+ for screenSize in iwidget.get('screenSizes', []):
+ screenSizeElem = etree.SubElement(screenSizesElem,
+ 'screensize',
+ moreOrEqual=str(screenSize['moreOrEqual']),
+ lessOrEqual=str(screenSize['lessOrEqual']),
+ id=str(screenSize['id']))
+
+ position = etree.SubElement(
+ screenSizeElem,
+ 'position',
+ anchor=str(screenSize['position']['anchor']),
+ x=str(int(float(screenSize['position']['x']))),
+ y=str(int(float(screenSize['position']['y']))),
+ z=str(int(float(screenSize['position']['z'])))
+ )
+ addAttributes(screenSize['position'], position, ('relx',), default='true', type='boolean')
+ addAttributes(screenSize['position'], position, ('rely',), default=('true' if layout != 1 else 'false'), type='boolean')
+
+ rendering = etree.SubElement(screenSizeElem, 'rendering',
+ height=str(int(float(screenSize['rendering']['height']))),
+ width=str(int(float(screenSize['rendering']['width'])))),
+ addAttributes(screenSize['rendering'], rendering, ('minimized', 'fulldragboard'), default='false', type='boolean')
+ addAttributes(screenSize['rendering'], rendering, ('relwidth', 'titlevisible'), default='true', type='boolean')
+ addAttributes(screenSize['rendering'], rendering, ('relheight',), default=('true' if layout != 1 else 'false'), type='boolean')
addPreferenceValues(resource, iwidget['preferences'])
diff --git a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss
index 71a3d3c4d..264c2c126 100644
--- a/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss
+++ b/src/wirecloud/defaulttheme/static/css/workspace/dragboard.scss
@@ -123,6 +123,7 @@
padding: 10px;
border-radius: 7px;
right: 50px;
+ top: 39px;
}
.wc-editing-interval-close {
diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js
index f852c7ef7..118b25b58 100644
--- a/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js
+++ b/src/wirecloud/platform/static/js/wirecloud/ui/SidebarLayout.js
@@ -136,6 +136,10 @@
return result;
}
+ removeHandle() {
+ this.handle.remove();
+ }
+
removeWidget(widget, affectsDragboard) {
const result = super.removeWidget(widget, affectsDragboard);
@@ -205,7 +209,7 @@
} else {
offset = 0;
}
- element.style.left = this.getColumnOffset(widget.position, true);
+ element.style.left = this.getColumnOffset(widget.position, null, true);
element.style.right = "";
if (this.position === "top") {
element.style.top = offset + "px";
diff --git a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js
index ee36fe870..7f15b8ae1 100644
--- a/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js
+++ b/src/wirecloud/platform/static/js/wirecloud/ui/WidgetView.js
@@ -842,6 +842,9 @@
};
this.layout.removeWidgetEventListeners(this);
+ if ('removeHandle' in this.layout) {
+ this.layout.removeHandle();
+ }
this.layout = null;
this.setPosition(newPos, false);
diff --git a/src/wirecloud/platform/workspace/mashupTemplateGenerator.py b/src/wirecloud/platform/workspace/mashupTemplateGenerator.py
index 224584ecd..cd1380bc2 100644
--- a/src/wirecloud/platform/workspace/mashupTemplateGenerator.py
+++ b/src/wirecloud/platform/workspace/mashupTemplateGenerator.py
@@ -41,6 +41,7 @@ def get_workspace_description(workspace):
return get_iwidgets_description(included_iwidgets)
+# TODO Adrian handle multiple screen sizes
def process_iwidget(workspace, iwidget, wiring, parametrization, readOnlyWidgets, cache_manager):
widget = iwidget.widget
@@ -136,35 +137,46 @@ def process_iwidget(workspace, iwidget, wiring, parametrization, readOnlyWidgets
'value': value,
}
- return {
+ screenSizes = []
+ for configuration in iwidget.positions['configurations']:
+ screenSizes.append({
+ 'moreOrEqual': configuration['moreOrEqual'],
+ 'lessOrEqual': configuration['lessOrEqual'],
+ 'id': configuration['id'],
+ 'position': {
+ 'anchor': configuration['widget'].get('anchor', 'top-left'),
+ 'relx': configuration['widget'].get('relx', True),
+ 'rely': configuration['widget'].get('rely', True if iwidget.layout != 1 else False),
+ 'x': str(configuration['widget']['left']),
+ 'y': str(configuration['widget']['top']),
+ 'z': str(configuration['widget']['zIndex'])
+ },
+ 'rendering': {
+ 'relwidth': configuration['widget'].get('relwidth', True),
+ 'relheight': configuration['widget'].get('relheight', True if iwidget.layout != 1 else False),
+ 'width': str(configuration['widget']['width']),
+ 'height': str(configuration['widget']['height']),
+ 'fulldragboard': bool(configuration['widget']['fulldragboard']),
+ 'minimized': bool(configuration['widget']['minimized']),
+ 'titlevisible': bool(configuration['widget'].get('titlevisible', True)),
+ },
+ })
+
+ iwidget_data = {
'id': iwidget_id,
'vendor': iwidget.widget.resource.vendor,
'name': iwidget.widget.resource.short_name,
'version': iwidget.widget.resource.version,
'title': iwidget.name,
+ 'layout': iwidget.layout,
'readonly': readOnlyWidgets,
'properties': properties,
'preferences': preferences,
- 'position': {
- 'anchor': iwidget.positions['widget'].get('anchor', 'top-left'),
- 'relx': iwidget.positions['widget'].get('relx', True),
- 'rely': iwidget.positions['widget'].get('rely', True if iwidget.layout != 1 else False),
- 'x': str(iwidget.positions['widget']['left']),
- 'y': str(iwidget.positions['widget']['top']),
- 'z': str(iwidget.positions['widget']['zIndex']),
- },
- 'rendering': {
- 'relwidth': iwidget.positions['widget'].get('relwidth', True),
- 'relheight': iwidget.positions['widget'].get('relheight', True if iwidget.layout != 1 else False),
- 'width': str(iwidget.positions['widget']['width']),
- 'height': str(iwidget.positions['widget']['height']),
- 'layout': iwidget.layout,
- 'fulldragboard': bool(iwidget.positions['widget']['fulldragboard']),
- 'minimized': bool(iwidget.positions['widget']['minimized']),
- 'titlevisible': bool(iwidget.positions['widget'].get('titlevisible', True)),
- },
+ 'screenSizes': screenSizes
}
+ return iwidget_data
+
def build_json_template_from_workspace(options, workspace, user):
options['type'] = 'mashup'
diff --git a/src/wirecloud/platform/workspace/mashupTemplateParser.py b/src/wirecloud/platform/workspace/mashupTemplateParser.py
index d280035de..034d95de4 100644
--- a/src/wirecloud/platform/workspace/mashupTemplateParser.py
+++ b/src/wirecloud/platform/workspace/mashupTemplateParser.py
@@ -225,27 +225,38 @@ def fillWorkspaceUsingTemplate(workspace, template):
for resource in tab_entry['resources']:
- position = resource['position']
- rendering = resource['rendering']
-
widget = get_or_add_widget_from_catalogue(resource.get('vendor'), resource.get('name'), resource.get('version'), user)
iwidget_data = {
"widget": widget.uri,
"title": resource.get('title'),
- "left": float(position.get('x')),
- "top": float(position.get('y')),
"icon_left": 0,
"icon_top": 0,
- "zIndex": int(position.get('z')),
- "width": float(rendering.get('width')),
- "height": float(rendering.get('height')),
- "layout": int(rendering.get('layout')),
- "minimized": rendering['minimized'],
- "fulldragboard": rendering['fulldragboard'],
- "titlevisible": rendering['titlevisible'],
+ "layout": int(resource.get('layout')),
+ "layoutConfigurations": []
}
+ for configuration in resource["screenSizes"]:
+ position = configuration['position']
+ rendering = configuration['rendering']
+
+ iwidget_layoutConfig = {
+ 'moreOrEqual': configuration['moreOrEqual'],
+ 'lessOrEqual': configuration['lessOrEqual'],
+ 'id': configuration['id'],
+ "left": float(position.get('x')),
+ "top": float(position.get('y')),
+ "zIndex": int(position.get('z')),
+ "width": float(rendering.get('width')),
+ "height": float(rendering.get('height')),
+ "minimized": rendering['minimized'],
+ "fulldragboard": rendering['fulldragboard'],
+ "titlevisible": rendering['titlevisible'],
+ 'action': 'update'
+ }
+
+ iwidget_data['layoutConfigurations'].append(iwidget_layoutConfig)
+
iwidget = SaveIWidget(iwidget_data, user, tab, commit=False)
if resource.get('readonly'):
iwidget.readOnly = True