diff --git a/src/main/java/org/olat/catalog/ui/CatalogEntryMoveController.java b/src/main/java/org/olat/catalog/ui/CatalogEntryMoveController.java index a9745c5bfe37b0cdf442a05ac122fc12bc06b18a..d1a1cff97c1a53a2de0625f0e8f91dbf52068975 100644 --- a/src/main/java/org/olat/catalog/ui/CatalogEntryMoveController.java +++ b/src/main/java/org/olat/catalog/ui/CatalogEntryMoveController.java @@ -73,7 +73,6 @@ public class CatalogEntryMoveController extends BasicController implements Catal mainVC = createVelocityContainer("catMove"); selectionTree = new SelectionTree("catSelection", trans); selectionTree.addListener(this); - selectionTree.setMultiselect(false); selectionTree.setFormButtonKey("cat.move.submit"); selectionTree.setShowCancelButton(true); selectionTree.setTreeModel(new CatalogTreeModel(catEntryList, moveMe, ownedEntries)); diff --git a/src/main/java/org/olat/commons/calendar/_content/calCLP.html b/src/main/java/org/olat/commons/calendar/_content/calCLP.html deleted file mode 100644 index 3e96ebe2eac87b07404ba68c661e34adf95df93b..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/commons/calendar/_content/calCLP.html +++ /dev/null @@ -1,7 +0,0 @@ -#if ($displayOnly) -#foreach ($link in $links) -<a href="javascript:top.o_openUriInMainWindow('$link.getURI()')">$r.escapeHtml($link.getDisplayName())</a><br> -#end -#else -$r.render("tree") -#end \ No newline at end of file diff --git a/src/main/java/org/olat/commons/calendar/_content/calCopy.html b/src/main/java/org/olat/commons/calendar/_content/calCopy.html deleted file mode 100644 index de8a0b8fd2f5897aac679725197ce7753da15041..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/commons/calendar/_content/calCopy.html +++ /dev/null @@ -1,4 +0,0 @@ -<fieldset> - <legend>$r.translate("cal.copy.title")</legend> - $r.render("tree") -</fieldset> \ No newline at end of file diff --git a/src/main/java/org/olat/commons/calendar/ui/CopyEventToCalendarController.java b/src/main/java/org/olat/commons/calendar/ui/CopyEventToCalendarController.java index 7aca82ae045ba8f68ddc68fd250f3874926afac6..285edbe96b9f35c10e0b85a67452adb9f1f620e1 100644 --- a/src/main/java/org/olat/commons/calendar/ui/CopyEventToCalendarController.java +++ b/src/main/java/org/olat/commons/calendar/ui/CopyEventToCalendarController.java @@ -36,94 +36,75 @@ import org.olat.commons.calendar.model.KalendarEvent; import org.olat.commons.calendar.model.KalendarEventLink; import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.tree.GenericTreeModel; -import org.olat.core.gui.components.tree.GenericTreeNode; -import org.olat.core.gui.components.tree.SelectionTree; -import org.olat.core.gui.components.tree.TreeEvent; -import org.olat.core.gui.components.tree.TreeModel; -import org.olat.core.gui.components.velocity.VelocityContainer; -import org.olat.core.gui.control.DefaultController; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.translator.Translator; import org.olat.core.util.Util; import org.olat.core.util.xml.XStreamHelper; -public class CopyEventToCalendarController extends DefaultController { - - private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(CalendarManager.class); +public class CopyEventToCalendarController extends FormBasicController { - private VelocityContainer mainVC; - private SelectionTree calendarSelectionTree; - private KalendarEvent kalendarEvent; + private static final String[] copy = new String[] {"copy"}; - public CopyEventToCalendarController(KalendarEvent kalendarEvent, Collection<KalendarRenderWrapper> calendars, - Translator translator, WindowControl wControl) { - super(wControl); - this.kalendarEvent = kalendarEvent; + private final KalendarEvent kalendarEvent; + private final Collection<KalendarRenderWrapper> calendars; + private List<MultipleSelectionElement> copyEls; + + public CopyEventToCalendarController(UserRequest ureq, WindowControl wControl, + KalendarEvent kalendarEvent, Collection<KalendarRenderWrapper> calendars) { + super(ureq, wControl); + setTranslator(Util.createPackageTranslator(CalendarManager.class, ureq.getLocale(), getTranslator())); - mainVC = new VelocityContainer("calCopy", VELOCITY_ROOT + "/calCopy.html", translator, this); - calendarSelectionTree = new SelectionTree("calSelection", translator); - calendarSelectionTree.addListener(this); - calendarSelectionTree.setMultiselect(true); - calendarSelectionTree.setFormButtonKey("cal.copy.submit"); - calendarSelectionTree.setShowCancelButton(true); - calendarSelectionTree.setTreeModel(new CalendarSelectionModel(calendars, kalendarEvent.getCalendar(), translator)); - mainVC.put("tree", calendarSelectionTree); + this.calendars = calendars; + this.kalendarEvent = kalendarEvent; - setInitialComponent(mainVC); + initForm(ureq); } - - public void event(UserRequest ureq, Component source, Event event) { - if (source == calendarSelectionTree) { - TreeEvent te = (TreeEvent) event; - if (event.getCommand().equals(TreeEvent.COMMAND_TREENODES_SELECTED)) { - // rebuild kalendar event links - List<String> selectedNodesIDS = te.getNodeIds(); - TreeModel model = calendarSelectionTree.getTreeModel(); - CalendarManager calendarManager = CalendarManagerFactory.getInstance().getCalendarManager(); - for (String nodeId : selectedNodesIDS) { - GenericTreeNode node = (GenericTreeNode)model.getNodeById(nodeId); - KalendarRenderWrapper calendarWrapper = (KalendarRenderWrapper)node.getUserObject(); - Kalendar cal = calendarWrapper.getKalendar(); - KalendarEvent clonedKalendarEvent = (KalendarEvent)XStreamHelper.xstreamClone(kalendarEvent); - if (clonedKalendarEvent.getKalendarEventLinks().size() != 0) - clonedKalendarEvent.setKalendarEventLinks(new ArrayList<KalendarEventLink>()); - calendarManager.addEventTo(cal, clonedKalendarEvent); -// calendarManager.persistCalendar(cal); - } - fireEvent(ureq, Event.DONE_EVENT); + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + setFormTitle("cal.copy.title"); + + copyEls = new ArrayList<>(calendars.size()); + for (KalendarRenderWrapper calendarWrapper : calendars) { + String calId = calendarWrapper.getKalendar().getCalendarID(); + String value = calendarWrapper.getKalendarConfig().getDisplayName(); + MultipleSelectionElement copyEl = uifactory + .addCheckboxesHorizontal("cal_" + calId, null, formLayout, copy, new String[]{ value }); + copyEl.setUserObject(calendarWrapper); + if (calendarWrapper.getKalendar().getCalendarID().equals(kalendarEvent.getCalendar().getCalendarID())) { + // this is the calendar, the event comes from + copyEl.select(copy[0], true); + copyEl.setEnabled(false); } else { - fireEvent(ureq, Event.CANCELLED_EVENT); + copyEl.setEnabled(calendarWrapper.getAccess() == KalendarRenderWrapper.ACCESS_READ_WRITE); } } } - + + @Override protected void doDispose() { // nothing to do here } - - public static class CalendarSelectionModel extends GenericTreeModel { - private static final long serialVersionUID = 8954574138862602309L; - - public CalendarSelectionModel(Collection<KalendarRenderWrapper> calendars, Kalendar excludeKalendar, Translator translator) { - GenericTreeNode rootNode = new GenericTreeNode(translator.translate("cal.copy.rootnode"), null); - for (KalendarRenderWrapper calendarWrapper : calendars) { - GenericTreeNode node = new GenericTreeNode(calendarWrapper.getKalendarConfig().getDisplayName(), calendarWrapper); - node.setIdent(calendarWrapper.getKalendar().getCalendarID()); - if (calendarWrapper.getKalendar().getCalendarID().equals(excludeKalendar.getCalendarID())) { - // this is the calendar, the event comes from - node.setSelected(true); - node.setAccessible(false); - } else { - node.setAccessible(calendarWrapper.getAccess() == KalendarRenderWrapper.ACCESS_READ_WRITE); + @Override + protected void formOK(UserRequest ureq) { + CalendarManager calendarManager = CalendarManagerFactory.getInstance().getCalendarManager(); + for (MultipleSelectionElement copyEl : copyEls) { + if(copyEl.isEnabled() && copyEl.isAtLeastSelected(1)) { + KalendarRenderWrapper calendarWrapper = (KalendarRenderWrapper)copyEl.getUserObject(); + Kalendar cal = calendarWrapper.getKalendar(); + KalendarEvent clonedKalendarEvent = (KalendarEvent)XStreamHelper.xstreamClone(kalendarEvent); + if (clonedKalendarEvent.getKalendarEventLinks().size() > 0) { + clonedKalendarEvent.setKalendarEventLinks(new ArrayList<KalendarEventLink>()); } - rootNode.addChild(node); - } - setRootNode(rootNode); + calendarManager.addEventTo(cal, clonedKalendarEvent); + } } + + fireEvent(ureq, Event.DONE_EVENT); } } \ No newline at end of file diff --git a/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java b/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java index ba01ee29d19f6995e1ef77bb45ea23c9c33d8082..4e9aa3b2b208d41e28bd4a908779356f9d85a375 100644 --- a/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java +++ b/src/main/java/org/olat/commons/calendar/ui/KalendarEntryDetailsController.java @@ -151,7 +151,7 @@ public class KalendarEntryDetailsController extends BasicController { if (activeLinkProvider != null) { activeLinkProvider.addControllerListener(this); activeLinkProvider.setKalendarEvent(kalendarEvent); - activeLinkProvider.setDisplayOnly(isReadOnly); + activeLinkProvider.setDisplayOnly(true); linkVC.put("linkprovider", activeLinkProvider.getControler().getInitialComponent()); linkVC.contextPut("hasLinkProvider", Boolean.TRUE); } else { @@ -218,7 +218,7 @@ public class KalendarEntryDetailsController extends BasicController { if (eventForm.isMulti()) { // offer to copy event to multiple calendars. removeAsListenerAndDispose(copyEventToCalendarController); - copyEventToCalendarController = new CopyEventToCalendarController(kalendarEvent, availableCalendars, getTranslator(), getWindowControl()); + copyEventToCalendarController = new CopyEventToCalendarController(ureq, getWindowControl(), kalendarEvent, availableCalendars); listenTo(copyEventToCalendarController); //copyEventToCalendarController.addControllerListener(this); mainPanel.setContent(copyEventToCalendarController.getInitialComponent()); diff --git a/src/main/java/org/olat/commons/calendar/ui/SearchAllCalendarsController.java b/src/main/java/org/olat/commons/calendar/ui/SearchAllCalendarsController.java deleted file mode 100644 index 480c7f4f427f018a305579f1fb98f78c2473f839..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/commons/calendar/ui/SearchAllCalendarsController.java +++ /dev/null @@ -1,177 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ - -package org.olat.commons.calendar.ui; - -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import org.olat.commons.calendar.CalendarManager; -import org.olat.commons.calendar.CalendarUtils; -import org.olat.commons.calendar.GotoDateEvent; -import org.olat.commons.calendar.model.KalendarEvent; -import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.link.Link; -import org.olat.core.gui.components.link.LinkFactory; -import org.olat.core.gui.components.panel.Panel; -import org.olat.core.gui.components.tree.GenericTreeModel; -import org.olat.core.gui.components.tree.GenericTreeNode; -import org.olat.core.gui.components.tree.SelectionTree; -import org.olat.core.gui.components.tree.TreeEvent; -import org.olat.core.gui.components.velocity.VelocityContainer; -import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.Event; -import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.controller.BasicController; -import org.olat.core.util.Formatter; - -public class SearchAllCalendarsController extends BasicController { - - private Collection<KalendarRenderWrapper> calendars; - - private VelocityContainer mainVC; - private Panel panel; - private SearchAllCalendarsForm searchForm; - private SelectionTree eventSelectionTree; - - private Link backLink; - - public SearchAllCalendarsController(UserRequest ureq, WindowControl wControl, - Collection<KalendarRenderWrapper> calendars) { - super(ureq, wControl); - this.calendars = calendars; - - setBasePackage(CalendarManager.class); - - mainVC = createVelocityContainer("calSearchMain"); - backLink = LinkFactory.createLinkBack(mainVC, this); - mainVC.contextPut("displayBackLink", Boolean.FALSE); - panel = new Panel("panel"); - searchForm = new SearchAllCalendarsForm(ureq, wControl); - listenTo(searchForm); - - panel.setContent(searchForm.getInitialComponent()); - mainVC.put("panel", panel); - - this.putInitialPanel(mainVC); - } - - - public void event(UserRequest ureq, Component source, Event event) { - if (source == eventSelectionTree) { - if (event.getCommand().equals(TreeEvent.COMMAND_TREENODE_CLICKED)) { - Date gotoDate = (Date)eventSelectionTree.getSelectedNode().getUserObject(); - fireEvent(ureq, new GotoDateEvent(gotoDate)); - } else { - fireEvent(ureq, Event.CANCELLED_EVENT); - } - } else if (source == backLink) { - if (panel.getContent() == eventSelectionTree) { - mainVC.contextPut("displayBackLink", Boolean.FALSE); - panel.setContent(searchForm.getInitialComponent()); - } - } - } - - public void event(UserRequest ureq, Controller source, Event event) { - if (source == searchForm) { - mainVC.contextPut("displayBackLink", Boolean.TRUE); - if (event == Event.DONE_EVENT) { - eventSelectionTree = new SelectionTree("eventSelection", getTranslator()); - eventSelectionTree.addListener(this); - eventSelectionTree.setFormButtonKey("cal.goto.event"); - eventSelectionTree.setShowCancelButton(true); - eventSelectionTree.setMultiselect(false); - eventSelectionTree.setShowAltTextAsHoverOnTitle(true); - eventSelectionTree.setAllowEmptySelection(false); - eventSelectionTree.setEscapeHtml(false); - GenericTreeNode rootNode = new GenericTreeNode("<b>" + translate("cal.search.results") + "</b>", null); - rootNode.setAccessible(false); - String subject = searchForm.getSubject(); - String location = searchForm.getLocation(); - Date beginPeriod = searchForm.getBeginPeriod(); - Date endPeriod = searchForm.getEndPeriod(); - // search for events and build selection tree model - for (KalendarRenderWrapper kalendarWrapper : calendars) { - // for locally read-only calendars: search only public events, for imported calendar search in private and public events - boolean searchPublicEventsOnly = (kalendarWrapper.getAccess() == KalendarRenderWrapper.ACCESS_READ_ONLY) && !kalendarWrapper.isImported(); - List<KalendarEvent> matchingEvents = CalendarUtils.findEvents(kalendarWrapper.getKalendar(), subject, location, beginPeriod, endPeriod, searchPublicEventsOnly); - if (matchingEvents.size() == 0) continue; - GenericTreeNode calendarNode = new GenericTreeNode("<i>" + translate("cal.form.calendarname") + ": " + kalendarWrapper.getKalendarConfig().getDisplayName() + "</i>", null); - calendarNode.setAccessible(false); - rootNode.addChild(calendarNode); - for (KalendarEvent matchingEvent: matchingEvents) { - StringBuilder display = new StringBuilder(); - String truncatedSubject = matchingEvent.getSubject(); - if (truncatedSubject.length() > CalendarManager.MAX_SUBJECT_DISPLAY_LENGTH) - truncatedSubject = truncatedSubject.substring(0, CalendarManager.MAX_SUBJECT_DISPLAY_LENGTH) + "..."; - display.append(truncatedSubject); - display.append(" ("); - display.append(CalendarUtils.getDateTimeAsString(matchingEvent.getBegin(), getLocale())); - display.append(" - "); - display.append(CalendarUtils.getDateTimeAsString(matchingEvent.getEnd(), getLocale())); - display.append(")"); - GenericTreeNode eventNode = new GenericTreeNode(display.toString(), matchingEvent); - eventNode.setAltText(layoutEventDetails(matchingEvent, kalendarWrapper)); - eventNode.setUserObject(matchingEvent.getBegin()); - if (searchPublicEventsOnly) eventNode.setAccessible(false); - calendarNode.addChild(eventNode); - } - } - if (rootNode.getChildCount() != 0) { - // add matching events to tree - GenericTreeModel treeModel = new GenericTreeModel(); - treeModel.setRootNode(rootNode); - eventSelectionTree.setTreeModel(treeModel); - panel.setContent(eventSelectionTree); - } else { - // no matching events - mainVC.contextPut("displayBackLink", Boolean.FALSE); - this.showInfo("cal.search.noMatches"); - } - } - } - } - - private String layoutEventDetails(KalendarEvent event, KalendarRenderWrapper kalendarWrapper) { - StringBuilder details = new StringBuilder(); - details.append(translate("cal.form.calendarname")).append(": ").append(kalendarWrapper.getKalendarConfig().getDisplayName()).append("<br />"); - details.append(translate("cal.form.begin")).append(": ").append(CalendarUtils.getDateTimeAsString(event.getBegin(), getLocale())).append("<br />"); - details.append(translate("cal.form.end")).append(": ").append(CalendarUtils.getDateTimeAsString(event.getEnd(), getLocale())).append("<br />"); - details.append(translate("cal.form.subject")).append(": ").append(Formatter.escWithBR(event.getSubject()).toString()).append("<br />"); - if (event.getLocation() != null) { - details.append(translate("cal.form.location")).append(": ").append(Formatter.escWithBR(event.getLocation()).toString()).append("<br />"); - } - return details.toString(); - } - - protected void doDispose() { - // nothing to do here - } - -} \ No newline at end of file diff --git a/src/main/java/org/olat/commons/calendar/ui/SearchAllCalendarsForm.java b/src/main/java/org/olat/commons/calendar/ui/SearchAllCalendarsForm.java deleted file mode 100644 index eb8410947c6490df6f2445f0434ac27a12e3541c..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/commons/calendar/ui/SearchAllCalendarsForm.java +++ /dev/null @@ -1,116 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -*/ - -package org.olat.commons.calendar.ui; - -import java.util.Date; - -import org.olat.commons.calendar.CalendarManager; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.form.flexible.FormItemContainer; -import org.olat.core.gui.components.form.flexible.elements.DateChooser; -import org.olat.core.gui.components.form.flexible.elements.TextElement; -import org.olat.core.gui.components.form.flexible.impl.FormBasicController; -import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.Event; -import org.olat.core.gui.control.WindowControl; - - -public class SearchAllCalendarsForm extends FormBasicController { - - private TextElement subject, location; - private DateChooser beginPeriod, endPeriod; - - - public SearchAllCalendarsForm(UserRequest ureq, WindowControl wControl) { - super(ureq, wControl); - - setBasePackage(CalendarManager.class); - - initForm (ureq); - } - - - public boolean validate() { - boolean valid = false; - valid = !subject.isEmpty() || !location.isEmpty(); - Date begin = beginPeriod.getDate(); - Date end = endPeriod.getDate(); - if (begin != null && end != null && begin.after(end)) { - beginPeriod.setErrorKey("cal.search.errorPeriodOverlap", null); - } - if (!valid) { - subject.setErrorKey("cal.search.errorNoParams", null); - return false; - } - return true; - } - - public String getSubject() { - return subject.getValue(); - } - - public String getLocation() { - return location.getValue(); - } - - public Date getBeginPeriod() { - return beginPeriod.getDate(); - } - - public Date getEndPeriod() { - // End period is inclusive, therefore adjust end period by one day - Date end = endPeriod.getDate(); - if (end != null) return new Date(end.getTime() + 24*60*60*1000); - return null; - } - - - @Override - protected void formOK(UserRequest ureq) { - fireEvent (ureq, Event.DONE_EVENT); - } - - - @Override - protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - setFormTitle ("cal.search.title"); - subject = uifactory.addTextElement("cal.search.subject", "cal.search.subject", 40, "", formLayout); - location = uifactory.addTextElement("cal.search.location", "cal.search.location", 40, "", formLayout); - beginPeriod = uifactory.addDateChooser("begin", "cal.search.beginPeriod", null, formLayout); - endPeriod = uifactory.addDateChooser("end", "cal.search.endPeriod", null, formLayout); - - beginPeriod.setExampleKey ("cal.form.recurrence.end.example", null); - endPeriod.setExampleKey ("cal.form.recurrence.end.example", null); - - uifactory.addFormSubmitButton("submit", "cal.search.submit", formLayout); - } - - - @Override - protected void doDispose() { - // - } -} diff --git a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java index ebc3ee3b2faddf8f002bba581d8b1818b86dd876..b6c880376fc86cb7478157ea7565ce58910b75ad 100644 --- a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java +++ b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java @@ -35,7 +35,6 @@ import java.util.List; import org.olat.commons.calendar.CalendarManager; import org.olat.commons.calendar.CalendarManagerFactory; import org.olat.commons.calendar.CalendarUtils; -import org.olat.commons.calendar.GotoDateEvent; import org.olat.commons.calendar.ImportCalendarManager; import org.olat.commons.calendar.model.Kalendar; import org.olat.commons.calendar.model.KalendarComparator; @@ -101,13 +100,11 @@ public class WeeklyCalendarController extends FormBasicController implements Act private KalendarConfigurationController calendarConfig; private ImportedCalendarConfigurationController importedCalendarConfig; private KalendarEntryDetailsController editController; - private SearchAllCalendarsController searchController; private ImportCalendarController importCalendarController; private CalendarSubscription calendarSubscription; private Controller subscriptionController; private String caller; private boolean dirty = false; - private Link searchLink; private FormLink subscribeButton, unsubscribeButton; private CloseableModalController cmc; @@ -409,20 +406,6 @@ public class WeeklyCalendarController extends FormBasicController implements Act } else if (event == ComponentUtil.VALIDATE_EVENT && weeklyCalendar.getComponent().isDirty() && modifiedCalenderDirty ) { KalendarRenderWrapper kalendarRenderWrapper = weeklyCalendar.getKalendarRenderWrapper(modifiedCalendarId); kalendarRenderWrapper.reloadKalendar(); - } else if (source == searchLink) { - - List<KalendarRenderWrapper> allCalendarWrappers = new ArrayList<KalendarRenderWrapper>(calendarWrappers); - allCalendarWrappers.addAll(importedCalendarWrappers); - - removeAsListenerAndDispose(searchController); - searchController = new SearchAllCalendarsController(ureq, getWindowControl(), allCalendarWrappers); - listenTo(searchController); - - removeAsListenerAndDispose(cmc); - cmc = new CloseableModalController(getWindowControl(), translate("close"), searchController.getInitialComponent()); - listenTo(cmc); - - cmc.activate(); } super.event(ureq, source, event); } @@ -473,12 +456,6 @@ public class WeeklyCalendarController extends FormBasicController implements Act setCalendars(calendarWrappers, importedCalendarWrappers); weeklyCalendar.getComponent().setDirty(true); } - } else if (source == searchController) { - if (event instanceof GotoDateEvent) { - Date gotoDate = ((GotoDateEvent)event).getGotoDate(); - weeklyCalendar.setFocusDate(gotoDate); - } - cmc.deactivate(); } else if (source == subscriptionController) { // nothing to do here } else if (source == dbcSequence) { diff --git a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarMapper.java b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarMapper.java index 2849e9645a0182af25e32ed01df5258ba803fa76..788f11e8f4a646d627740181124f35a49219e2e7 100644 --- a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarMapper.java +++ b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarMapper.java @@ -138,7 +138,6 @@ public class FullCalendarMapper implements Mapper { private boolean isInRange(Date from, Date to, KalendarEvent event) { Date end = event.getEnd(); Date begin = event.getBegin(); - System.out.println(begin + " -> " + end); if(begin != null && end != null) { if(from.compareTo(begin) <= 0 && to.compareTo(end) >= 0) { return true; diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java b/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java index aff813dcce72b2f817e2821ab3ea089038ee60ca..ed165078f7bfd0015fe51901fbba85d5a5dc94e1 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java @@ -59,7 +59,7 @@ import org.olat.core.gui.components.form.flexible.impl.elements.FormSubmit; import org.olat.core.gui.components.form.flexible.impl.elements.FormToggleImpl; import org.olat.core.gui.components.form.flexible.impl.elements.IntegerElementImpl; import org.olat.core.gui.components.form.flexible.impl.elements.JSDateChooser; -import org.olat.core.gui.components.form.flexible.impl.elements.MultiSelectionTree; +import org.olat.core.gui.components.form.flexible.impl.elements.MultiSelectionTreeImpl; import org.olat.core.gui.components.form.flexible.impl.elements.MultipleSelectionElementImpl; import org.olat.core.gui.components.form.flexible.impl.elements.SelectboxSelectionImpl; import org.olat.core.gui.components.form.flexible.impl.elements.SingleSelectionImpl; @@ -285,7 +285,7 @@ public class FormUIFactory { * @return */ public MultipleSelectionElement addTreeMultiselect(String name, String i18nLabel, FormItemContainer formLayout, TreeModel treemodel, INodeFilter selectableFilter){ - MultipleSelectionElement mse = new MultiSelectionTree(name, treemodel, selectableFilter); + MultipleSelectionElement mse = new MultiSelectionTreeImpl(name, treemodel, selectableFilter); setLabelIfNotNull(i18nLabel, mse); formLayout.add(mse); return mse; diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultiSelectionTree.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultiSelectionTree.java new file mode 100644 index 0000000000000000000000000000000000000000..275ebe258beb8758a964d3794efc5120db03a16d --- /dev/null +++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/MultiSelectionTree.java @@ -0,0 +1,30 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.gui.components.form.flexible.elements; + +/** + * + * Initial date: 11.07.2014<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface MultiSelectionTree { + +} diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultiSelectionTree.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultiSelectionTreeImpl.java similarity index 92% rename from src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultiSelectionTree.java rename to src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultiSelectionTreeImpl.java index 75f3124a7419f81ab7725bdc4a95c1162416697f..1c56c0a9175815912cb7687fe97dedb1f8df3004 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultiSelectionTree.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/MultiSelectionTreeImpl.java @@ -31,6 +31,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import org.olat.core.gui.components.form.flexible.elements.MultiSelectionTree; import org.olat.core.gui.components.tree.TreeModel; import org.olat.core.gui.components.tree.TreeNode; import org.olat.core.util.tree.INodeFilter; @@ -45,12 +46,12 @@ import org.olat.core.util.tree.TreeHelper; * * @author patrickb */ -public class MultiSelectionTree extends MultipleSelectionElementImpl { +public class MultiSelectionTreeImpl extends MultipleSelectionElementImpl implements MultiSelectionTree { private INodeFilter selectableFilter; private TreeModel treemodel; - public MultiSelectionTree(String name, TreeModel treemodel, INodeFilter selectableFilter) { + public MultiSelectionTreeImpl(String name, TreeModel treemodel, INodeFilter selectableFilter) { super(name); this.selectableFilter = selectableFilter; this.treemodel = treemodel; @@ -88,7 +89,7 @@ public class MultiSelectionTree extends MultipleSelectionElementImpl { String cssClass = tn.getCssClass(); String checkName = getName() + "_" + keys[i]; CheckboxElement ssec = new CheckboxElement(checkName, this, i, null, cssClass); - ssec.setTextOnly(selectableFilter.isSelectable(tn)); + ssec.setEnabled(selectableFilter.isSelectable(tn)); checkboxitems.put(keys[i], ssec); } } @@ -104,7 +105,7 @@ public class MultiSelectionTree extends MultipleSelectionElementImpl { @Override public void reset() { super.reset(); - // set menu tree dirty to render new values + initSelectionElements(); component.setDirty(true); } diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponent.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponent.java index edfab524adc8324defa6c6181cbc759eff24e16f..7be07a15c84438bc79aa0c416f6eaa15cb074da7 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponent.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponent.java @@ -37,7 +37,7 @@ import org.olat.core.util.tree.INodeFilter; */ class SelectionTreeComponent extends MultipleSelectionComponent { - private final MultiSelectionTree selectionElement; + private final MultiSelectionTreeImpl selectionElement; private final TreeModel treeModel; private final INodeFilter selectableFilter; private Map<String, CheckboxElement> subComponents; @@ -46,7 +46,7 @@ class SelectionTreeComponent extends MultipleSelectionComponent { /** * @param name */ - public SelectionTreeComponent(String name, MultiSelectionTree selectionElement, + public SelectionTreeComponent(String name, MultiSelectionTreeImpl selectionElement, TreeModel treeModel, INodeFilter selectableFilter) { super(name, selectionElement); this.selectionElement = selectionElement; @@ -62,7 +62,7 @@ class SelectionTreeComponent extends MultipleSelectionComponent { return RENDERER; } - MultiSelectionTree getSelectionElement() { + MultiSelectionTreeImpl getSelectionElement() { return selectionElement; } diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java index 0399752883f703e5fbd609606579905a40927e5b..5bfb6af80730919289bc3b67b902e83680b911b7 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/SelectionTreeComponentRenderer.java @@ -56,7 +56,10 @@ class SelectionTreeComponentRenderer extends DefaultComponentRenderer { Map<String,CheckboxElement> checkboxes = stc.getSubComponents(); TreeModel tm = stc.getTreeModel(); - TreeNode rootNode = (TreeNode)tm.getRootNode().getChildAt(0); + TreeNode rootNode = tm.getRootNode(); + if(rootNode.getChildCount() == 1) { + rootNode = (TreeNode)rootNode.getChildAt(0); + } INodeFilter selectableFilter = stc.getSelectableFilter(); sb.append("<div class='o_selection_tree'><ul class='o_selection_tree_l0'>"); @@ -110,7 +113,7 @@ class SelectionTreeComponentRenderer extends DefaultComponentRenderer { } private void renderCheckbox(StringOutput sb, TreeNode node, int level, CheckboxElement check, SelectionTreeComponent stc) { - MultiSelectionTree stF = stc.getSelectionElement(); + MultiSelectionTreeImpl stF = stc.getSelectionElement(); String subStrName = "name=\"" + check.getGroupingName() + "\""; @@ -129,19 +132,21 @@ class SelectionTreeComponentRenderer extends DefaultComponentRenderer { String cssClass = check.getCssClass(); //optional CSS class String iconLeftCSS = check.getIconLeftCSS(); - sb.append("<input type='checkbox' id='").append(stc.getFormDispatchId()).append("' ") - .append(subStrName) - .append(" value='").append(key).append("'"); - if (selected) { - sb.append(" checked='checked' "); - } - if(check.isEnabled()){ - //use the selection form dispatch id and not the one of the element! - sb.append(FormJSHelper.getRawJSFor(stF.getRootForm(), check.getSelectionElementFormDispatchId(), check.getAction())); - } else { - sb.append(" disabled='disabled' "); + if(!check.isTextOnly()) { + sb.append("<input type='checkbox' id='").append(stc.getFormDispatchId()).append("' ") + .append(subStrName) + .append(" value='").append(key).append("'"); + if (selected) { + sb.append(" checked='checked' "); + } + if(check.isEnabled()){ + //use the selection form dispatch id and not the one of the element! + sb.append(FormJSHelper.getRawJSFor(stF.getRootForm(), check.getSelectionElementFormDispatchId(), check.getAction())); + } else { + sb.append(" disabled='disabled' "); + } + sb.append(" />"); } - sb.append(" />"); renderNodeIcon(sb, node); if (StringHelper.containsNonWhitespace(iconLeftCSS) || StringHelper.containsNonWhitespace(cssClass)) { sb.append(" <i class='").append(iconLeftCSS, iconLeftCSS != null) diff --git a/src/main/java/org/olat/core/gui/components/tree/SelectionTree.java b/src/main/java/org/olat/core/gui/components/tree/SelectionTree.java index 95e6991e53fa33be5338cba71914e15a0f5b14af..d3fd9953f14c1d4586789b3b66182b1037defc9c 100644 --- a/src/main/java/org/olat/core/gui/components/tree/SelectionTree.java +++ b/src/main/java/org/olat/core/gui/components/tree/SelectionTree.java @@ -26,10 +26,6 @@ package org.olat.core.gui.components.tree; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - import org.olat.core.gui.GUIInterna; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.AbstractComponent; @@ -49,21 +45,15 @@ import org.olat.core.util.tree.TreeHelper; public class SelectionTree extends AbstractComponent { private static final ComponentRenderer RENDERER = new SelectionTreeRenderer(); - private TreeModel treeModel; - private String selectedNodeId = null; // selection of single select - private List<String> selectedNodeIds = null; // selection of multiselect + private String selectedNodeId; // selection of single select private String formButtonKey; private String actionCommand; - private boolean multiselect = false; private boolean allowEmptySelection = false; - private boolean greyOutNonSelectableEntries = false; private boolean showCancelButton = true; - private boolean showAltTextAsHoverOnTitle = false; private boolean escapeHtml = true; private Object userObject; - /** * @param name */ @@ -79,39 +69,19 @@ public class SelectionTree extends AbstractComponent { this.userObject = userObject; } + @Override protected void doDispatchRequest(UserRequest ureq) { selectedNodeId = null; - selectedNodeIds = new ArrayList<String>(); - - int iMode = -1;//0 -> OK, 1 -> CANCEL if (ureq.getParameter(Form.SUBMIT_IDENTIFICATION) != null) { iMode = 0; - if(!multiselect){ - if (GUIInterna.isLoadPerformanceMode()) { - String selPath = ureq.getParameter(SelectionTreeRenderer.ATTR_SELECTION); - TreeNode tn = TreeHelper.resolveTreeNode(selPath, getTreeModel()); - selectedNodeId = tn.getIdent(); - } else { - selectedNodeId = ureq.getParameter(SelectionTreeRenderer.ATTR_SELECTION); - } + if (GUIInterna.isLoadPerformanceMode()) { + String selPath = ureq.getParameter(SelectionTreeRenderer.ATTR_SELECTION); + TreeNode tn = TreeHelper.resolveTreeNode(selPath, getTreeModel()); + selectedNodeId = tn.getIdent(); } else { - Enumeration<String> parameterNames = ureq.getHttpReq().getParameterNames(); - while (parameterNames.hasMoreElements()) { - String parameterName = parameterNames.nextElement(); - if (SelectionTreeRenderer.isMultiSelectParameter(parameterName)) { - String selNodeId = null; - if (GUIInterna.isLoadPerformanceMode()) { - String treePath = ureq.getParameter(parameterName); - TreeNode node = TreeHelper.resolveTreeNode(treePath, getTreeModel()); - selNodeId = node.getIdent(); - } else { - selNodeId = ureq.getParameter(parameterName); - } - selectedNodeIds.add(selNodeId); - } - } + selectedNodeId = ureq.getParameter(SelectionTreeRenderer.ATTR_SELECTION); } } else { iMode = 1; @@ -127,32 +97,12 @@ public class SelectionTree extends AbstractComponent { private void dispatchRequest(UserRequest ureq, int iMode) { //test for recorder if (iMode == 0) { - if (!multiselect) { // grab radio selection value - setDirty(true); - fireEvent(ureq, new TreeEvent(actionCommand == null ? TreeEvent.COMMAND_TREENODE_CLICKED : actionCommand, selectedNodeId)); - } else { // grab checkbox selection values - setDirty(true); - fireEvent(ureq, new TreeEvent(actionCommand == null ? TreeEvent.COMMAND_TREENODES_SELECTED : actionCommand, selectedNodeIds)); - } + setDirty(true); + fireEvent(ureq, new TreeEvent(actionCommand == null ? TreeEvent.COMMAND_TREENODE_CLICKED : actionCommand, selectedNodeId)); } else { fireEvent(ureq, TreeEvent.CANCELLED_TREEEVENT); } } - - /** - * Set wether to grey out non selectable entries in the tree. - * @param b - */ - public void setGreyOutNonSelectableEntries(boolean b) { - this.greyOutNonSelectableEntries = b; - } - - /** - * @return - */ - public boolean getGreyOutNonSelectableEntries() { - return greyOutNonSelectableEntries; - } /** * @return @@ -186,22 +136,6 @@ public class SelectionTree extends AbstractComponent { this.treeModel = treeModel; } - /** - * If set to true, user may select more than one treenode. - * - * @param b - */ - public void setMultiselect(boolean b) { - multiselect = b; - } - - /** - * @return - */ - public boolean isMultiselect() { - return multiselect; - } - /** * @return */ @@ -247,8 +181,6 @@ public class SelectionTree extends AbstractComponent { public boolean isShowCancelButton() { return showCancelButton; } - - public boolean isAllowEmptySelection() { return allowEmptySelection; @@ -257,16 +189,6 @@ public class SelectionTree extends AbstractComponent { public void setAllowEmptySelection(boolean allowEmptySelection) { this.allowEmptySelection = allowEmptySelection; } - - - public boolean isShowAltTextAsHoverOnTitle() { - return showAltTextAsHoverOnTitle; - } - - - public void setShowAltTextAsHoverOnTitle(boolean showAltTextAsHoverOnTitle) { - this.showAltTextAsHoverOnTitle = showAltTextAsHoverOnTitle; - } /** * @@ -279,5 +201,4 @@ public class SelectionTree extends AbstractComponent { protected boolean isEscapeHtml() { return escapeHtml; } - } \ No newline at end of file diff --git a/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java b/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java index c1f6fe33229361edda1cb7b7f879b1d1f0495bdc..fa3b03329f3366701fcc74ba3bf243f037079d8c 100644 --- a/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java +++ b/src/main/java/org/olat/core/gui/components/tree/SelectionTreeRenderer.java @@ -46,11 +46,6 @@ import org.olat.core.util.tree.TreeHelper; * @author Felix Jost */ public class SelectionTreeRenderer extends DefaultComponentRenderer { - - private static String imgDots = "<div class=\"o_selectiontree_line\"></div>"; - private static String imgDots_spacer = "<div class=\"o_selectiontree_space\"></div>"; - private static String imgDots_nt = "<div class=\"o_selectiontree_junction\"></div>"; - private static String imgDots_nl = "<div class=\"o_selectiontree_end\"></div>"; /** * <code>ATTR_SELECTION</code> */ @@ -62,11 +57,6 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { + "\" &&\n" + " document.seltree.elements[i].checked) {\n" + " numselected++;\n" + " }\n" + "}\n" + "if (numselected < 1) {\n alert(\""; - private static final String SCRIPT_MULTI_PRE = "<script type=\"text/javascript\">\n function seltree_check() {\n" - + "var i;\n" + "var numselected = 0;\n" + "for (i=0; document.seltree.elements[i]; i++) {\n" - + " if (document.seltree.elements[i].type == \"checkbox\" &&\n" + " document.seltree.elements[i].checked) {\n" - + " numselected++;\n" + " }\n" + "}\n" + "if (numselected < 1) {\n alert(\""; - private static final String SCRIPT_POST = "\");\n return false;\n" + "}\n" + "return true;\n}\n" + "function checkall(checked) {\n" + @@ -80,15 +70,6 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { "}\n" + "</script>"; - - /** - * Constructor for TableRenderer. Singleton and must be reentrant There must - * be an empty contructor for the Class.forName() call - */ - public SelectionTreeRenderer() { - super(); - } - /** * @param renderer * @param target @@ -98,6 +79,7 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { * @param renderResult * @param args */ + @Override public void render(Renderer renderer, StringOutput target, Component source, URLBuilder ubu, Translator translator, RenderResult renderResult, String[] args) { @@ -105,10 +87,10 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { Translator internalTranslator = tree.getTranslator(); TreeNode root = tree.getTreeModel().getRootNode(); - target.append(tree.isMultiselect() ? SCRIPT_MULTI_PRE : SCRIPT_SINGLE_PRE); + target.append(SCRIPT_SINGLE_PRE); target.append(translator.translate("alert")); target.append(SCRIPT_POST); - target.append("<div class=\"o_selection_tree"); + target.append("<div class=\""); if(StringHelper.containsNonWhitespace(tree.getElementCssClass())) { target.append(" ").append(tree.getElementCssClass()); } @@ -120,25 +102,16 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { if (iframePostEnabled) { ubu.appendTarget(target); } - target.append(" id=\"").append(Form.JSFORMID).append(tree.hashCode()).append("\""); - target.append(">"); - // append root node - renderRootNode(root, target); + target.append(" id=\"").append(Form.JSFORMID).append(tree.hashCode()).append("\"") + .append(">") + .append("<div class='o_selection_tree'><ul class='o_selection_tree_l0'>"); boolean atLeastOneIsAccessible = atLeastOneIsAccessible(root); if (root.getChildCount() != 0) { - renderChildNodes(root, "", tree.hashCode(), tree.isMultiselect(), tree.getGreyOutNonSelectableEntries(), tree.isShowAltTextAsHoverOnTitle(), target, tree); - if (tree.isMultiselect() && atLeastOneIsAccessible) { - target.append("<div class=\"o_togglecheck\"><a href=\"javascript:checkall(true);setFormDirty('").append(Form.JSFORMID).append(tree.hashCode()).append("');\">"); - target.append("<input type=\"checkbox\" checked=\"checked\" disabled=\"disabled\" />"); - target.append(translator.translate("checkall")); - target.append("</a> <a href=\"javascript:checkall(false);setFormDirty('").append(Form.JSFORMID).append(tree.hashCode()).append("\');\">"); - target.append("<input type=\"checkbox\" disabled=\"disabled\" />"); - target.append(translator.translate("uncheckall")); - target.append("</a></div>"); - } + renderNode(root, root, tree.hashCode(), 1, target, tree); + } else { + target.append(internalTranslator.translate("selectiontree.noentries")); } - else target.append(internalTranslator.translate("selectiontree.noentries")); - target.append("<br /><br />"); + target.append("</ul></div><div class='o_button_group'>"); if (atLeastOneIsAccessible && tree.getFormButtonKey() != null) { target.append("<button type=\"submit\" class=\"btn btn-primary o_sel_submit_selection\" name=\"" + Form.SUBMIT_IDENTIFICATION + "\" value=\""); target.append(StringEscapeUtils.escapeHtml(translator.translate(tree.getFormButtonKey()))); @@ -148,14 +121,13 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { target.append("\">"); } target.append(translator.translate(tree.getFormButtonKey())).append("</button>"); - } if(tree.isShowCancelButton()){ target.append(" <button type=\"submit\" class=\"btn btn-default o_sel_cancel_selection\" name=\"" + Form.CANCEL_IDENTIFICATION + "\" value=\""); target.append(StringEscapeUtils.escapeHtml(translator.translate("cancel"))).append("\">"); target.append(translator.translate("cancel")).append("</button>"); } - target.append("</form></div>"); + target.append("</div></form></div>"); } private boolean atLeastOneIsAccessible(TreeNode node) { @@ -166,112 +138,66 @@ public class SelectionTreeRenderer extends DefaultComponentRenderer { } return false; } + + private void renderNode(TreeNode root, TreeNode child, int treeID, + int level, StringOutput sb, SelectionTree tree) { - private void renderRootNode(TreeNode root, StringOutput target) { - target.append("\n<div class=\"o_selectiontree_item\">"); - renderNodeIcon(target, root); - target.append("<div class=\"o_selectiontree_content\">"); - // text using css if available - String cssClass = root.getCssClass(); - if (cssClass != null) target.append("<span class=\"").append(cssClass).append("\">"); - target.append(StringHelper.escapeHtml(root.getTitle())); - if (cssClass != null) target.append("</span>"); - target.append("</div></div>"); - } - - private void renderChildNodes(TreeNode root, String indent, int treeID, boolean multiselect, boolean greyOutNonSelectable, - boolean showAltTextAsHoverOnTitle, StringOutput sb, SelectionTree tree) { - String newIndent = indent + imgDots; + sb.append("<li><div>"); - // extract directories - int childcnt = root.getChildCount(); - for (int i = 0; i < childcnt; i++) { - TreeNode child = (TreeNode) root.getChildAt(i); - // BEGIN of choice div - sb.append("\n<div class=\"o_selectiontree_item\">"); - // render all icons first - // indent and dots-images - sb.append(indent); - if (i < childcnt - 1) { - sb.append(imgDots_nt); + // node title (using css if available) + String cssClass = child.getCssClass(); + + // append radio or checkbox if selectable + if (child.isAccessible()) { + + sb.append("<div class='radio o_tree_l").append(level).append("'>") + .append("<label class='").append(cssClass, cssClass != null).append("'>"); + + sb.append("<input type='radio' name=\"" + ATTR_SELECTION + "\" value=\""); + if (GUIInterna.isLoadPerformanceMode()) { + sb.append(TreeHelper.buildTreePath(child)); } else { - sb.append(imgDots_nl); + sb.append(child.getIdent()); } - // custom icon if available - - sb.append("<div class='o_selectiontree_content'>"); + sb.append("\" onchange=\"return setFormDirty('").append(Form.JSFORMID).append(treeID).append("')\" ") + .append(" onclick=\"return setFormDirty('").append(Form.JSFORMID).append(treeID).append("')\" />"); - // append radio or checkbox if selectable - if (child.isAccessible()) { - if (multiselect) { // render chekcboxes - sb.append("<input type=\"checkbox\" class=\"o_checkbox\" name=\"" + ATTR_SELECTION); - if (GUIInterna.isLoadPerformanceMode()) { - String tPath = TreeHelper.buildTreePath(child); - sb.append(tPath); - } else { - sb.append(child.getIdent()); - } - sb.append("\" "); - if (child.isSelected()) - sb.append("checked "); - sb.append("value=\""); - } else { // render radioboxes - sb.append("<input type=\"radio\" class=\"b_radio\" name=\"" + ATTR_SELECTION + "\" value=\""); - } - if (GUIInterna.isLoadPerformanceMode()) { - sb.append(TreeHelper.buildTreePath(child)); - } else { - sb.append(child.getIdent()); - } - sb.append("\" onchange=\"return setFormDirty('").append(Form.JSFORMID).append(treeID).append("')\" "); - sb.append(" onclick=\"return setFormDirty('").append(Form.JSFORMID).append(treeID).append("')\" />"); + renderNodeIcon(sb, child); + if(tree.isEscapeHtml()) { + sb.append(StringEscapeUtils.escapeHtml(child.getTitle())); + } else { + sb.append(child.getTitle()); } - // node title (using css if available) - String cssClass = child.getCssClass(); - if (cssClass != null) sb.append("<span class=\"").append(cssClass).append("\">"); - if (!child.isAccessible() && greyOutNonSelectable) { - sb.append("<span class=\"o_disabled\">"); - renderNodeIcon(sb, child); - if(tree.isEscapeHtml()) { - sb.append(StringEscapeUtils.escapeHtml(child.getTitle())); - } else { - sb.append(child.getTitle()); - } - sb.append("</span>"); - } else { - if (child.getAltText() != null && showAltTextAsHoverOnTitle) { - sb.append("<span onmouseover=\"o_showEventDetails(' ', '") - .append(child.getAltText()) - .append("');\" onmouseout=\"return nd();\" onclick=\"return nd();\">"); - if(tree.isEscapeHtml()) { - sb.append(StringEscapeUtils.escapeHtml(child.getTitle())); - } else { - sb.append(child.getTitle()); - } - sb.append("</span>"); - } else { - if(tree.isEscapeHtml()) { - sb.append(StringEscapeUtils.escapeHtml(child.getTitle())); - } else { - sb.append(child.getTitle()); - } - } + if(!StringHelper.containsNonWhitespace(child.getTitle())) { + sb.append(" "); } - if (cssClass != null) sb.append("</span>"); renderNodeDecorators(sb, child); - // END of choice div - sb.append("</div></div>"); - - // do the same for all children - if (i < childcnt - 1) { - renderChildNodes(child, newIndent, treeID, multiselect, greyOutNonSelectable, showAltTextAsHoverOnTitle, sb, tree); - } else { - renderChildNodes(child, indent + imgDots_spacer, treeID, multiselect, greyOutNonSelectable, showAltTextAsHoverOnTitle, sb, tree); + sb.append("</label></div>"); + } else { + sb.append("<span class='o_tree_l").append(level).append("'>"); + renderNodeIcon(sb, child); + if(tree.isEscapeHtml()) { + sb.append(StringEscapeUtils.escapeHtml(child.getTitle())); + } else { + sb.append(child.getTitle()); + } + renderNodeDecorators(sb, child); + sb.append("</span>"); + } + sb.append("</div>"); + + int numOfChildren = child.getChildCount(); + if(numOfChildren > 0) { + int childLevel = level + 1; + sb.append("<ul class='o_tree_l").append(childLevel).append("'>"); + for (int i = 0; i < numOfChildren; i++) { + renderNode(root, (TreeNode)child.getChildAt(i), treeID, childLevel, sb, tree); } - - } // for recursion - } // buildTargets - + sb.append("</ul>"); + } + + sb.append("</li>"); + } /** * Renders the node icons if available diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java index 9e6842c8a1b7e80091514ea58baa158716ffa458..5c116244a32405e665c99a7532724c91c261fab5 100644 --- a/src/main/java/org/olat/course/run/RunMainController.java +++ b/src/main/java/org/olat/course/run/RunMainController.java @@ -1237,7 +1237,7 @@ public class RunMainController extends MainLayoutBasicController implements Gene } if (cc.isCalendarEnabled() && !isGuest) { calendarLink = LinkFactory.createToolLink("calendar",translate("command.calendar"), this, "o_icon_calendar"); - calendarLink.setPopup(true);//"950", "750" + calendarLink.setPopup(new LinkPopupSettings(950, 750, "cal")); toolbarPanel.addTool(calendarLink); } if (cc.hasGlossary()) { diff --git a/src/main/java/org/olat/course/run/calendar/CourseLinkProviderController.java b/src/main/java/org/olat/course/run/calendar/CourseLinkProviderController.java index 6cbca62a6811056cbca44cc2ca28290b6defe3f1..6369a9206ada1a3a6589dbae2a7d587c11edf9a1 100644 --- a/src/main/java/org/olat/course/run/calendar/CourseLinkProviderController.java +++ b/src/main/java/org/olat/course/run/calendar/CourseLinkProviderController.java @@ -26,6 +26,7 @@ package org.olat.course.run.calendar; import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -35,94 +36,94 @@ import org.olat.commons.calendar.model.KalendarEvent; import org.olat.commons.calendar.model.KalendarEventLink; import org.olat.commons.calendar.ui.LinkProvider; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.form.flexible.impl.elements.FormSubmit; import org.olat.core.gui.components.tree.GenericTreeModel; import org.olat.core.gui.components.tree.GenericTreeNode; -import org.olat.core.gui.components.tree.SelectionTree; -import org.olat.core.gui.components.tree.TreeEvent; import org.olat.core.gui.components.tree.TreeNode; -import org.olat.core.gui.components.velocity.VelocityContainer; -import org.olat.core.gui.control.ControllerEventListener; +import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; -import org.olat.core.gui.control.controller.BasicController; import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.id.context.ContextEntry; import org.olat.core.util.Util; import org.olat.core.util.nodes.INode; import org.olat.core.util.resource.OresHelper; +import org.olat.core.util.tree.INodeFilter; import org.olat.course.ICourse; import org.olat.course.nodes.CourseNode; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; -public class CourseLinkProviderController extends BasicController implements LinkProvider { +public class CourseLinkProviderController extends FormBasicController implements LinkProvider { private static final String COURSE_LINK_PROVIDER = "COURSE"; - private static final String CAL_LINKS_SUBMIT = "cal.links.submit"; - private VelocityContainer clpVC; private KalendarEvent kalendarEvent; - private SelectionTree selectionTree; + + private FormSubmit saveButton; private final OLATResourceable ores; private final List<ICourse> availableCourses; + private MultipleSelectionElement multiSelectTree; + private final CourseNodeSelectionTreeModel courseNodeTreeModel; public CourseLinkProviderController(ICourse course, List<ICourse> courses, UserRequest ureq, WindowControl wControl) { - super(ureq, wControl, Util.createPackageTranslator(CalendarManager.class, ureq.getLocale())); + super(ureq, wControl, LAYOUT_BAREBONE); + setTranslator(Util.createPackageTranslator(CalendarManager.class, ureq.getLocale(), getTranslator())); this.ores = course; - this.availableCourses = new ArrayList<ICourse>(courses); - - setVelocityRoot(Util.getPackageVelocityRoot(CalendarManager.class)); - clpVC = createVelocityContainer("calCLP"); - selectionTree = new SelectionTree("clpTree", getTranslator()); - selectionTree.addListener(this); - selectionTree.setMultiselect(true); - selectionTree.setAllowEmptySelection(true); - selectionTree.setShowCancelButton(true); - selectionTree.setFormButtonKey(CAL_LINKS_SUBMIT); - selectionTree.setTreeModel(new CourseNodeSelectionTreeModel(courses)); - clpVC.put("tree", selectionTree); - putInitialPanel(clpVC); + availableCourses = new ArrayList<ICourse>(courses); + courseNodeTreeModel = new CourseNodeSelectionTreeModel(courses); + + initForm(ureq); } - public Long getCourseId() { - return ores.getResourceableId(); + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + multiSelectTree = uifactory.addTreeMultiselect("seltree", null, formLayout, courseNodeTreeModel, courseNodeTreeModel); + + FormLayoutContainer buttonsContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + buttonsContainer.setRootForm(mainForm); + formLayout.add(buttonsContainer); + saveButton = uifactory.addFormSubmitButton("ok", "cal.links.submit", buttonsContainer); } - public void event(UserRequest ureq, Component source, Event event) { - if (source == selectionTree) { - TreeEvent te = (TreeEvent)event; - if (event.getCommand().equals(TreeEvent.COMMAND_TREENODES_SELECTED)) { - // rebuild kalendar event links - // we do not use the tree event's getSelectedNodeIDs, instead - // we walk through the model and fetch the children in order - // to keep the sorting. - //fxdiff - List<KalendarEventLink> kalendarEventLinks = kalendarEvent.getKalendarEventLinks(); - TreeNode rootNode = selectionTree.getTreeModel().getRootNode(); - for(Iterator<KalendarEventLink> linkIt = kalendarEventLinks.iterator(); linkIt.hasNext(); ) { - KalendarEventLink link = linkIt.next(); - if(COURSE_LINK_PROVIDER.equals(link.getProvider())) { - linkIt.remove(); - } - } - - clearSelection(rootNode); - rebuildKalendarEventLinks(rootNode, te.getNodeIds(), kalendarEventLinks); - // if the calendarevent is already associated with a calendar, save the modifications. - // otherwise, the modifications will be saver, when the user saves - // the calendar event. - if (kalendarEvent.getCalendar() != null) - CalendarManagerFactory.getInstance().getCalendarManager().addEventTo(kalendarEvent.getCalendar(), kalendarEvent); - fireEvent(ureq, Event.DONE_EVENT); - } else if (event.getCommand().equals(TreeEvent.CANCELLED_TREEEVENT.getCommand())) { - fireEvent(ureq, Event.CANCELLED_EVENT); + @Override + protected void doDispose() { + // + } + + @Override + protected void formOK(UserRequest ureq) { + List<KalendarEventLink> kalendarEventLinks = kalendarEvent.getKalendarEventLinks(); + TreeNode rootNode = courseNodeTreeModel.getRootNode(); + for(Iterator<KalendarEventLink> linkIt = kalendarEventLinks.iterator(); linkIt.hasNext(); ) { + KalendarEventLink link = linkIt.next(); + if(COURSE_LINK_PROVIDER.equals(link.getProvider())) { + linkIt.remove(); } } + + clearSelection(rootNode); + Collection<String> nodeIds = multiSelectTree.getSelectedKeys(); + rebuildKalendarEventLinks(rootNode, nodeIds, kalendarEventLinks); + // if the calendarevent is already associated with a calendar, save the modifications. + // otherwise, the modifications will be saver, when the user saves + // the calendar event. + if (kalendarEvent.getCalendar() != null) { + CalendarManagerFactory.getInstance().getCalendarManager().addEventTo(kalendarEvent.getCalendar(), kalendarEvent); + } + fireEvent(ureq, Event.DONE_EVENT); + } + + public Long getCourseId() { + return ores.getResourceableId(); } - private void rebuildKalendarEventLinks(INode node, List<String> selectedNodeIDs, List<KalendarEventLink> kalendarEventLinks) { + private void rebuildKalendarEventLinks(INode node, Collection<String> selectedNodeIDs, List<KalendarEventLink> kalendarEventLinks) { if (selectedNodeIDs.contains(node.getIdent()) && node instanceof LinkTreeNode) { // assemble link LinkTreeNode treeNode = (LinkTreeNode)node; @@ -147,41 +148,36 @@ public class CourseLinkProviderController extends BasicController implements Lin } } - protected void doDispose() { - // - } - + @Override public CourseLinkProviderController getControler() { return this; } + @Override public void setKalendarEvent(KalendarEvent kalendarEvent) { this.kalendarEvent = kalendarEvent; - clearSelection(selectionTree.getTreeModel().getRootNode()); + clearSelection(courseNodeTreeModel.getRootNode()); for (KalendarEventLink link: kalendarEvent.getKalendarEventLinks()) { - if (!link.getProvider().equals(COURSE_LINK_PROVIDER)) continue; - String nodeId = link.getId(); - TreeNode node = selectionTree.getTreeModel().getNodeById(nodeId); - if(node == null) { - nodeId = availableCourses.get(0).getResourceableId() + "_" + nodeId; - node = selectionTree.getTreeModel().getNodeById(nodeId); - } - if (node != null) { - node.setSelected(true); + if (link.getProvider().equals(COURSE_LINK_PROVIDER)) { + String nodeId = link.getId(); + TreeNode node = courseNodeTreeModel.getNodeById(nodeId); + if(node == null) { + nodeId = availableCourses.get(0).getResourceableId() + "_" + nodeId; + node = courseNodeTreeModel.getNodeById(nodeId); + } + if (node != null) { + node.setSelected(true); + multiSelectTree.select(node.getIdent(), true); + } } } } + @Override public void setDisplayOnly(boolean displayOnly) { - if (displayOnly) { - clpVC.contextPut("displayOnly", Boolean.TRUE); - selectionTree.setVisible(false); - clpVC.contextPut("links", kalendarEvent.getKalendarEventLinks()); - } else { - clpVC.contextPut("displayOnly", Boolean.FALSE); - selectionTree.setVisible(true); - clpVC.contextRemove("links"); - } + courseNodeTreeModel.setReadOnly(displayOnly); + multiSelectTree.reset(); + saveButton.setVisible(!displayOnly); } private void clearSelection(TreeNode node) { @@ -191,39 +187,43 @@ public class CourseLinkProviderController extends BasicController implements Lin clearSelection(childNode); } } - - public void addControllerListener(ControllerEventListener controller) { - super.addControllerListener(controller); - } - private static class CourseNodeSelectionTreeModel extends GenericTreeModel { + private static class CourseNodeSelectionTreeModel extends GenericTreeModel implements INodeFilter { private static final long serialVersionUID = -7863033366847344767L; + + private boolean readOnly; + + public CourseNodeSelectionTreeModel(List<ICourse> courses) { if(courses.size() == 1) { ICourse course = courses.get(0); - setRootNode(buildTree(course, course.getRunStructure().getRootNode())); + setRootNode(buildCourseTree(course)); } else { LinkTreeNode rootNode = new LinkTreeNode("", null, null); for(ICourse course:courses) { - LinkTreeNode node = new LinkTreeNode(course.getCourseTitle(), course, null); - node.setAltText(course.getCourseTitle()); - node.setIdent(course.getResourceableId().toString()); - node.setIconCssClass("o_CourseModule_icon"); - - LinkTreeNode childNode = buildTree(course, course.getRunStructure().getRootNode()); - node.addChild(childNode); - rootNode.addChild(node); + rootNode.addChild(buildCourseTree(course)); } setRootNode(rootNode); } } + + private LinkTreeNode buildCourseTree(ICourse course) { + LinkTreeNode node = new LinkTreeNode(course.getCourseTitle(), course, null); + node.setAltText(course.getCourseTitle()); + node.setIdent(course.getResourceableId().toString()); + node.setIconCssClass("o_CourseModule_icon"); + + LinkTreeNode childNode = buildTree(course, course.getRunStructure().getRootNode()); + node.addChild(childNode); + return node; + } private LinkTreeNode buildTree(ICourse course, CourseNode courseNode) { LinkTreeNode node = new LinkTreeNode(courseNode.getShortTitle(), course, courseNode); node.setAltText(courseNode.getLongTitle()); node.setIdent(course.getResourceableId() + "_" + courseNode.getIdent()); - node.setIconCssClass(("o_" + courseNode.getType() + "_icon").intern()); + node.setIconCssClass(("o_icon o_" + courseNode.getType() + "_icon").intern()); node.setUserObject(course); for (int i = 0; i < courseNode.getChildCount(); i++) { CourseNode childNode = (CourseNode)courseNode.getChildAt(i); @@ -231,6 +231,20 @@ public class CourseLinkProviderController extends BasicController implements Lin } return node; } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + + @Override + public boolean isSelectable(INode node) { + return !readOnly; + } + + @Override + public boolean isVisible(INode node) { + return true; + } } private static class LinkTreeNode extends GenericTreeNode { diff --git a/src/main/java/org/olat/modules/qpool/ui/metadata/GeneralMetadataEditController.java b/src/main/java/org/olat/modules/qpool/ui/metadata/GeneralMetadataEditController.java index 4218343c08fbda61841c8c39d5e41e82d3e05fd7..5904deac0bf8b30026d9ea839945560a2fa8a7ec 100644 --- a/src/main/java/org/olat/modules/qpool/ui/metadata/GeneralMetadataEditController.java +++ b/src/main/java/org/olat/modules/qpool/ui/metadata/GeneralMetadataEditController.java @@ -186,7 +186,6 @@ public class GeneralMetadataEditController extends FormBasicController { selectPathCmp = new SelectionTree("taxPathSelection", getTranslator()); selectPathCmp.addListener(this); - selectPathCmp.setMultiselect(false); selectPathCmp.setFormButtonKey("select"); selectPathCmp.setShowCancelButton(true); TaxonomyTreeModel treeModel = new TaxonomyTreeModel(""); diff --git a/src/main/java/org/olat/modules/qpool/ui/metadata/MetadataBulkChangeController.java b/src/main/java/org/olat/modules/qpool/ui/metadata/MetadataBulkChangeController.java index 344068c923e88d0d79e932178ce7f91e12af1a0d..ec0c14239baae0b54ade2ef908f1fb4345b376fd 100644 --- a/src/main/java/org/olat/modules/qpool/ui/metadata/MetadataBulkChangeController.java +++ b/src/main/java/org/olat/modules/qpool/ui/metadata/MetadataBulkChangeController.java @@ -349,7 +349,6 @@ public class MetadataBulkChangeController extends FormBasicController { private void doOpenSelection() { selectPathCmp = new SelectionTree("taxPathSelection", getTranslator()); selectPathCmp.addListener(this); - selectPathCmp.setMultiselect(false); selectPathCmp.setFormButtonKey("select"); selectPathCmp.setShowCancelButton(true); TaxonomyTreeModel treeModel = new TaxonomyTreeModel(""); diff --git a/src/main/webapp/static/themes/light/modules/_tree.scss b/src/main/webapp/static/themes/light/modules/_tree.scss index 781cd80d1afe42a6b5fdab240fbbc9e256256f83..9bd6adc84b5e1ef01acb3dcf5554c5081dd37445 100644 --- a/src/main/webapp/static/themes/light/modules/_tree.scss +++ b/src/main/webapp/static/themes/light/modules/_tree.scss @@ -168,7 +168,7 @@ } @for $i from 0 through 11 { - li>div>span.o_tree_l#{$i}, li>div>div.checkbox.o_tree_l#{$i} { + li>div>span.o_tree_l#{$i}, li>div>div.checkbox.o_tree_l#{$i}, li>div>div.radio.o_tree_l#{$i} { display:block; padding: $o-tree-padding-vertical 2px $o-tree-padding-vertical ($o-tree-padding-horizontal_root_visible + ($i * $o-tree-padding-steps-px)); z-index:9; diff --git a/src/main/webapp/static/themes/light/theme.css b/src/main/webapp/static/themes/light/theme.css index 7828e43825a666bc4077a2326e73f34e58fa4990..f2cd71b8b3d265f9d2e0cc2f9187cc30a2d310eb 100644 --- a/src/main/webapp/static/themes/light/theme.css +++ b/src/main/webapp/static/themes/light/theme.css @@ -63,7 +63,7 @@ fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100% #o_share{margin-top:10px;font-size:14px}#o_share a{margin:0 3px 0 0;opacity:0.6;filter:alpha(opacity=60)}#o_share a:hover{opacity:1;filter:alpha(opacity=100)}#o_navbar_wrapper{z-index:4}#o_navbar_wrapper #o_navbar_container{position:relative}#o_navbar_wrapper #o_navbar_container a.o_navbar-brand{font-size:40px;vertical-align:top;font-weight:bold;color:#31729B}#o_navbar_wrapper #o_navbar_container a.o_navbar-brand:after{content:"\221E"}.o_navbar .o_navbar_tabs li a{padding-right:30px}.o_navbar .o_navbar_tabs .o_navbar_tab_close{position:absolute;top:15px;right:0.5em;padding:0;width:1em;height:1em}.o_navbar .o_navbar_tabs .o_navbar_tab_close i:before{color:#A87E7E}.o_navbar .o_navbar_tabs .o_navbar_tab_close:hover i:before{color:#CC0000}.o_navbar #o_navbar_tools_permanent #o_navbar_langchooser{color:#777;padding:7px 15px}.o_navbar #o_navbar_tools_permanent #o_navbar_langchooser form span+div{display:inline}.o_navbar #o_navbar_tools_permanent #o_navbar_help a i{margin-right:0.4em}@media (max-width: 767px){.o_navbar #o_navbar_tools_permanent #o_navbar_impress a span{display:none}}.o_navbar #o_navbar_tools_personal .o_navbar_tool a{padding-right:5px}.o_navbar #o_navbar_tools_personal #o_navbar_my_menu .dropdown-toggle{padding-left:45px}.o_navbar #o_navbar_tools_personal #o_navbar_my_menu .o_portrait{position:absolute;left:7px;top:10px}.o_navbar #o_navbar_tools_personal .o_logout{color:#d9534f}.o_navbar.o_navbar-offcanvas .o_navbar_tab_close{top:10px}.o_navbar.o_navbar-offcanvas .o_navbar_tool{display:none}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu a{color:#777}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu a:hover,.o_navbar.o_navbar-offcanvas #o_navbar_my_menu a:focus{color:#fff;background-color:transparent}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu a.o_logout{color:#d9534f}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu a.o_logout:hover,.o_navbar.o_navbar-offcanvas #o_navbar_my_menu a.o_logout:focus{color:#d9534f}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu .dropdown-header{padding-left:15px}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu .dropdown-toggle{display:none}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu .dropdown-menu{box-shadow:none;position:relative;top:0;left:0;display:block;float:none;background-color:#222;color:#777;font-size:14px}.o_navbar.o_navbar-offcanvas #o_navbar_my_menu .dropdown-menu .divider{background:none}.o_navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}.o_navbar:before,.o_navbar:after{content:" ";display:table}.o_navbar:after{clear:both}.o_navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.o_navbar-collapse:before,.o_navbar-collapse:after{content:" ";display:table}.o_navbar-collapse:after{clear:both}.o_navbar-collapse.o_collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.o_navbar-offcanvas .o_navbar-collapse{width:auto;border-top:0;box-shadow:none;margin-top:10px;margin-right:-15px;margin-left:-15px}.o_navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.o_navbar-brand:hover,.o_navbar-brand:focus{text-decoration:none}.o_navbar-toggle{position:relative;margin-right:15px;margin-left:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.o_navbar-toggle:focus{outline:none}.o_navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.o_navbar-toggle .icon-bar+.icon-bar{margin-top:4px}#o_navbar_left-toggle{float:left}#o_navbar_right-toggle{float:right}.o_navbar-nav{margin:7.5px -15px}.o_navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}.o_collapse .o_navbar-nav{float:left;margin:0}.o_collapse .o_navbar-nav>li{float:left}.o_collapse .o_navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.o_collapse .o_navbar-nav.o_navbar-right:last-child{margin-right:-15px}.o_collapse.o_navbar-collapse .o_navbar-left{float:left !important}.o_collapse.o_navbar-collapse .o_navbar-right{float:right !important}.o_navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:8px;margin-bottom:8px}@media (max-width: 767px){.o_navbar-form .form-group{margin-bottom:5px}} .o_collapse .o_navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.o_collapse .o_navbar-form.o_navbar-right:last-child{margin-right:-15px}.o_navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.o_navbar-fixed-bottom .o_navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.o_navbar-btn{margin-top:8px;margin-bottom:8px}.o_navbar-btn.btn-sm,.btn-group-sm>.o_navbar-btn.btn{margin-top:10px;margin-bottom:10px}.o_navbar-btn.btn-xs,.btn-group-xs>.o_navbar-btn.btn{margin-top:14px;margin-bottom:14px}.o_navbar-text{margin-top:15px;margin-bottom:15px}.o_collapse .o_navbar-text{float:left;margin-left:15px;margin-right:15px}.o_collapse .o_navbar-text.o_navbar-right:last-child{margin-right:0}.o_navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.o_navbar-default .o_navbar-brand{color:#777}.o_navbar-default .o_navbar-brand:hover,.o_navbar-default .o_navbar-brand:focus{color:#5e5e5e;background-color:transparent}.o_navbar-default .o_navbar-text{color:#777}.o_navbar-default .o_navbar-nav>li>a{color:#777}.o_navbar-default .o_navbar-nav>li>a:hover,.o_navbar-default .o_navbar-nav>li>a:focus{color:#333;background-color:transparent}.o_navbar-default .o_navbar-nav>.active>a,.o_navbar-default .o_navbar-nav>.active>a:hover,.o_navbar-default .o_navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.o_navbar-default .o_navbar-nav>.disabled>a,.o_navbar-default .o_navbar-nav>.disabled>a:hover,.o_navbar-default .o_navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.o_navbar-default .o_navbar-toggle{border-color:#ddd}.o_navbar-default .o_navbar-toggle:hover,.o_navbar-default .o_navbar-toggle:focus{background-color:#ddd}.o_navbar-default .o_navbar-toggle .icon-bar{background-color:#888}.o_navbar-default .o_navbar-collapse,.o_navbar-default .o_navbar-form{border-color:#e7e7e7}.o_navbar-default .o_navbar-nav>.open>a,.o_navbar-default .o_navbar-nav>.open>a:hover,.o_navbar-default .o_navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}.o_navbar-default .o_navbar-link{color:#777}.o_navbar-default .o_navbar-link:hover{color:#333}.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>li>a{color:#777}.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>li>a:hover,.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>.active>a,.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>.active>a:hover,.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>.disabled>a,.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>.disabled>a:hover,.o_navbar-offcanvas.o_navbar-default .o_navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}.o_navbar-inverse{background-color:#222;border-color:#090909}.o_navbar-inverse .o_navbar-brand{color:#777}.o_navbar-inverse .o_navbar-brand:hover,.o_navbar-inverse .o_navbar-brand:focus{color:#fff;background-color:transparent}.o_navbar-inverse .o_navbar-text{color:#777}.o_navbar-inverse .o_navbar-nav>li>a{color:#777}.o_navbar-inverse .o_navbar-nav>li>a:hover,.o_navbar-inverse .o_navbar-nav>li>a:focus{color:#fff;background-color:transparent}.o_navbar-inverse .o_navbar-nav>.active>a,.o_navbar-inverse .o_navbar-nav>.active>a:hover,.o_navbar-inverse .o_navbar-nav>.active>a:focus{color:#fff;background-color:#090909}.o_navbar-inverse .o_navbar-nav>.disabled>a,.o_navbar-inverse .o_navbar-nav>.disabled>a:hover,.o_navbar-inverse .o_navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.o_navbar-inverse .o_navbar-toggle{border-color:#333}.o_navbar-inverse .o_navbar-toggle:hover,.o_navbar-inverse .o_navbar-toggle:focus{background-color:#333}.o_navbar-inverse .o_navbar-toggle .icon-bar{background-color:#fff}.o_navbar-inverse .o_navbar-collapse,.o_navbar-inverse .o_navbar-form{border-color:#101010}.o_navbar-inverse .o_navbar-nav>.open>a,.o_navbar-inverse .o_navbar-nav>.open>a:hover,.o_navbar-inverse .o_navbar-nav>.open>a:focus{background-color:#090909;color:#fff}.o_navbar-inverse .o_navbar-nav .o_navbar-link{color:#777}.o_navbar-inverse .o_navbar-nav .o_navbar-link:hover{color:#fff}.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#090909}.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu .divider{background-color:#090909}.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>li>a{color:#777}.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>li>a:hover,.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.active>a,.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.active>a:hover,.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#090909}.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.disabled>a,.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.disabled>a:hover,.o_navbar-inverse .o_navbar-offcanvas.o_navbar-inverse .o_navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}.o_toolbar{position:relative;min-height:37px;margin-bottom:20px;border:1px solid transparent;background-color:#f8f8f8;border-color:#e7e7e7;text-align:center;min-height:37px}.o_toolbar:before,.o_toolbar:after{content:" ";display:table}.o_toolbar:after{clear:both}@media (min-width: 768px){.o_toolbar{border-radius:4px}}.o_toolbar a{color:#777;display:inline-block}.o_toolbar a:hover{color:#333}.o_toolbar .o_breadcrumb{float:left;margin-top:4px;margin-bottom:2px;padding-right:5px;padding-left:5px;padding-top:3px;border-right:1px solid #e7e7e7;margin-right:15px;margin-left:-15px}.o_toolbar .o_breadcrumb i{font-size:18px}.o_toolbar .o_breadcrumb .o_history.o_tool_dropdown i{font-size:14px}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_breadcrumb{margin-top:3px;margin-bottom:2px;padding-top:3px}.o_toolbar .o_breadcrumb i{font-size:16px}.o_toolbar .o_breadcrumb .o_history.o_tool_dropdown i{font-size:12px}}@media (max-width: 767px){.o_toolbar .o_breadcrumb{margin-top:6px;margin-bottom:4px;padding-top:0}.o_toolbar .o_breadcrumb i{font-size:20px}.o_toolbar .o_breadcrumb .o_history{display:none}}.o_toolbar .o_tools_close{float:right;position:relative;margin:8px -15px 5px 15px;border-left:1px solid #e7e7e7;padding-right:5px;padding-left:5px;vertical-align:middle}.o_toolbar .o_tools_close a{line-height:37px;color:#d9534f}.o_toolbar .o_tools_close a:hover{color:#b52b27}.o_toolbar .o_tools_close a i{font-size:18px}.o_toolbar .o_tools_close a span{display:none}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_tools_close{margin-top:6px;margin-bottom:4px}.o_toolbar .o_tools_close a{line-height:35px}.o_toolbar .o_tools_close a i{font-size:16px}}@media (max-width: 767px){.o_toolbar .o_tools_close{min-height:22px;margin-top:6px;margin-bottom:4px}.o_toolbar .o_tools_close a{line-height:22px}.o_toolbar .o_tools_close a i{font-size:20px}}.o_toolbar .o_tools{margin-top:8px;margin-bottom:5px}.o_toolbar .o_tool,.o_toolbar .o_text{position:relative;margin:0 10px}.o_toolbar .o_tool a i,.o_toolbar .o_tool .o_disabled i,.o_toolbar .o_text a i,.o_toolbar .o_text .o_disabled i{font-size:18px}.o_toolbar .o_tool a span,.o_toolbar .o_tool .o_disabled span,.o_toolbar .o_text a span,.o_toolbar .o_text .o_disabled span{display:block;font-size:12px}.o_toolbar .o_tool a span.badge,.o_toolbar .o_tool .o_disabled span.badge,.o_toolbar .o_text a span.badge,.o_toolbar .o_text .o_disabled span.badge{position:absolute;right:50%;top:-24px;margin-right:-12px;font-size:13px}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_tool a i,.o_toolbar .o_tool .o_disabled i,.o_toolbar .o_text a i,.o_toolbar .o_text .o_disabled i{font-size:16px}.o_toolbar .o_tool a span,.o_toolbar .o_tool .o_disabled span,.o_toolbar .o_text a span,.o_toolbar .o_text .o_disabled span{font-size:11px}.o_toolbar .o_tool a span.badge,.o_toolbar .o_tool .o_disabled span.badge,.o_toolbar .o_text a span.badge,.o_toolbar .o_text .o_disabled span.badge{top:-22px;margin-right:-11px;font-size:12px}}@media (max-width: 767px){.o_toolbar .o_tool a i,.o_toolbar .o_tool .o_disabled i,.o_toolbar .o_text a i,.o_toolbar .o_text .o_disabled i{font-size:20px}.o_toolbar .o_tool a span,.o_toolbar .o_tool .o_disabled span,.o_toolbar .o_text a span,.o_toolbar .o_text .o_disabled span{display:none}.o_toolbar .o_tool a span.badge,.o_toolbar .o_tool .o_disabled span.badge,.o_toolbar .o_text a span.badge,.o_toolbar .o_text .o_disabled span.badge{display:block;position:relative;top:0;left:0}}.o_toolbar .o_tool .o_chelp,.o_toolbar .o_text .o_chelp{position:relative;top:-1em;vertical-align:top}.o_toolbar .o_tool_dropdown{position:relative}.o_toolbar .o_tool_dropdown a.dropdown-toggle i{font-size:18px}.o_toolbar .o_tool_dropdown a.dropdown-toggle span{display:block;font-size:12px}.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{position:absolute;right:50%;top:4px;margin-right:-20px;font-size:14px}@media (min-width: 767px) and (max-width: 991px){.o_toolbar .o_tool_dropdown a.dropdown-toggle i{font-size:16px}.o_toolbar .o_tool_dropdown a.dropdown-toggle span,.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{font-size:11px}.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{top:4px;margin-right:-18px;font-size:12px}}@media (max-width: 767px){.o_toolbar .o_tool_dropdown a.dropdown-toggle i{font-size:20px}.o_toolbar .o_tool_dropdown a.dropdown-toggle span,.o_toolbar .o_tool_dropdown a.dropdown-toggle .o_icon_caret{display:none}}.o_toolbar .o_tool_dropdown .dropdown-menu{text-align:left}.o_toolbar .o_tools_left{float:left}.o_toolbar .o_tools_right{float:right}@media (max-width: 991px){.o_toolbar{min-height:35px}.o_toolbar .o_tools{margin-top:6px;margin-bottom:4px}.o_toolbar .o_tool span{max-width:10em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media (max-width: 767px){.o_toolbar{min-height:22px;text-align:left}.o_toolbar .o_tools{margin-top:6px;margin-bottom:4px}.o_toolbar .o_tools .o_chelp{top:0;vertical-align:top}.o_toolbar .o_tools_right,.o_toolbar .o_tools_center{float:left}} body{overflow-x:hidden}.o_container_offcanvas{position:relative;max-width:1324px;-webkit-transition:all .25s ease-in-out;-moz-transition:all .25s ease-in-out;-o-transition:all .25s ease-in-out;-m-transition:all .25s ease-in-out;transition:all .25s ease-in-out}@media screen and (min-width: 1324px) and (max-width: 1574px){body.o_offcanvas_right_visible .o_container_offcanvas{left:-125px;max-width:1074px}}@media screen and (min-width: 1574px) and (max-width: 1824px){body.o_offcanvas_right_visible .o_container_offcanvas{left:-125px}}#o_offcanvas_right{position:absolute;top:0;right:-250px;width:250px;padding:15px 15px;background-color:#222;color:#777;border:1px solid #090909;-webkit-box-shadow:0px 0px 4px 3px rgba(0,0,0,0.25);box-shadow:0px 0px 4px 3px rgba(0,0,0,0.25);min-height:100%;z-index:10;display:none}#o_offcanvas_right:before,#o_offcanvas_right:after{content:" ";display:table}#o_offcanvas_right:after{clear:both}@media screen and (max-width: 767px){.row-offcanvas{position:relative;-webkit-transition:all .25s ease-out;-moz-transition:all .25s ease-out;transition:all .25s ease-out}.row-offcanvas-right{right:0}.row-offcanvas-right .sidebar-offcanvas{right:-50%}.row-offcanvas-right.active{right:50%}.row-offcanvas-left{left:0}.row-offcanvas-left .sidebar-offcanvas{left:-50%}.row-offcanvas-left.active{left:50%}.sidebar-offcanvas{position:absolute;top:0;width:50%}}.o_info,.o_form .o_info,.o_togglebox_wrapper div.o_togglebox_content,div.o_qti_item_itemfeedback{margin:20px 0;padding:20px;border-left:3px solid #d4d4d4;background-color:#eee}.o_info h2,.o_info h3,.o_info h4,.o_info .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_info h2,.o_info h5,.o_form .o_info h2,.o_togglebox_wrapper div.o_togglebox_content h2,div.o_qti_item_itemfeedback h2,.o_form .o_info h3,.o_togglebox_wrapper div.o_togglebox_content h3,div.o_qti_item_itemfeedback h3,.o_form .o_info h4,.o_togglebox_wrapper div.o_togglebox_content h4,div.o_qti_item_itemfeedback h4,.o_form .o_info .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_form .o_info h2,.o_togglebox_wrapper div.o_togglebox_content .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_togglebox_wrapper div.o_togglebox_content h2,div.o_qti_item_itemfeedback .o_cal .fc-header-title h2,.o_cal .fc-header-title div.o_qti_item_itemfeedback h2,.o_form .o_info h5,.o_togglebox_wrapper div.o_togglebox_content h5,div.o_qti_item_itemfeedback h5{color:#d4d4d4}.o_note,.o_form .o_desc,.o_course_run .o_statusinfo,.o_course_stats .o_desc{margin:20px 0;padding:20px;border-left:3px solid #5bc0de;background-color:#f4f8fa}.o_note h2,.o_note h3,.o_note h4,.o_note .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_note h2,.o_note h5,.o_form .o_desc h2,.o_course_run .o_statusinfo h2,.o_course_stats .o_desc h2,.o_form .o_desc h3,.o_course_run .o_statusinfo h3,.o_course_stats .o_desc h3,.o_form .o_desc h4,.o_course_run .o_statusinfo h4,.o_course_stats .o_desc h4,.o_form .o_desc .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_form .o_desc h2,.o_course_run .o_statusinfo .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_course_run .o_statusinfo h2,.o_course_stats .o_desc .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_course_stats .o_desc h2,.o_form .o_desc h5,.o_course_run .o_statusinfo h5,.o_course_stats .o_desc h5{color:#5bc0de}.o_important,.o_bc_empty,.o_course_run .o_no_scoreinfo{margin:20px 0;padding:20px;border-left:3px solid #f4d000;background-color:#fff1a4}.o_important h2,.o_important h3,.o_important h4,.o_important .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_important h2,.o_important h5,.o_bc_empty h2,.o_course_run .o_no_scoreinfo h2,.o_bc_empty h3,.o_course_run .o_no_scoreinfo h3,.o_bc_empty h4,.o_course_run .o_no_scoreinfo h4,.o_bc_empty .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_bc_empty h2,.o_course_run .o_no_scoreinfo .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_course_run .o_no_scoreinfo h2,.o_bc_empty h5,.o_course_run .o_no_scoreinfo h5{color:#f4d000}.o_success{margin:20px 0;padding:20px;border-left:3px solid #3c763d;background-color:#d6e9c6}.o_success h2,.o_success h3,.o_success h4,.o_success .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_success h2,.o_success h5{color:#3c763d}.o_warning,.o_form .o_warning{margin:20px 0;padding:20px;border-left:3px solid #ff9e3e;background-color:#ffd5aa}.o_warning h2,.o_warning h3,.o_warning h4,.o_warning .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_warning h2,.o_warning h5,.o_form .o_warning h2,.o_form .o_warning h3,.o_form .o_warning h4,.o_form .o_warning .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_form .o_warning h2,.o_form .o_warning h5{color:#ff9e3e}.o_error{margin:20px 0;padding:20px;border-left:3px solid #d9534f;background-color:#fdf7f7}.o_error h2,.o_error h3,.o_error h4,.o_error .o_cal .fc-header-title h2,.o_cal .fc-header-title .o_error h2,.o_error h5{color:#d9534f}div.o_callout_overlay{position:fixed;top:0;left:0;width:100%;height:100%;zoom:1;background:#000;opacity:0;filter:alpha(opacity=0)}.o_alert_info{position:fixed;top:-100%;left:0;display:none;z-index:2000;width:100%;text-align:center}.o_alert_info .alert{position:relative;width:auto;margin:0 auto;text-align:left;-webkit-box-shadow:0px 1px 5px -1px rgba(0,0,0,0.15);box-shadow:0px 1px 5px -1px rgba(0,0,0,0.15)}.o_alert_info .alert .o_icon_close{float:right;color:#777}.o_alert_info .alert .o_icon_close:hover{color:#555}@media (min-width: 768px){.o_alert_info .alert{width:600px}} -#o_msg_sticky,#o_msg_sticky_preview{position:relative;color:#a94442;background-color:#f2dede;border:1px solid #ebccd1;padding:10px 16px 10px 60px;min-height:40px;margin:-20px 0 20px 0}#o_msg_sticky .o_icon_info_msg,#o_msg_sticky_preview .o_icon_info_msg{position:absolute;left:10px;top:5px;font-size:40px}.o_tree{position:relative;display:block;background-color:none;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow:hidden;font-size:14px}.o_tree a{color:#777;background-color:none}.o_tree a:hover,.o_tree a:focus{color:#333;background-color:#f8f8f8}.o_tree ul{margin:0;padding:0;list-style-type:none}.o_tree ul li{margin:0;padding:0;white-space:nowrap}.o_tree ul li div{position:relative;margin-bottom:-1px;border-bottom:1px solid #ddd}.o_tree ul li div a.o_tree_oc_l0{position:absolute;top:10px;left:-4px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l0,.o_tree ul .o_tree_level_close.b_tree_oc_l0{z-index:10}.o_tree ul li div a.o_tree_oc_l1{position:absolute;top:10px;left:11px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l1,.o_tree ul .o_tree_level_close.b_tree_oc_l1{z-index:10}.o_tree ul li div a.o_tree_oc_l2{position:absolute;top:10px;left:26px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l2,.o_tree ul .o_tree_level_close.b_tree_oc_l2{z-index:10}.o_tree ul li div a.o_tree_oc_l3{position:absolute;top:10px;left:41px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l3,.o_tree ul .o_tree_level_close.b_tree_oc_l3{z-index:10}.o_tree ul li div a.o_tree_oc_l4{position:absolute;top:10px;left:56px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l4,.o_tree ul .o_tree_level_close.b_tree_oc_l4{z-index:10}.o_tree ul li div a.o_tree_oc_l5{position:absolute;top:10px;left:71px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l5,.o_tree ul .o_tree_level_close.b_tree_oc_l5{z-index:10}.o_tree ul li div a.o_tree_oc_l6{position:absolute;top:10px;left:86px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l6,.o_tree ul .o_tree_level_close.b_tree_oc_l6{z-index:10}.o_tree ul li div a.o_tree_oc_l7{position:absolute;top:10px;left:101px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l7,.o_tree ul .o_tree_level_close.b_tree_oc_l7{z-index:10}.o_tree ul li div a.o_tree_oc_l8{position:absolute;top:10px;left:116px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l8,.o_tree ul .o_tree_level_close.b_tree_oc_l8{z-index:10}.o_tree ul li div a.o_tree_oc_l9{position:absolute;top:10px;left:131px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l9,.o_tree ul .o_tree_level_close.b_tree_oc_l9{z-index:10}.o_tree ul li div a.o_tree_oc_l10{position:absolute;top:10px;left:146px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l10,.o_tree ul .o_tree_level_close.b_tree_oc_l10{z-index:10}.o_tree ul li div a.o_tree_oc_l11{position:absolute;top:10px;left:161px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l11,.o_tree ul .o_tree_level_close.b_tree_oc_l11{z-index:10}.o_tree ul li div a.o_tree_l0{display:block;padding:10px 2px 10px 10px;z-index:9}.o_tree ul li div a.o_tree_l1{display:block;padding:10px 2px 10px 25px;z-index:9}.o_tree ul li div a.o_tree_l2{display:block;padding:10px 2px 10px 40px;z-index:9}.o_tree ul li div a.o_tree_l3{display:block;padding:10px 2px 10px 55px;z-index:9}.o_tree ul li div a.o_tree_l4{display:block;padding:10px 2px 10px 70px;z-index:9}.o_tree ul li div a.o_tree_l5{display:block;padding:10px 2px 10px 85px;z-index:9}.o_tree ul li div a.o_tree_l6{display:block;padding:10px 2px 10px 100px;z-index:9}.o_tree ul li div a.o_tree_l7{display:block;padding:10px 2px 10px 115px;z-index:9}.o_tree ul li div a.o_tree_l8{display:block;padding:10px 2px 10px 130px;z-index:9}.o_tree ul li div a.o_tree_l9{display:block;padding:10px 2px 10px 145px;z-index:9}.o_tree ul li div a.o_tree_l10{display:block;padding:10px 2px 10px 160px;z-index:9}.o_tree ul li div a.o_tree_l11{display:block;padding:10px 2px 10px 175px;z-index:9}.o_tree ul span.o_tree_leaf{display:none}.o_tree ul li .badge{float:right;font-size:70%}.o_tree ul li div.o_dnd_sibling{margin:0;padding:0;border-bottom:none}.o_tree ul li a.active{color:#428bca;background-color:none;font-weight:bold}.o_tree ul li a.active:hover,.o_tree ul li a.active:focus{color:#2a6496;background-color:#eee}.o_tree ul li a.active_parent{color:#777;font-weight:bold}.o_tree ul li a.active_parent:hover,.o_tree ul li a.active_parent:focus{color:#333}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l0{left:6px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l1{left:21px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l2{left:36px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l3{left:51px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l4{left:66px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l5{left:81px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l6{left:96px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l7{left:111px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l8{left:126px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l9{left:141px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l10{left:156px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l11{left:171px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l0{padding:10px 2px 10px 20px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l1{padding:10px 2px 10px 35px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l2{padding:10px 2px 10px 50px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l3{padding:10px 2px 10px 65px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l4{padding:10px 2px 10px 80px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l5{padding:10px 2px 10px 95px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l6{padding:10px 2px 10px 110px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l7{padding:10px 2px 10px 125px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l8{padding:10px 2px 10px 140px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l9{padding:10px 2px 10px 155px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l10{padding:10px 2px 10px 170px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l11{padding:10px 2px 10px 185px}.o_tree .o_dnd_item{cursor:move;z-index:100}.o_tree .o_dnd_proxy{opacity:0.4;filter:alpha(opacity=40);background-color:yellow}.o_tree .o_dnd_item.o_dnd_over{background-color:#ffff60}.o_tree .o_dnd_sibling{height:3px;width:100%}.o_tree .o_dnd_sibling.o_dnd_over{background:transparent url(../light/images/arrow_dd.png) top left no-repeat}.o_tree .o_dnd_l1{margin-left:0 !important}.o_tree .o_dnd_l2{margin-left:1em !important}.o_tree .o_dnd_l3{margin-left:2em !important}.o_tree .o_dnd_l4{margin-left:3em !important}.o_tree .o_dnd_l5{margin-left:4em !important}.o_tree .o_dnd_l6{margin-left:5em !important}.o_tree .o_dnd_l7{margin-left:6em !important}.o_tree .o_dnd_l8{margin-left:7em !important}.o_tree .o_dnd_l9{margin-left:8em !important}.o_tree .o_dnd_l10{margin-left:9em !important}.o_tree .o_dnd_l11{margin-left:10em !important}.o_offcanvas .o_tree{border:0}.o_selection_tree{position:relative;display:block;background-color:none;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow:hidden;font-size:14px}.o_selection_tree ul{margin:0;padding:0;list-style-type:none}.o_selection_tree li{margin:0;padding:0;white-space:nowrap}.o_selection_tree li div{position:relative;margin-bottom:-1px;border-bottom:1px solid #ddd}.o_selection_tree li>div>span.o_tree_l0,.o_selection_tree li>div>div.checkbox.o_tree_l0{display:block;padding:10px 2px 10px 10px;z-index:9}.o_selection_tree li>div>span.o_tree_l1,.o_selection_tree li>div>div.checkbox.o_tree_l1{display:block;padding:10px 2px 10px 25px;z-index:9}.o_selection_tree li>div>span.o_tree_l2,.o_selection_tree li>div>div.checkbox.o_tree_l2{display:block;padding:10px 2px 10px 40px;z-index:9}.o_selection_tree li>div>span.o_tree_l3,.o_selection_tree li>div>div.checkbox.o_tree_l3{display:block;padding:10px 2px 10px 55px;z-index:9}.o_selection_tree li>div>span.o_tree_l4,.o_selection_tree li>div>div.checkbox.o_tree_l4{display:block;padding:10px 2px 10px 70px;z-index:9}.o_selection_tree li>div>span.o_tree_l5,.o_selection_tree li>div>div.checkbox.o_tree_l5{display:block;padding:10px 2px 10px 85px;z-index:9}.o_selection_tree li>div>span.o_tree_l6,.o_selection_tree li>div>div.checkbox.o_tree_l6{display:block;padding:10px 2px 10px 100px;z-index:9}.o_selection_tree li>div>span.o_tree_l7,.o_selection_tree li>div>div.checkbox.o_tree_l7{display:block;padding:10px 2px 10px 115px;z-index:9}.o_selection_tree li>div>span.o_tree_l8,.o_selection_tree li>div>div.checkbox.o_tree_l8{display:block;padding:10px 2px 10px 130px;z-index:9}.o_selection_tree li>div>span.o_tree_l9,.o_selection_tree li>div>div.checkbox.o_tree_l9{display:block;padding:10px 2px 10px 145px;z-index:9}.o_selection_tree li>div>span.o_tree_l10,.o_selection_tree li>div>div.checkbox.o_tree_l10{display:block;padding:10px 2px 10px 160px;z-index:9}.o_selection_tree li>div>span.o_tree_l11,.o_selection_tree li>div>div.checkbox.o_tree_l11{display:block;padding:10px 2px 10px 175px;z-index:9}.o_breadcrumb{position:relative}.o_breadcrumb .o_breadcrumb_close{float:right}.o_form .o_icon_mandatory{position:relative;right:0;line-height:inherit;margin-left:0.25em}.o_form .o_error{margin-top:1px;margin-bottom:0;padding:10px}.o_form hr.o_spacer_noline{border-top:1px solid transparent}.o_form .o_date{position:relative;padding-right:34px}.o_form .o_date.form-inline .form-group,.o_form .o_date.navbar-form .form-group,.o_form .o_date.o_navbar-form .form-group{margin-left:0}.o_form input.o_date_ms{width:3em}.o_form .o_date.form-inline .o_date_ms.form-group,.o_form .o_date.navbar-form .o_date_ms.form-group,.o_form .o_date.o_navbar-form .o_date_ms.form-group{margin-left:25px}.o_form .input-group.o_date_picker{width:16em}.o_form .o_filepreview{margin-bottom:10px}.o_form .o_fileinput{cursor:pointer;position:relative}.o_form .o_fileinput .o_fakechooser{position:relative;z-index:1}.o_form .o_fileinput .o_realchooser{position:absolute;top:0;left:0;z-index:2;opacity:0;filter:alpha(opacity=0)}.o_choice_checkrow,.o_choice_textrow{vertical-align:text-top;padding-bottom:2px}.o_choice_textrow{padding-left:1em}.o_togglecheck a{white-space:nowrap}.o_catalog .o_catalog_delete_img{position:relative;top:-0.5em}.o_button_dirty{color:#fff;background-color:#f0ad4e;border-color:#eea236}.o_button_dirty:hover,.o_button_dirty:focus,.o_button_dirty:active,.o_button_dirty.active,.open>.o_button_dirty.dropdown-toggle{color:#fff;background-color:#ec971f;border-color:#d58512}.o_button_dirty:active,.o_button_dirty.active,.open>.o_button_dirty.dropdown-toggle{background-image:none}.o_button_dirty.disabled,.o_button_dirty.disabled:hover,.o_button_dirty.disabled:focus,.o_button_dirty.disabled:active,.o_button_dirty.disabled.active,.o_button_dirty[disabled],.o_button_dirty[disabled]:hover,.o_button_dirty[disabled]:focus,.o_button_dirty[disabled]:active,.o_button_dirty[disabled].active,fieldset[disabled] .o_button_dirty,fieldset[disabled] .o_button_dirty:hover,fieldset[disabled] .o_button_dirty:focus,fieldset[disabled] .o_button_dirty:active,fieldset[disabled] .o_button_dirty.active{background-color:#f0ad4e;border-color:#eea236}.o_button_dirty .badge{color:#f0ad4e;background-color:#fff}.o_button_toggle{border:1px solid #777;border-top-right-radius:9px;border-top-left-radius:9px;border-bottom-right-radius:9px;border-bottom-left-radius:9px;background:#eee;display:inline-block;height:18px;line-height:16px;font-size:16px;text-align:left;padding:0 0.5em 0 0;margin:0}.o_button_toggle i{color:#777;text-shadow:1px 0 2px rgba(0,0,0,0.25)}.o_button_toggle span{line-height:16px;vertical-align:top;font-size:60%;color:#777;text-transform:uppercase}.o_button_toggle.o_on{text-align:right;padding:0 0 0 0.5em}.o_button_toggle.o_on i{color:#428bca;text-shadow:-1px 0 2px rgba(0,0,0,0.25)}.o_table_wrapper.o_table_flexi .o_table_body{margin-top:20px}.o_table_wrapper.o_table_flexi .table{margin-top:20px}.o_table_wrapper.o_table_flexi .table td ul{margin:0}.o_table_wrapper .o_table_search{max-width:50em}.o_table_wrapper .o_table_footer .o_table_pagination{text-align:center}.o_table_wrapper .o_row_selected td{background-color:#dff0d8 !important}.o_table_wrapper .o_table{margin-bottom:0}.o_table_config{font-size:12px}.o_table_buttons{text-align:center}.o_table_buttons input{margin-right:1em}.o_table_buttons input:last-child{margin-right:0}.o_table_tools{margin-left:0.5em}.o_table_count{max-width:20em;float:left;padding:0 15px}.o_info .table-bordered td,o_note .table-bordered td,o_important .table-bordered td,o_warning .table-bordered td,o_error .table-bordered td{border-color:#333}.panel .o_table_layout{border-top:1px solid #ddd;padding-top:6px}.panel .o_table_count{padding:0 15px}#o_navbar_imclient #o_im_message,#o_navbar_imclient #o_im_status,#o_navbar_imclient #o_im_summary{float:left;position:relative;padding:15px 3px}#o_navbar_imclient #o_im_summary{padding-right:15px}#o_navbar_imclient #o_im_status div.o_chelp_wrapper{right:0.5em}.o_im_load_history{margin-bottom:6px}.o_im_load_history .o_label{font-size:12px;padding-right:0.5em;line-height:1.5em;color:#777}.o_im_chat_history{height:170px;font-size:90%;border:1px solid #eee;margin:0 0 1em 0;overflow:scroll;overflow-x:auto}.o_im_message_group{padding:3px 3px 3px 40px;min-height:40px;position:relative;border-top:1px solid #eee;background:#fff}.o_im_message_group.o_odd{background:#f4f4f4}.o_im_message_group .o_portrait{position:absolute;top:3px;left:3px}.o_im_message_group .o_im_from{color:#777;font-size:12px;font-weight:bold}.o_im_message_group .o_im_from:hover{color:#5e5e5e}.o_im_message_group div.o_im_body{padding:3px 0 3px 0;font-size:12px}.o_im_message_group div.o_im_body .o_date{float:right;color:#777;font-size:9px}.o_groupchat_roster{font-size:12px}.o_groupchat_roster li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333}.o_groupchat_roster li.o_vip{color:#3c763d}.o_groupchat_roster li.o_anonymous{color:#31708f}.o_im_buddieslist .o_im_buddieslist_toggler .btn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.o_im_buddieslist ul{font-size:12px}.o_im_buddieslist ul ul{padding-left:1em}.o_im_buddieslist ul a{color:#428bca}.o_im_buddieslist ul a:hover{color:#2a6496}.o_flag{position:relative;top:1px;display:inline-block;line-height:1;width:16px;height:16px;background-repeat:no-repeat;background-position:0 100%}option.o_with_flag{padding-left:23px;min-height:16px;background-repeat:no-repeat;background-position:2px 50%}.o_flag_en{background-image:url("../light/images/flags/gb.png")}.o_flag_de{background-image:url("../light/images/flags/de.png")}.o_flag_fr{background-image:url("../light/images/flags/fr.png")}.o_flag_it{background-image:url("../light/images/flags/it.png")}.o_flag_es{background-image:url("../light/images/flags/es.png")}.o_flag_da{background-image:url("../light/images/flags/dk.png")}.o_flag_cs{background-image:url("../light/images/flags/cz.png")}.o_flag_el{background-image:url("../light/images/flags/gr.png")}.o_flag_ee{background-image:url("../light/images/flags/ee.png")}.o_flag_ru{background-image:url("../light/images/flags/ru.png")}.o_flag_pl{background-image:url("../light/images/flags/pl.png")}.o_flag_zh_CN{background-image:url("../light/images/flags/cn.png")}.o_flag_zh_TW{background-image:url("../light/images/flags/tw.png")}.o_flag_lt{background-image:url("../light/images/flags/lt.png")}.o_flag_fa{background-image:url("../light/images/flags/ir.png")}.o_flag_pt_PT{background-image:url("../light/images/flags/pt.png")}.o_flag_pt_BR{background-image:url("../light/images/flags/br.png")}.o_flag_tr{background-image:url("../light/images/flags/tr.png")}.o_flag_hu{background-image:url("../light/images/flags/hu.png")}.o_flag_sq{background-image:url("../light/images/flags/al.png")}.o_flag_in{background-image:url("../light/images/flags/id.png")}.o_flag_ar{background-image:url("../light/images/flags/eg.png")}.o_flag_rm{background-image:url("../light/images/flags/rm.png")}.o_flag_af{background-image:url("../light/images/flags/za.png")}.o_flag_vi{background-image:url("../light/images/flags/vn.png")}.o_flag_mn{background-image:url("../light/images/flags/mn.png")}.o_flag_iw{background-image:url("../light/images/flags/il.png")}.o_flag_ko{background-image:url("../light/images/flags/kr.png")}.o_flag_nl_NL{background-image:url("../light/images/flags/nl.png")}.o_flag_jp{background-image:url("../light/images/flags/jp.png")}.o_flag_nb_NO{background-image:url("../light/images/flags/no.png")}.o_flag_et_EE{background-image:url("../light/images/flags/ee.png")}.o_flag_bg{background-image:url("../light/images/flags/bg.png")}.o_flag_hi_IN_ASIA{background-image:url("../light/images/flags/in.png")}.o_flag_ar_LB{background-image:url("../light/images/flags/lb.png")}.o_flag_gl_ES{background-image:url("../light/images/flags/galicia.png")}.o_rating .o_rating_title{font-size:12px}.o_rating .o_rating_items{white-space:nowrap}.o_rating .o_rating_items .o_icon{color:#f0ad4e}.o_rating .o_rating_items .o_icon:hover{color:#428bca}.o_rating .o_rating_items .o_legend{margin-left:1em;font-size:12px;line-height:1em}.o_rating .o_rating_explanation{font-size:12px;color:#777}@media (max-width: 991px){.o_rating .o_rating_title,.o_rating .o_rating_explanation{display:none}} +#o_msg_sticky,#o_msg_sticky_preview{position:relative;color:#a94442;background-color:#f2dede;border:1px solid #ebccd1;padding:10px 16px 10px 60px;min-height:40px;margin:-20px 0 20px 0}#o_msg_sticky .o_icon_info_msg,#o_msg_sticky_preview .o_icon_info_msg{position:absolute;left:10px;top:5px;font-size:40px}.o_tree{position:relative;display:block;background-color:none;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow:hidden;font-size:14px}.o_tree a{color:#777;background-color:none}.o_tree a:hover,.o_tree a:focus{color:#333;background-color:#f8f8f8}.o_tree ul{margin:0;padding:0;list-style-type:none}.o_tree ul li{margin:0;padding:0;white-space:nowrap}.o_tree ul li div{position:relative;margin-bottom:-1px;border-bottom:1px solid #ddd}.o_tree ul li div a.o_tree_oc_l0{position:absolute;top:10px;left:-4px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l0,.o_tree ul .o_tree_level_close.b_tree_oc_l0{z-index:10}.o_tree ul li div a.o_tree_oc_l1{position:absolute;top:10px;left:11px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l1,.o_tree ul .o_tree_level_close.b_tree_oc_l1{z-index:10}.o_tree ul li div a.o_tree_oc_l2{position:absolute;top:10px;left:26px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l2,.o_tree ul .o_tree_level_close.b_tree_oc_l2{z-index:10}.o_tree ul li div a.o_tree_oc_l3{position:absolute;top:10px;left:41px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l3,.o_tree ul .o_tree_level_close.b_tree_oc_l3{z-index:10}.o_tree ul li div a.o_tree_oc_l4{position:absolute;top:10px;left:56px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l4,.o_tree ul .o_tree_level_close.b_tree_oc_l4{z-index:10}.o_tree ul li div a.o_tree_oc_l5{position:absolute;top:10px;left:71px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l5,.o_tree ul .o_tree_level_close.b_tree_oc_l5{z-index:10}.o_tree ul li div a.o_tree_oc_l6{position:absolute;top:10px;left:86px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l6,.o_tree ul .o_tree_level_close.b_tree_oc_l6{z-index:10}.o_tree ul li div a.o_tree_oc_l7{position:absolute;top:10px;left:101px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l7,.o_tree ul .o_tree_level_close.b_tree_oc_l7{z-index:10}.o_tree ul li div a.o_tree_oc_l8{position:absolute;top:10px;left:116px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l8,.o_tree ul .o_tree_level_close.b_tree_oc_l8{z-index:10}.o_tree ul li div a.o_tree_oc_l9{position:absolute;top:10px;left:131px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l9,.o_tree ul .o_tree_level_close.b_tree_oc_l9{z-index:10}.o_tree ul li div a.o_tree_oc_l10{position:absolute;top:10px;left:146px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l10,.o_tree ul .o_tree_level_close.b_tree_oc_l10{z-index:10}.o_tree ul li div a.o_tree_oc_l11{position:absolute;top:10px;left:161px;z-index:9}.o_tree ul .o_tree_level_open.b_tree_oc_l11,.o_tree ul .o_tree_level_close.b_tree_oc_l11{z-index:10}.o_tree ul li div a.o_tree_l0{display:block;padding:10px 2px 10px 10px;z-index:9}.o_tree ul li div a.o_tree_l1{display:block;padding:10px 2px 10px 25px;z-index:9}.o_tree ul li div a.o_tree_l2{display:block;padding:10px 2px 10px 40px;z-index:9}.o_tree ul li div a.o_tree_l3{display:block;padding:10px 2px 10px 55px;z-index:9}.o_tree ul li div a.o_tree_l4{display:block;padding:10px 2px 10px 70px;z-index:9}.o_tree ul li div a.o_tree_l5{display:block;padding:10px 2px 10px 85px;z-index:9}.o_tree ul li div a.o_tree_l6{display:block;padding:10px 2px 10px 100px;z-index:9}.o_tree ul li div a.o_tree_l7{display:block;padding:10px 2px 10px 115px;z-index:9}.o_tree ul li div a.o_tree_l8{display:block;padding:10px 2px 10px 130px;z-index:9}.o_tree ul li div a.o_tree_l9{display:block;padding:10px 2px 10px 145px;z-index:9}.o_tree ul li div a.o_tree_l10{display:block;padding:10px 2px 10px 160px;z-index:9}.o_tree ul li div a.o_tree_l11{display:block;padding:10px 2px 10px 175px;z-index:9}.o_tree ul span.o_tree_leaf{display:none}.o_tree ul li .badge{float:right;font-size:70%}.o_tree ul li div.o_dnd_sibling{margin:0;padding:0;border-bottom:none}.o_tree ul li a.active{color:#428bca;background-color:none;font-weight:bold}.o_tree ul li a.active:hover,.o_tree ul li a.active:focus{color:#2a6496;background-color:#eee}.o_tree ul li a.active_parent{color:#777;font-weight:bold}.o_tree ul li a.active_parent:hover,.o_tree ul li a.active_parent:focus{color:#333}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l0{left:6px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l1{left:21px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l2{left:36px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l3{left:51px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l4{left:66px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l5{left:81px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l6{left:96px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l7{left:111px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l8{left:126px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l9{left:141px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l10{left:156px}.o_tree.o_tree_root_hidden ul li div a.o_tree_oc_l11{left:171px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l0{padding:10px 2px 10px 20px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l1{padding:10px 2px 10px 35px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l2{padding:10px 2px 10px 50px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l3{padding:10px 2px 10px 65px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l4{padding:10px 2px 10px 80px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l5{padding:10px 2px 10px 95px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l6{padding:10px 2px 10px 110px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l7{padding:10px 2px 10px 125px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l8{padding:10px 2px 10px 140px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l9{padding:10px 2px 10px 155px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l10{padding:10px 2px 10px 170px}.o_tree.o_tree_root_hidden ul li div a.o_tree_l11{padding:10px 2px 10px 185px}.o_tree .o_dnd_item{cursor:move;z-index:100}.o_tree .o_dnd_proxy{opacity:0.4;filter:alpha(opacity=40);background-color:yellow}.o_tree .o_dnd_item.o_dnd_over{background-color:#ffff60}.o_tree .o_dnd_sibling{height:3px;width:100%}.o_tree .o_dnd_sibling.o_dnd_over{background:transparent url(../light/images/arrow_dd.png) top left no-repeat}.o_tree .o_dnd_l1{margin-left:0 !important}.o_tree .o_dnd_l2{margin-left:1em !important}.o_tree .o_dnd_l3{margin-left:2em !important}.o_tree .o_dnd_l4{margin-left:3em !important}.o_tree .o_dnd_l5{margin-left:4em !important}.o_tree .o_dnd_l6{margin-left:5em !important}.o_tree .o_dnd_l7{margin-left:6em !important}.o_tree .o_dnd_l8{margin-left:7em !important}.o_tree .o_dnd_l9{margin-left:8em !important}.o_tree .o_dnd_l10{margin-left:9em !important}.o_tree .o_dnd_l11{margin-left:10em !important}.o_offcanvas .o_tree{border:0}.o_selection_tree{position:relative;display:block;background-color:none;border:1px solid #ddd;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;overflow:hidden;font-size:14px}.o_selection_tree ul{margin:0;padding:0;list-style-type:none}.o_selection_tree li{margin:0;padding:0;white-space:nowrap}.o_selection_tree li div{position:relative;margin-bottom:-1px;border-bottom:1px solid #ddd}.o_selection_tree li>div>span.o_tree_l0,.o_selection_tree li>div>div.checkbox.o_tree_l0,.o_selection_tree li>div>div.radio.o_tree_l0{display:block;padding:10px 2px 10px 10px;z-index:9}.o_selection_tree li>div>span.o_tree_l1,.o_selection_tree li>div>div.checkbox.o_tree_l1,.o_selection_tree li>div>div.radio.o_tree_l1{display:block;padding:10px 2px 10px 25px;z-index:9}.o_selection_tree li>div>span.o_tree_l2,.o_selection_tree li>div>div.checkbox.o_tree_l2,.o_selection_tree li>div>div.radio.o_tree_l2{display:block;padding:10px 2px 10px 40px;z-index:9}.o_selection_tree li>div>span.o_tree_l3,.o_selection_tree li>div>div.checkbox.o_tree_l3,.o_selection_tree li>div>div.radio.o_tree_l3{display:block;padding:10px 2px 10px 55px;z-index:9}.o_selection_tree li>div>span.o_tree_l4,.o_selection_tree li>div>div.checkbox.o_tree_l4,.o_selection_tree li>div>div.radio.o_tree_l4{display:block;padding:10px 2px 10px 70px;z-index:9}.o_selection_tree li>div>span.o_tree_l5,.o_selection_tree li>div>div.checkbox.o_tree_l5,.o_selection_tree li>div>div.radio.o_tree_l5{display:block;padding:10px 2px 10px 85px;z-index:9}.o_selection_tree li>div>span.o_tree_l6,.o_selection_tree li>div>div.checkbox.o_tree_l6,.o_selection_tree li>div>div.radio.o_tree_l6{display:block;padding:10px 2px 10px 100px;z-index:9}.o_selection_tree li>div>span.o_tree_l7,.o_selection_tree li>div>div.checkbox.o_tree_l7,.o_selection_tree li>div>div.radio.o_tree_l7{display:block;padding:10px 2px 10px 115px;z-index:9}.o_selection_tree li>div>span.o_tree_l8,.o_selection_tree li>div>div.checkbox.o_tree_l8,.o_selection_tree li>div>div.radio.o_tree_l8{display:block;padding:10px 2px 10px 130px;z-index:9}.o_selection_tree li>div>span.o_tree_l9,.o_selection_tree li>div>div.checkbox.o_tree_l9,.o_selection_tree li>div>div.radio.o_tree_l9{display:block;padding:10px 2px 10px 145px;z-index:9}.o_selection_tree li>div>span.o_tree_l10,.o_selection_tree li>div>div.checkbox.o_tree_l10,.o_selection_tree li>div>div.radio.o_tree_l10{display:block;padding:10px 2px 10px 160px;z-index:9}.o_selection_tree li>div>span.o_tree_l11,.o_selection_tree li>div>div.checkbox.o_tree_l11,.o_selection_tree li>div>div.radio.o_tree_l11{display:block;padding:10px 2px 10px 175px;z-index:9}.o_breadcrumb{position:relative}.o_breadcrumb .o_breadcrumb_close{float:right}.o_form .o_icon_mandatory{position:relative;right:0;line-height:inherit;margin-left:0.25em}.o_form .o_error{margin-top:1px;margin-bottom:0;padding:10px}.o_form hr.o_spacer_noline{border-top:1px solid transparent}.o_form .o_date{position:relative;padding-right:34px}.o_form .o_date.form-inline .form-group,.o_form .o_date.navbar-form .form-group,.o_form .o_date.o_navbar-form .form-group{margin-left:0}.o_form input.o_date_ms{width:3em}.o_form .o_date.form-inline .o_date_ms.form-group,.o_form .o_date.navbar-form .o_date_ms.form-group,.o_form .o_date.o_navbar-form .o_date_ms.form-group{margin-left:25px}.o_form .input-group.o_date_picker{width:16em}.o_form .o_filepreview{margin-bottom:10px}.o_form .o_fileinput{cursor:pointer;position:relative}.o_form .o_fileinput .o_fakechooser{position:relative;z-index:1}.o_form .o_fileinput .o_realchooser{position:absolute;top:0;left:0;z-index:2;opacity:0;filter:alpha(opacity=0)}.o_choice_checkrow,.o_choice_textrow{vertical-align:text-top;padding-bottom:2px}.o_choice_textrow{padding-left:1em}.o_togglecheck a{white-space:nowrap}.o_catalog .o_catalog_delete_img{position:relative;top:-0.5em}.o_button_dirty{color:#fff;background-color:#f0ad4e;border-color:#eea236}.o_button_dirty:hover,.o_button_dirty:focus,.o_button_dirty:active,.o_button_dirty.active,.open>.o_button_dirty.dropdown-toggle{color:#fff;background-color:#ec971f;border-color:#d58512}.o_button_dirty:active,.o_button_dirty.active,.open>.o_button_dirty.dropdown-toggle{background-image:none}.o_button_dirty.disabled,.o_button_dirty.disabled:hover,.o_button_dirty.disabled:focus,.o_button_dirty.disabled:active,.o_button_dirty.disabled.active,.o_button_dirty[disabled],.o_button_dirty[disabled]:hover,.o_button_dirty[disabled]:focus,.o_button_dirty[disabled]:active,.o_button_dirty[disabled].active,fieldset[disabled] .o_button_dirty,fieldset[disabled] .o_button_dirty:hover,fieldset[disabled] .o_button_dirty:focus,fieldset[disabled] .o_button_dirty:active,fieldset[disabled] .o_button_dirty.active{background-color:#f0ad4e;border-color:#eea236}.o_button_dirty .badge{color:#f0ad4e;background-color:#fff}.o_button_toggle{border:1px solid #777;border-top-right-radius:9px;border-top-left-radius:9px;border-bottom-right-radius:9px;border-bottom-left-radius:9px;background:#eee;display:inline-block;height:18px;line-height:16px;font-size:16px;text-align:left;padding:0 0.5em 0 0;margin:0}.o_button_toggle i{color:#777;text-shadow:1px 0 2px rgba(0,0,0,0.25)}.o_button_toggle span{line-height:16px;vertical-align:top;font-size:60%;color:#777;text-transform:uppercase}.o_button_toggle.o_on{text-align:right;padding:0 0 0 0.5em}.o_button_toggle.o_on i{color:#428bca;text-shadow:-1px 0 2px rgba(0,0,0,0.25)}.o_table_wrapper.o_table_flexi .o_table_body{margin-top:20px}.o_table_wrapper.o_table_flexi .table{margin-top:20px}.o_table_wrapper.o_table_flexi .table td ul{margin:0}.o_table_wrapper .o_table_search{max-width:50em}.o_table_wrapper .o_table_footer .o_table_pagination{text-align:center}.o_table_wrapper .o_row_selected td{background-color:#dff0d8 !important}.o_table_wrapper .o_table{margin-bottom:0}.o_table_config{font-size:12px}.o_table_buttons{text-align:center}.o_table_buttons input{margin-right:1em}.o_table_buttons input:last-child{margin-right:0}.o_table_tools{margin-left:0.5em}.o_table_count{max-width:20em;float:left;padding:0 15px}.o_info .table-bordered td,o_note .table-bordered td,o_important .table-bordered td,o_warning .table-bordered td,o_error .table-bordered td{border-color:#333}.panel .o_table_layout{border-top:1px solid #ddd;padding-top:6px}.panel .o_table_count{padding:0 15px}#o_navbar_imclient #o_im_message,#o_navbar_imclient #o_im_status,#o_navbar_imclient #o_im_summary{float:left;position:relative;padding:15px 3px}#o_navbar_imclient #o_im_summary{padding-right:15px}#o_navbar_imclient #o_im_status div.o_chelp_wrapper{right:0.5em}.o_im_load_history{margin-bottom:6px}.o_im_load_history .o_label{font-size:12px;padding-right:0.5em;line-height:1.5em;color:#777}.o_im_chat_history{height:170px;font-size:90%;border:1px solid #eee;margin:0 0 1em 0;overflow:scroll;overflow-x:auto}.o_im_message_group{padding:3px 3px 3px 40px;min-height:40px;position:relative;border-top:1px solid #eee;background:#fff}.o_im_message_group.o_odd{background:#f4f4f4}.o_im_message_group .o_portrait{position:absolute;top:3px;left:3px}.o_im_message_group .o_im_from{color:#777;font-size:12px;font-weight:bold}.o_im_message_group .o_im_from:hover{color:#5e5e5e}.o_im_message_group div.o_im_body{padding:3px 0 3px 0;font-size:12px}.o_im_message_group div.o_im_body .o_date{float:right;color:#777;font-size:9px}.o_groupchat_roster{font-size:12px}.o_groupchat_roster li{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333}.o_groupchat_roster li.o_vip{color:#3c763d}.o_groupchat_roster li.o_anonymous{color:#31708f}.o_im_buddieslist .o_im_buddieslist_toggler .btn{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.o_im_buddieslist ul{font-size:12px}.o_im_buddieslist ul ul{padding-left:1em}.o_im_buddieslist ul a{color:#428bca}.o_im_buddieslist ul a:hover{color:#2a6496}.o_flag{position:relative;top:1px;display:inline-block;line-height:1;width:16px;height:16px;background-repeat:no-repeat;background-position:0 100%}option.o_with_flag{padding-left:23px;min-height:16px;background-repeat:no-repeat;background-position:2px 50%}.o_flag_en{background-image:url("../light/images/flags/gb.png")}.o_flag_de{background-image:url("../light/images/flags/de.png")}.o_flag_fr{background-image:url("../light/images/flags/fr.png")}.o_flag_it{background-image:url("../light/images/flags/it.png")}.o_flag_es{background-image:url("../light/images/flags/es.png")}.o_flag_da{background-image:url("../light/images/flags/dk.png")}.o_flag_cs{background-image:url("../light/images/flags/cz.png")}.o_flag_el{background-image:url("../light/images/flags/gr.png")}.o_flag_ee{background-image:url("../light/images/flags/ee.png")}.o_flag_ru{background-image:url("../light/images/flags/ru.png")}.o_flag_pl{background-image:url("../light/images/flags/pl.png")}.o_flag_zh_CN{background-image:url("../light/images/flags/cn.png")}.o_flag_zh_TW{background-image:url("../light/images/flags/tw.png")}.o_flag_lt{background-image:url("../light/images/flags/lt.png")}.o_flag_fa{background-image:url("../light/images/flags/ir.png")}.o_flag_pt_PT{background-image:url("../light/images/flags/pt.png")}.o_flag_pt_BR{background-image:url("../light/images/flags/br.png")}.o_flag_tr{background-image:url("../light/images/flags/tr.png")}.o_flag_hu{background-image:url("../light/images/flags/hu.png")}.o_flag_sq{background-image:url("../light/images/flags/al.png")}.o_flag_in{background-image:url("../light/images/flags/id.png")}.o_flag_ar{background-image:url("../light/images/flags/eg.png")}.o_flag_rm{background-image:url("../light/images/flags/rm.png")}.o_flag_af{background-image:url("../light/images/flags/za.png")}.o_flag_vi{background-image:url("../light/images/flags/vn.png")}.o_flag_mn{background-image:url("../light/images/flags/mn.png")}.o_flag_iw{background-image:url("../light/images/flags/il.png")}.o_flag_ko{background-image:url("../light/images/flags/kr.png")}.o_flag_nl_NL{background-image:url("../light/images/flags/nl.png")}.o_flag_jp{background-image:url("../light/images/flags/jp.png")}.o_flag_nb_NO{background-image:url("../light/images/flags/no.png")}.o_flag_et_EE{background-image:url("../light/images/flags/ee.png")}.o_flag_bg{background-image:url("../light/images/flags/bg.png")}.o_flag_hi_IN_ASIA{background-image:url("../light/images/flags/in.png")}.o_flag_ar_LB{background-image:url("../light/images/flags/lb.png")}.o_flag_gl_ES{background-image:url("../light/images/flags/galicia.png")}.o_rating .o_rating_title{font-size:12px}.o_rating .o_rating_items{white-space:nowrap}.o_rating .o_rating_items .o_icon{color:#f0ad4e}.o_rating .o_rating_items .o_icon:hover{color:#428bca}.o_rating .o_rating_items .o_legend{margin-left:1em;font-size:12px;line-height:1em}.o_rating .o_rating_explanation{font-size:12px;color:#777}@media (max-width: 991px){.o_rating .o_rating_title,.o_rating .o_rating_explanation{display:none}} .o_comments .o_comment_wrapper .o_avatar{float:left;margin:0 1em 0 0}.o_comments .o_comment_wrapper .o_reply,.o_comments .o_comment_wrapper .o_delete{float:right}.o_ratings_and_comments .o_rating_wrapper{vertical-align:middle;display:inline-block}.o_ratings_and_comments a.o_comments{margin-left:10px;position:relative;top:0.1em}.d3chart .bar{shape-rendering:crispEdges}.d3chart .bar_default_light{fill:#7eb0db}.d3chart .bar_default{fill:#428bca}.d3chart .bar_default_dark{fill:#2a6496}.d3chart .axis{font:12px sans-serif}.d3chart .axis path,.d3chart .axis line{fill:none;stroke:#000;shape-rendering:crispEdges}.o_forum_peekview .o_quote_wrapper,.o_forum_peekview .b_quote_wrapper{display:none}.o_forum_thread_sticky{font-weight:bold}.o_forum_switch{font-size:12px}.o_forum_toolbar{margin-bottom:6px;float:left}.o_forum_fulltextsearch{float:right}@media (max-width: 767px){.o_forum_fulltextsearch{float:left}}.o_forum .o_mark,.o_forum .o_ep_collect{float:right;position:relative;width:2em;margin-left:12px}.o_forum .o_portrait{float:left;margin-right:16px}.o_forum .o_portrait_avatar{width:70px;height:70px}.o_forum .o_newindicator{font-size:10px;color:#5cb85c;text-transform:uppercase;padding-left:1em;vertical-align:text-top;white-space:nowrap}.o_forum .o_author,.o_forum .o_date{display:inline-block;color:#777}.o_forum .o_date{font-size:12px}.o_forum .o_modified{color:#8a6d3b;font-size:12px;font-style:italic}.o_forum .o_forum_message{margin-bottom:20px;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1)}.o_forum .o_forum_message_new{-webkit-box-shadow:0 1px 10px rgba(92,184,92,0.3);box-shadow:0 1px 10px rgba(92,184,92,0.3)}.o_forum .o_forum_message_highlight{-webkit-box-shadow:0 1px 10px rgba(240,173,78,0.5);box-shadow:0 1px 10px rgba(240,173,78,0.5)}.o_forum .o_forum_message_header{padding:10px 15px;border-bottom:1px solid #ddd;background-color:#f5f5f5;border-top-right-radius:3px;border-top-left-radius:3px}.o_forum .o_forum_message_title{margin-top:0}.o_forum .o_forum_message_body{padding:10px 15px}.o_forum .o_forum_message_attachments{border-top:1px solid #ddd;padding:10px 15px;font-size:12px;background-color:#f7f7f9}.o_forum .o_attachment{position:relative;max-width:250px;vertical-align:top;margin:6px 12px 10px 0}.o_forum .o_attachment img{margin-top:6px}.o_forum .o_filename{max-width:250px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.o_forum .o_icon_enlarge{position:absolute;left:1em;bottom:1em;text-shadow:1px 1px 2px #fff, -1px 1px 2px #fff, 1px -1px 2px #fff, -1px -1px 2px #fff}@media (min-width: 768px) and (max-width: 991px){.o_forum .o_attachments{font-size:10px}.o_forum .o_attachment{max-width:200px}.o_forum .o_attachment img{max-width:150px}.o_forum .o_filename{max-width:200px}}@media (max-width: 767px){.o_forum .o_attachments{font-size:9px}.o_forum .o_attachment{max-width:150px}.o_forum .o_attachment img{max-width:100px}.o_forum .o_filename{max-width:150px}} .o_quote_wrapper,.b_quote_wrapper{position:relative;margin:10px 0}.o_quote_author,.b_quote_author{color:#777;font-size:12px}.o_quote_author:before,.b_quote_author:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;content:"\f10e";font-size:21px;padding-right:0.5em}blockquote.o_quote,blockquote.b_quote{color:#555;font-size:12px;margin-top:6px;padding:0 12px}a.o_chelp{display:inline-block;padding:1px 3px;text-align:center;vertical-align:middle;white-space:nowrap;font-size:10px;font-weight:normal;line-height:15px;color:#fff;background-color:#428bca;border:1px solid #357ebd;border-radius:2px;cursor:help;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}a.o_chelp:active,a.o_chelp:hover,a.o_chelp:focus{text-decoration:none;color:#fff;background-color:#3276b1;border-color:#285e8e}a.o_chelp i{font-size:10px !important}.o_chelp_wrapper{position:relative;float:right;display:inline-block;line-height:1em}.o_iframedisplay iframe{width:100%}.o_singlepage .o_edit{position:absolute;top:10px;right:37px}.o_content_popup{position:absolute;top:10px;right:12px}.o_module_cp_wrapper .o_tools{position:absolute;top:10px;right:12px;text-align:right;vertical-align:middle}.o_module_cp_wrapper .o_tools .o_search_wrapper{display:inline-block;position:relative;top:-2px}.o_bc_meta .o_thumbnail,.tooltip .o_thumbnail{width:200px;height:200px}.o_htmleditor .o_lastmodified{color:#777}.o_htmleditor #o_save{margin-top:10px;text-align:center}.o_htmleditor #o_save input{margin-right:1em}.o_htmleditor #o_save input:last-child{margin-right:0}.o_notifications_news_wrapper .o_notifications_news_subscription{margin:10px 0}.o_notifications_news_wrapper .o_notifications_news_subscription h4 i,.o_notifications_news_wrapper .o_notifications_news_subscription .o_cal .fc-header-title h2 i,.o_cal .fc-header-title .o_notifications_news_wrapper .o_notifications_news_subscription h2 i{display:none}.o_notifications_news_wrapper .o_notifications_news_subscription .o_notifications_news_context{color:#777}.o_notifications_news_wrapper .o_notifications_news_subscription .o_notifications_news_content{margin-left:1.5em;position:relative}.o_notifications_news_wrapper .o_notifications_news_subscription .o_notifications_news_content .o_icon{position:absolute;left:-1.5em;line-height:1.5em;top:0}.o_notifications_news_wrapper .o_notifications_news_subscription .o_notifications_news_content .o_date{color:#777}.o_notifications_news_wrapper .o_notifications_news_subscription .o_notifications_news_url{margin-left:1.5em}.o_noti{margin:6px 0 6px 12px;float:right;color:#777}.o_noti .o_label{color:#777;cursor:help}@media (max-width: 767px){.o_noti .o_label span{display:none}} .panel-body .o_noti{margin:0}.o_portrait{display:inline-block}.o_portrait img{border-radius:50%;border:none;background-color:#eee;background-position:50% 50%;background-repeat:no-repeat;background-size:cover}.o_portrait_name{margin-top:6px}.o_portrait_avatar,.o_portrait_dummy,.o_portrait_dummy_female_big,.o_portrait_dummy_male_big,.o_portrait_anonymous{width:100px;height:100px}.o_portrait_dummy{background-image:url("../light/images/portrait/dummy.png")}.o_portrait_dummy_female_big{background-image:url("../light/images/portrait/dummy_female_big.png")}.o_portrait_dummy_male_big{background-image:url("../light/images/portrait/dummy_male_big.png")}.o_portrait_anonymous{background-image:url("../light/images/portrait/dummy.png")}.o_portrait_avatar_small,.o_portrait_dummy_small,.o_portrait_dummy_female_small,.o_portrait_dummy_male_small,.o_portrait_anonymous_small{width:30px;height:30px}.o_portrait_dummy_small{background-image:url("../light/images/portrait/dummy_small.png")}.o_portrait_dummy_female_small{background-image:url("../light/images/portrait/dummy_female_small.png")}.o_portrait_dummy_male_small{background-image:url("../light/images/portrait/dummy_male_small.png")}.o_portrait_anonymous_small{background-image:url("../light/images/portrait/dummy_small.png")}.o_datecomp{position:relative;width:40px;height:52px;border:1px solid #555;margin-right:12px;text-align:center;vertical-align:middle}.o_datecomp div.o_year{position:absolute;left:0;width:100%;top:-20px;height:20px;line-height:20px;font-size:10px}.o_datecomp div.o_month{height:20px;line-height:20px;font-size:12px;background-color:#428bca;color:#fff}.o_datecomp div.o_day{height:30px;line-height:30px;font-size:18px;border-top:1px solid #555;background-color:#fff;color:#333}.o_block_with_datecomp .o_head{position:relative;padding-left:52px}.o_block_with_datecomp .o_datecomp{position:absolute;top:0.2em;left:0}.o_block_with_datecomp .o_title{margin-top:0}.o_block_with_datecomp .o_meta{color:#777}.o_block_with_datecomp .o_content{border-left:5px solid #eee;padding:0 20px}.o_block_with_datecomp .o_block_footer{padding-left:25px}.o_cal_toptoolbar{margin-bottom:6px}.o_cal_toptoolbar .o_cal_toptoolbar_sub,.o_cal_toptoolbar .o_cal_toptoolbar_help{float:left;margin-right:12px}.o_feed .o_date,.o_feed .o_author{color:#777}.o_feed .o_subscription a{margin-right:1.5em}.o_feed .o_subscription form{margin-top:6px}.o_feed .o_blog_posts .o_ratings_and_comments .o_rating_wrapper{float:left}.o_feed .o_blog_posts .o_ratings_and_comments .o_rating_wrapper .o_rating_title,.o_feed .o_blog_posts .o_ratings_and_comments .o_rating_wrapper .o_rating_explanation,.o_feed .o_blog_posts .o_ratings_and_comments .o_rating_wrapper .o_legend{display:none}.o_feed .o_blog_posts .o_ratings_and_comments a.o_comments span{display:none}.o_segments_content{margin-top:20px}.o_tabbed_pane .o_tabbed_pane_content{padding:20px 0 6px 0}.o_togglebox_wrapper .o_opener{position:relative;left:-0.5em}.o_togglebox_wrapper div.o_togglebox_content{position:relative;margin:0}.o_togglebox_wrapper div.o_togglebox_content .o_hide{position:absolute;bottom:0.5em;right:1em}.o_toolboxes ul{margin:0 0 1.5em 0;padding:0 0 0 1.5em}.o_qrcode{width:256px;height:256px}#o_ajax_busy{position:absolute;left:50%;top:20em;margin-left:-2.5em;height:5em;width:5em;color:#fff;z-index:1201;display:none}#o_body.o_ajax_busy{cursor:busy}.o_exception .o_visual{position:relative;background-image:url("../light/images/lion-500x333.jpg");filter:grayscale(50%);-webkit-filter:grayscale(50%);-moz-filter:grayscale(50%);-ms-filter:grayscale(50%);-o-filter:grayscale(50%);width:500px;height:333px;background-repeat:no-repeat;background-position:50% 50%;background-size:contain;margin:0 0 10px 16px}@media (min-width: 768px) and (max-width: 991px){.o_exception .o_visual{width:375px;height:249px}}@media (min-width: 500px) and (max-width: 767px){.o_exception .o_visual{width:250px;height:166px}}@media (max-width: 500px){.o_exception .o_visual{background-size:cover}}