diff --git a/addons/web/common/http.py b/addons/web/common/http.py index cd17f5711e0..87748d2e6d9 100644 --- a/addons/web/common/http.py +++ b/addons/web/common/http.py @@ -417,6 +417,18 @@ class ControllerType(type): class Controller(object): __metaclass__ = ControllerType +class DisableCacheMiddleware(object): + def __init__(self, app): + self.app = app + def __call__(self, environ, start_response): + def start_wrapped(status, headers): + debug = environ.get('HTTP_REFERER', '').find('debug') != -1 + filtered_headers = [(k,v) for k,v in headers if not (k=='Last-Modified' or (debug and k=='Cache-Control'))] + if debug: + filtered_headers.append(('Cache-Control', 'no-cache')) + start_response(status, filtered_headers) + return self.app(environ, start_wrapped) + class Root(object): """Root WSGI application for the OpenERP Web Client. @@ -452,8 +464,8 @@ class Root(object): static_dirs = self._load_addons(openerp_addons_namespace) if options.serve_static: - self.dispatch = SuperSharedDataMiddleware( - self.dispatch, static_dirs, cache=False) + app = werkzeug.wsgi.SharedDataMiddleware( self.dispatch, static_dirs) + self.dispatch = DisableCacheMiddleware(app) if options.session_storage: if not os.path.exists(options.session_storage): @@ -555,75 +567,6 @@ class Root(object): return m ps, _slash, meth = ps.rpartition('/') return None - -class SuperSharedDataMiddleware(werkzeug.wsgi.SharedDataMiddleware): - """Redefine SharedDataMiddleware to better handle the cache = False directive. - Also desactivate 304 Not Modified headers only when the referer has 'debug' in its - arguments. - """ - def __call__(self, environ, start_response): - import os - import mimetypes - import werkzeug.http - import urlparse - # sanitize the path for non unix systems - cleaned_path = environ.get('PATH_INFO', '').strip('/') - for sep in os.sep, os.altsep: - if sep and sep != '/': - cleaned_path = cleaned_path.replace(sep, '/') - path = '/'.join([''] + [x for x in cleaned_path.split('/') - if x and x != '..']) - file_loader = None - for search_path, loader in self.exports.iteritems(): - if search_path == path: - real_filename, file_loader = loader(None) - if file_loader is not None: - break - if not search_path.endswith('/'): - search_path += '/' - if path.startswith(search_path): - real_filename, file_loader = loader(path[len(search_path):]) - if file_loader is not None: - break - if file_loader is None or not self.is_allowed(real_filename): - return self.app(environ, start_response) - - guessed_type = mimetypes.guess_type(real_filename) - mime_type = guessed_type[0] or self.fallback_mimetype - f, mtime, file_size = file_loader() - - etag = self.generate_etag(mtime, file_size, real_filename) - modified = werkzeug.http.is_resource_modified(environ, etag, last_modified=mtime) - - headers = [('Date', werkzeug.http.http_date())] - if self.cache: - timeout = self.cache_timeout - headers += [ - ('Etag', '"%s"' % etag), - ('Cache-Control', 'max-age=%d, public' % timeout) - ] - if modified: - headers.append(('Expires', werkzeug.http.http_date(time() + timeout))) - else: - headers.append(('Cache-Control', 'no-cache')) - - referer = environ.get('HTTP_REFERER', '') - parsed = urlparse.urlparse(referer) - debug = not urlparse.parse_qs(parsed.query).has_key('debug') - # it's important to put it at the end - if not debug and not modified: - f.close() - start_response('304 Not Modified', headers) - return [] - - headers.extend(( - ('Content-Type', mime_type), - ('Content-Length', str(file_size)), - ('Last-Modified', werkzeug.http.http_date(mtime)) - )) - start_response('200 OK', headers) - return werkzeug.wsgi.wrap_file(environ, f) - class LibException(Exception): """ Base of all client lib exceptions """ diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index c48ab0e3012..0a3d24d41f4 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -1,4 +1,4 @@ -@charset "utf-8"; +@charset "UTF-8"; @font-face { font-family: "mnmliconsRegular"; src: url("/web/static/src/font/mnmliconsv21-webfont.eot") format("eot"); @@ -34,7 +34,7 @@ background: white; /* http://www.quirksmode.org/dom/inputfile.html * http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image - */ */ + */ } .openerp a { text-decoration: none; @@ -234,14 +234,13 @@ .openerp.ui-dialog .ui-dialog-buttonpane { border-top: 1px solid #e0e0e0; background: #f5f7f9; - padding: 8px; margin: 0; -moz-border-radius: 0 0 2px 2px; -webkit-border-radius: 0 0 2px 2px; border-radius: 0 0 2px 2px; } .openerp.ui-dialog .ui-dialog-buttonpane button { - margin-left: 8px; + margin: 0; } .openerp.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: left; @@ -1855,9 +1854,12 @@ font-weight: bold; font-size: 18px; } +.openerp .oe_form .oe_subtotal_footer label:after { + content: ":"; +} .openerp .oe_form .oe_subtotal_footer label.oe_subtotal_footer_separator { font-weight: bold !important; - padding: 2px 8px 2px 0px !important; + padding: 2px 11px 2px 0px !important; } .openerp .oe_form .oe_subtotal_footer label.oe_form_label_help { font-weight: normal; @@ -2061,15 +2063,6 @@ .openerp .oe_form .oe_form_field_with_button.oe_no_button > .oe_button { display: none; } -.openerp .oe_form .oe_form_field_with_button:not(.oe_no_button) input { - border-right: none; - -webkit-border-top-right-radius: 0px; - -webkit-border-bottom-right-radius: 0px; - -moz-border-radius-topright: 0px; - -moz-border-radius-bottomright: 0px; - border-top-right-radius: 0px; - border-bottom-right-radius: 0px; -} .openerp .oe_form .oe_form_field_with_button:not(.oe_no_button) > .oe_button { float: right; -moz-border-radius: 0; @@ -2148,9 +2141,12 @@ } .openerp .oe_form_field_many2one span.oe_m2o_drop_down_button { position: absolute; - top: 1px; + top: 2px; right: 0px; } +.openerp .oe_form_field_many2one .oe_m2o_cm_button { + line-height: 14px; +} .openerp .oe_form .oe_form_field_one2many > .oe_view_manager .oe_list_pager_single_page { display: none; } diff --git a/addons/web/static/src/css/base.sass b/addons/web/static/src/css/base.sass index 8a2c510ec42..fb67945a02d 100644 --- a/addons/web/static/src/css/base.sass +++ b/addons/web/static/src/css/base.sass @@ -232,11 +232,10 @@ $sheet-max-width: 860px .ui-dialog-buttonpane border-top: 1px solid #e0e0e0 background: #f5f7f9 - padding: 8px margin: 0 @include radius(0 0 2px 2px) button - margin-left: 8px + margin: 0 .ui-dialog-buttonset float: left .ui-dialog-titlebar-close @@ -1444,9 +1443,11 @@ $sheet-max-width: 860px border-top: 1px solid #cacaca font-weight: bold font-size: 18px + label:after + content: ":" label.oe_subtotal_footer_separator font-weight: bold !important - padding: 2px 8px 2px 0px !important + padding: 2px 11px 2px 0px !important label.oe_form_label_help font-weight: normal // no sheet in popups @@ -1610,14 +1611,6 @@ $sheet-max-width: 860px .oe_form_field_with_button.oe_no_button > .oe_button display: none .oe_form_field_with_button:not(.oe_no_button) - input - border-right: none - -webkit-border-top-right-radius: 0px - -webkit-border-bottom-right-radius: 0px - -moz-border-radius-topright: 0px - -moz-border-radius-bottomright: 0px - border-top-right-radius: 0px - border-bottom-right-radius: 0px > .oe_button float: right @include radius(0) @@ -1691,8 +1684,10 @@ $sheet-max-width: 860px position: relative span.oe_m2o_drop_down_button position: absolute - top: 1px + top: 2px right: 0px + .oe_m2o_cm_button + line-height: 14px // }}} // FormView.one2many {{{ .oe_form .oe_form_field_one2many > .oe_view_manager diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index 3f389d3d41f..2e404a6bfdd 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -2739,10 +2739,20 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc this.$input.val(str.split("\n")[0]); this.current_display = this.$input.val(); } else { - str = _.escape(str).split("\n").join("
"); + var lines = _.escape(str).split("\n"); + var link = ""; + var follow = ""; + if (! this.get_definition_options().highlight_first_line) { + link = lines.join("
"); + } else { + link = lines[0]; + follow = _.rest(lines).join("
"); + if (follow) + link += "
"; + } this.$element.find('a') .unbind('click') - .html(str) + .html(link) .click(function () { self.do_action({ type: 'ir.actions.act_window', @@ -2754,6 +2764,7 @@ instance.web.form.FieldMany2One = instance.web.form.AbstractField.extend(instanc }); return false; }); + $(".oe_form_m2o_follow").html(follow); } }, set_value: function(value_) { diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 5779a6801ee..c80c1f8a3c6 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -951,11 +951,12 @@ - + + + + - + /