[ADD] selection of existing image in image dialog
authorXavier Morel <xmo@openerp.com>
Wed, 4 Sep 2013 11:32:22 +0000 (13:32 +0200)
committerXavier Morel <xmo@openerp.com>
Wed, 4 Sep 2013 11:32:22 +0000 (13:32 +0200)
bzr revid: xmo@openerp.com-20130904113222-xync5o48nwngvtj4

addons/website/controllers/main.py
addons/website/static/src/js/website.editor.js
addons/website/static/src/xml/website.editor.xml

index c2dd664..b6dc50b 100644 (file)
@@ -43,6 +43,7 @@ class Website(openerp.addons.web.controllers.main.Home):
     def admin(self, *args, **kw):
         return super(Website, self).index(*args, **kw)
 
+     # FIXME: auth, if /pagenew known anybody can create new empty page
     @route('/pagenew/<path:path>', type='http', auth="admin")
     def pagenew(self, path, noredirect=NOPE):
         if '.' in path:
@@ -146,7 +147,8 @@ class Website(openerp.addons.web.controllers.main.Home):
                 })
         return result
 
-    @route('/website/attach', type='http', auth='admin') # FIXME: auth
+    #  # FIXME: auth, anybody can upload an attachment if URL known/found
+    @route('/website/attach', type='http', auth='admin')
     def attach(self, func, upload):
         req = request.httprequest
         if req.method != 'POST':
@@ -172,6 +174,7 @@ class Website(openerp.addons.web.controllers.main.Home):
 
     @route('/website/attachment/<int:id>', type='http', auth="admin")
     def attachment(self, id):
+        # TODO: provide actual thumbnails?
         # FIXME: can't use Binary.image because auth=user and website attachments need to be public
         attachment = request.registry['ir.attachment'].browse(
             request.cr, request.uid, id, request.context)
index 941a0f7..42e35ea 100644 (file)
             },
             'change input[type=file]': 'file_selection',
             'change input.url': 'preview_image',
+            'click .existing-attachments a': 'select_existing',
         }),
         start: function () {
             var selection = this.editor.getSelection();
             this.element = null;
             if (el && el.is('img')) {
                 this.element = el;
-                this.$('input.url').val(el.getAttribute('src'));
-                this.preview_image();
+                this.set_image(el.getAttribute('src'));
             }
 
-            return this._super();
+            return $.when(
+                this._super(),
+                this.fetch_existing().then(this.proxy('fetched_existing')));
         },
         save: function () {
             var url = this.$('input.url').val();
             this._super();
         },
 
+        /**
+         * Sets the provided image url as the dialog's value-to-save and
+         * refreshes the preview element to use it.
+         */
+        set_image: function (url) {
+            this.$('input.url').val(url);
+            this.preview_image();
+        },
+
         file_selection: function (e) {
             this.$('button.filepicker').removeClass('btn-danger btn-success');
 
                 return;
             }
             $button.addClass('btn-success');
-            this.$('input.url').val(url);
-            this.preview_image();
+            this.set_image(url);
         },
         preview_image: function () {
             var image = this.$('input.url').val();
             if (!image) { return; }
 
-            this.$('img').attr('src', image);
+            this.$('img.image-preview').attr('src', image);
+        },
+
+        fetch_existing: function () {
+            // FIXME: lazy load attachments?
+            return openerp.jsonRpc('/web/dataset/call_kw', 'call', {
+                model: 'ir.attachment',
+                method: 'search_read',
+                args: [],
+                kwargs: {
+                    fields: ['name'],
+                    domain: [['res_model', '=', 'ir.ui.view']],
+                    order: 'name',
+                }
+            });
+        },
+        fetched_existing: function (records) {
+            // Create rows of 3 records
+            var rows = _(records).chain()
+                .groupBy(function (_, index) { return Math.floor(index / 3); })
+                .values()
+                .value();
+            this.$('.existing-attachments').replaceWith(
+                openerp.qweb.render('website.editor.dialog.image.existing', {rows: rows}));
+        },
+        select_existing: function (e) {
+            e.preventDefault();
+            this.set_image(e.currentTarget.getAttribute('href'));
         },
     });
 
 
     var Observer = window.MutationObserver || window.WebkitMutationObserver || window.JsMutationObserver;
     var observer = new Observer(function (mutations) {
+        // NOTE: Webkit does not fire DOMAttrModified => webkit browsers
+        //       relying on JsMutationObserver shim (Chrome < 18, Safari < 6)
+        //       will not mark dirty on attribute changes (@class, img/@src,
+        //       a/@href, ...)
         _(mutations).chain()
-            .filter(function (m) {
+                .filter(function (m) {
                 switch(m.type) {
                 case 'attributes':
                     // ignore cke_focus being added & removed from RTE root
index 4dd6a95..927ad3d 100644 (file)
                             Upload an image from your computer
                         </button>
                     </div>
+                    <p class="text-center">— or —</p>
+                    <div class="well">
+                        <h3 class="list-group-item-heading">Pick an existing attachment</h3>
+                        <div class="existing-attachments"/>
+                    </div>
                     <input type="hidden" name="func"/>
                 </form>
                 <div class="col-sm-4">
                     <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAC0lEQVQIHWP4zwAAAgEBAMVfG14AAAAASUVORK5CYII%3D"
-                         class="pull-right img-rounded"
+                         class="pull-right img-rounded image-preview"
                          width="100%"/>
                 </div>
             </div>
             <iframe src="about:blank" name="fileframe" class="hidden"/>
         </t>
     </t>
+    <t t-name="website.editor.dialog.image.existing">
+        <div class="existing-attachments">
+            <div class="row" t-foreach="rows" t-as="row">
+                <div class="col-md-4" t-foreach="row" t-as="attachment">
+                    <t t-set="url">/website/attachment/<t t-esc="attachment.id"/></t>
+                    <a t-att-href="url" class="thumbnail">
+                        <img t-att-src="url" t-att-alt="attachment.name"/>
+                    </a>
+                </div>
+            </div>
+        </div>
+    </t>
 </templates>