summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabien Pinckaers <fp@openerp.com>2012-07-18 00:14:08 +0200
committerFabien Pinckaers <fp@openerp.com>2012-07-18 00:14:08 +0200
commit36cde3d9fca0f786a8fa8dabf94bac71e1ae637a (patch)
treee05d1c8ede03d63cafacaf7150456570c0961a0f
parent2a89c6079c9f7f5d9135bcda777fda3f3ed8d859 (diff)
parent45c50d3a31cc9627e61384bd0c1c80f22c5e740e (diff)
[IMP] some cleaning in etherpad
bzr revid: fp@openerp.com-20120717221408-zk30i103f0erk4a3
-rw-r--r--addons/.bzrignore4
-rw-r--r--addons/pad/__init__.py3
-rw-r--r--addons/pad/__openerp__.py1
-rw-r--r--addons/pad/etherpad.py254
-rw-r--r--addons/pad/ir_attachment.py37
-rw-r--r--addons/pad/pad.py53
-rw-r--r--addons/pad/res_company.py7
-rw-r--r--addons/pad/res_company.xml1
-rw-r--r--addons/pad/static/src/css/etherpad.css71
-rw-r--r--addons/pad/static/src/js/pad.js55
-rw-r--r--addons/pad/static/src/xml/pad.xml10
-rw-r--r--addons/pad_project/__init__.py2
-rw-r--r--addons/pad_project/__openerp__.py4
-rw-r--r--addons/pad_project/models/__init__.py24
-rw-r--r--addons/pad_project/models/project_task.py17
-rw-r--r--addons/pad_project/models/project_task.xml15
-rw-r--r--addons/pad_project/project_task.py11
-rw-r--r--addons/pad_project/project_task.xml18
18 files changed, 473 insertions, 114 deletions
diff --git a/addons/.bzrignore b/addons/.bzrignore
index 8d98f9debde..5fee3e96f5d 100644
--- a/addons/.bzrignore
+++ b/addons/.bzrignore
@@ -1 +1,5 @@
.*
+pad/__init__.pyc
+pad/ir_attachment.pyc
+pad/res_company.pyc
+web_etherpad
diff --git a/addons/pad/__init__.py b/addons/pad/__init__.py
index 663cac2cbf0..ee80bcaf8d0 100644
--- a/addons/pad/__init__.py
+++ b/addons/pad/__init__.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+import pad
import res_company
-import ir_attachment
+
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/__openerp__.py b/addons/pad/__openerp__.py
index 267f595c7e5..bc4159089d7 100644
--- a/addons/pad/__openerp__.py
+++ b/addons/pad/__openerp__.py
@@ -25,6 +25,7 @@ Lets the company customize which Pad installation should be used to link to new
"static/src/xml/*.xml",
],
'images': ['static/src/img/pad_link_companies.jpeg'],
+ "css": ['static/src/css/etherpad.css',],
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/etherpad.py b/addons/pad/etherpad.py
new file mode 100644
index 00000000000..547720c1cc8
--- /dev/null
+++ b/addons/pad/etherpad.py
@@ -0,0 +1,254 @@
+#!/usr/bin/env python
+"""Module to talk to EtherpadLite API."""
+
+import json
+import urllib
+import urllib2
+
+
+class EtherpadLiteClient:
+ """Client to talk to EtherpadLite API."""
+ API_VERSION = 1 # TODO probably 1.1 sometime soon
+
+ CODE_OK = 0
+ CODE_INVALID_PARAMETERS = 1
+ CODE_INTERNAL_ERROR = 2
+ CODE_INVALID_FUNCTION = 3
+ CODE_INVALID_API_KEY = 4
+ TIMEOUT = 20
+
+ apiKey = ""
+ baseUrl = ""
+
+ def __init__(self, apiKey=None, baseUrl=None):
+ if apiKey:
+ self.apiKey = apiKey
+
+ if baseUrl:
+ self.baseUrl = baseUrl
+
+ def call(self, function, arguments=None):
+ """Create a dictionary of all parameters"""
+ url = '%s/%d/%s' % (self.baseUrl, self.API_VERSION, function)
+
+ params = arguments or {}
+ params.update({'apikey': self.apiKey})
+ data = urllib.urlencode(params, True)
+
+ try:
+ opener = urllib2.build_opener()
+ request = urllib2.Request(url=url, data=data)
+ response = opener.open(request, timeout=self.TIMEOUT)
+ result = response.read()
+ response.close()
+ except urllib2.HTTPError:
+ raise
+
+ result = json.loads(result)
+ if result is None:
+ raise ValueError("JSON response could not be decoded")
+
+ return self.handleResult(result)
+
+ def handleResult(self, result):
+ """Handle API call result"""
+ if 'code' not in result:
+ raise Exception("API response has no code")
+ if 'message' not in result:
+ raise Exception("API response has no message")
+
+ if 'data' not in result:
+ result['data'] = None
+
+ if result['code'] == self.CODE_OK:
+ return result['data']
+ elif result['code'] == self.CODE_INVALID_PARAMETERS or result['code'] == self.CODE_INVALID_API_KEY:
+ raise ValueError(result['message'])
+ elif result['code'] == self.CODE_INTERNAL_ERROR:
+ raise Exception(result['message'])
+ elif result['code'] == self.CODE_INVALID_FUNCTION:
+ raise Exception(result['message'])
+ else:
+ raise Exception("An unexpected error occurred whilst handling the response")
+
+ # GROUPS
+ # Pads can belong to a group. There will always be public pads that do not belong to a group (or we give this group the id 0)
+
+ def createGroup(self):
+ """creates a new group"""
+ return self.call("createGroup")
+
+ def createGroupIfNotExistsFor(self, groupMapper):
+ """this functions helps you to map your application group ids to etherpad lite group ids"""
+ return self.call("createGroupIfNotExistsFor", {
+ "groupMapper": groupMapper
+ })
+
+ def deleteGroup(self, groupID):
+ """deletes a group"""
+ return self.call("deleteGroup", {
+ "groupID": groupID
+ })
+
+ def listPads(self, groupID):
+ """returns all pads of this group"""
+ return self.call("listPads", {
+ "groupID": groupID
+ })
+
+ def createGroupPad(self, groupID, padName, text=''):
+ """creates a new pad in this group"""
+ params = {
+ "groupID": groupID,
+ "padName": padName,
+ }
+ if text:
+ params['text'] = text
+ return self.call("createGroupPad", params)
+
+ # AUTHORS
+ # Theses authors are bind to the attributes the users choose (color and name).
+
+ def createAuthor(self, name=''):
+ """creates a new author"""
+ params = {}
+ if name:
+ params['name'] = name
+ return self.call("createAuthor", params)
+
+ def createAuthorIfNotExistsFor(self, authorMapper, name=''):
+ """this functions helps you to map your application author ids to etherpad lite author ids"""
+ params = {
+ 'authorMapper': authorMapper
+ }
+ if name:
+ params['name'] = name
+ return self.call("createAuthorIfNotExistsFor", params)
+
+ # SESSIONS
+ # Sessions can be created between a group and a author. This allows
+ # an author to access more than one group. The sessionID will be set as
+ # a cookie to the client and is valid until a certain date.
+
+ def createSession(self, groupID, authorID, validUntil):
+ """creates a new session"""
+ return self.call("createSession", {
+ "groupID": groupID,
+ "authorID": authorID,
+ "validUntil": validUntil
+ })
+
+ def deleteSession(self, sessionID):
+ """deletes a session"""
+ return self.call("deleteSession", {
+ "sessionID": sessionID
+ })
+
+ def getSessionInfo(self, sessionID):
+ """returns informations about a session"""
+ return self.call("getSessionInfo", {
+ "sessionID": sessionID
+ })
+
+ def listSessionsOfGroup(self, groupID):
+ """returns all sessions of a group"""
+ return self.call("listSessionsOfGroup", {
+ "groupID": groupID
+ })
+
+ def listSessionsOfAuthor(self, authorID):
+ """returns all sessions of an author"""
+ return self.call("listSessionsOfAuthor", {
+ "authorID": authorID
+ })
+
+ # PAD CONTENT
+ # Pad content can be updated and retrieved through the API
+
+ def getText(self, padID, rev=None):
+ """returns the text of a pad"""
+ params = {"padID": padID}
+ if rev is not None:
+ params['rev'] = rev
+ return self.call("getText", params)
+
+ # introduced with pull request merge
+ def getHtml(self, padID, rev=None):
+ """returns the html of a pad"""
+ params = {"padID": padID}
+ if rev is not None:
+ params['rev'] = rev
+ return self.call("getHTML", params)
+
+ def setText(self, padID, text):
+ """sets the text of a pad"""
+ return self.call("setText", {
+ "padID": padID,
+ "text": text
+ })
+
+ def setHtml(self, padID, html):
+ """sets the text of a pad from html"""
+ return self.call("setHTML", {
+ "padID": padID,
+ "html": html
+ })
+
+ # PAD
+ # Group pads are normal pads, but with the name schema
+ # GROUPID$PADNAME. A security manager controls access of them and its
+ # forbidden for normal pads to include a in the name.
+
+ def createPad(self, padID, text=''):
+ """creates a new pad"""
+ params = {
+ "padID": padID,
+ }
+ if text:
+ params['text'] = text
+ return self.call("createPad", params)
+
+ def getRevisionsCount(self, padID):
+ """returns the number of revisions of this pad"""
+ return self.call("getRevisionsCount", {
+ "padID": padID
+ })
+
+ def deletePad(self, padID):
+ """deletes a pad"""
+ return self.call("deletePad", {
+ "padID": padID
+ })
+
+ def getReadOnlyID(self, padID):
+ """returns the read only link of a pad"""
+ return self.call("getReadOnlyID", {
+ "padID": padID
+ })
+
+ def setPublicStatus(self, padID, publicStatus):
+ """sets a boolean for the public status of a pad"""
+ return self.call("setPublicStatus", {
+ "padID": padID,
+ "publicStatus": publicStatus
+ })
+
+ def getPublicStatus(self, padID):
+ """return true of false"""
+ return self.call("getPublicStatus", {
+ "padID": padID
+ })
+
+ def setPassword(self, padID, password):
+ """returns ok or a error message"""
+ return self.call("setPassword", {
+ "padID": padID,
+ "password": password
+ })
+
+ def isPasswordProtected(self, padID):
+ """returns true or false"""
+ return self.call("isPasswordProtected", {
+ "padID": padID
+ })
+
diff --git a/addons/pad/ir_attachment.py b/addons/pad/ir_attachment.py
deleted file mode 100644
index ba8c88632dd..00000000000
--- a/addons/pad/ir_attachment.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- coding: utf-8 -*-
-from osv import fields, osv
-import random
-import string
-
-class ir_attachment(osv.osv):
- _inherit = 'ir.attachment'
-
- def pad_generate_url(self, cr, uid, model, id):
- pad_url_template = self.pool.get('res.users').browse(cr,uid,[uid])[0].company_id.pad_url_template
- s = string.ascii_uppercase + string.digits
- salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(8)])
- template_vars = {
- 'db' : cr.dbname,
- 'model' : model,
- 'id' : id,
- 'salt' : salt,
- 'name' : '',
- }
- return pad_url_template % template_vars
-
- def pad_get(self, cr, uid, model, id):
- attachment = self.search(cr, uid, [('res_model', '=', model), ('res_id', '=', id), ('type', '=', 'url'), ('name', '=', 'Pad')])
- if attachment:
- return self.read(cr, uid, attachment)[0]['url']
- else:
- url = self.pad_generate_url(cr, uid, model, id)
- self.create(cr, uid, {
- 'res_model' : model,
- 'res_id' : id,
- 'type' : 'url',
- 'name' : 'Pad',
- 'url' : url,
- })
- return url
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/pad.py b/addons/pad/pad.py
new file mode 100644
index 00000000000..c7e448767bc
--- /dev/null
+++ b/addons/pad/pad.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+from osv import fields, osv
+import random
+import string
+from etherpad import EtherpadLiteClient
+import urllib2
+from tools.translate import _
+
+
+class pad_common(osv.osv_memory):
+ _name = 'pad.common'
+ _pad_url = None # name of the field for the etherpad
+ def pad_generate_url(self, cr, uid, model, context=None):
+ pad_url_template = self._pad_url_template(cr, uid, context)
+ s = string.ascii_uppercase + string.digits
+ salt = ''.join([s[random.randint(0, len(s) - 1)] for i in range(8)])
+ template_vars = {
+ 'db' : cr.dbname,
+ 'model' : model,
+ 'salt' : salt,
+ }
+ url = pad_url_template % template_vars
+ api_key = self._pad_api_key(cr, uid, context)
+ if api_key:
+ urls = url.split('/')
+ api_url = '/'.join(urls[:3]) + "/api"
+ pad_id = urls[-1]
+ ep_client = EtherpadLiteClient(api_key, api_url)
+ try:
+ ep_client.createPad(pad_id," ")
+ except ValueError as strerror:
+ raise osv.except_osv(_('Configuration Error !'),_("Etherpad Have Wrong API Key."))
+ except urllib2.HTTPError as e:
+ raise osv.except_osv(_('Configuration Error !'),_("Etherpad Have Wrong API URL."))
+ except urllib2.URLError as e:
+ raise osv.except_osv(_('Configuration Error !'),_("Etherpad Have Wrong Pad URL Template."))
+ return url
+
+ def _pad_api_key(self, cr, uid, context=None):
+ return self.pool.get('res.users').browse(cr,uid, uid, context).company_id.etherpad_api_key
+
+ def _pad_url_template(self, cr, uid, context=None):
+ return self.pool.get('res.users').browse(cr,uid, uid, context).company_id.pad_url_template
+
+ def copy(self, cr, uid, id, default=None, context=None):
+ if not default:
+ default = {}
+ default.update({
+ self._pad_url:self.pad_generate_url(cr, uid, self._name),
+ })
+ return super(pad_common, self).copy(cr, uid, id, default, context)
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad/res_company.py b/addons/pad/res_company.py
index 0c1dc7c4929..4ce27fd4d22 100644
--- a/addons/pad/res_company.py
+++ b/addons/pad/res_company.py
@@ -1,14 +1,19 @@
# -*- coding: utf-8 -*-
from osv import fields, osv
+PAD_TEMPLATE = 'http://beta.etherpad.org/p/%(db).10s-%(model)s-%(salt)s'
+PAD_API_KEY = 'EtherpadFTW'
+
class company_pad(osv.osv):
_inherit = 'res.company'
_columns = {
'pad_url_template': fields.char('Pad URL Template', size=128, required=True,
help="Template used to generate pad URL."),
+ 'etherpad_api_key': fields.char('Pad API Key', size=128),
}
_defaults = {
- 'pad_url_template': 'http://ietherpad.com/%(db)s-%(model)s-%(id)d-%(salt)s-%(name)s'
+ 'pad_url_template': PAD_TEMPLATE,
+ 'etherpad_api_key': PAD_API_KEY,
}
diff --git a/addons/pad/res_company.xml b/addons/pad/res_company.xml
index 9b1c0656470..96c3c004bef 100644
--- a/addons/pad/res_company.xml
+++ b/addons/pad/res_company.xml
@@ -9,6 +9,7 @@
<xpath expr="//group[@name='account_grp']" position="after">
<group string="Pads">
<field name="pad_url_template"/>
+ <field name="etherpad_api_key"/>
</group>
</xpath>
</field>
diff --git a/addons/pad/static/src/css/etherpad.css b/addons/pad/static/src/css/etherpad.css
new file mode 100644
index 00000000000..fd804c95472
--- /dev/null
+++ b/addons/pad/static/src/css/etherpad.css
@@ -0,0 +1,71 @@
+.etherpad_head{
+ width: 99.7%;
+ display: block;
+ border-radius: 3px 3px 0px 0px;
+ background: -webkit-linear-gradient( #F7F7F7, #F1F1F1 80%);
+ padding-left:3px;
+ cursor:pointer;
+}
+.etherpad_zoom_head{
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 15px;
+}
+.etherpad_zoom{
+ position: fixed;
+ left: 0px;
+ top: 15px;
+ width: 100%;
+ height: 98% !important;
+ z-index:10001 !important;
+ background-color:white;
+}
+.etherpad_default{
+ width: 100%;
+ height: 450px;
+}
+.etherpad_body{
+ overflow:hidden;
+}
+
+.etherpad_readonly{
+ width: 97.2%;
+ height: 450px;
+ padding:7px 7px 10px 10px;
+ overflow:auto;
+}
+.etherpad_readonly ul,.etherpad_readonly ol{
+ -webkit-margin-before: 1em;
+ -webkit-margin-after: 1em;
+ -webkit-margin-start: 0px;
+ -webkit-margin-end: 0px;
+ -webkit-padding-start: 40px !important;
+}
+.etherpad_readonly ul li{
+ list-style-type: disc;
+}
+.etherpad_readonly ol li{
+ list-style-type: decimal;
+}
+.etherpad_readonly .indent li{
+ list-style-type: none !important;
+}
+
+
+.etherpad_readonly{
+ font-family: arial, sans-serif;
+ font-size: 13px;
+ line-height: 17px;
+}
+
+.etherpad_readonly ul.indent { list-style-type: none !important; }
+.etherpad_readonly ol li{ list-style-type: decimal !important; }
+.etherpad_readonly ol ol li{ list-style-type: lower-latin !important; }
+.etherpad_readonly ol ol ol li{ list-style-type: lower-roman !important; }
+.etherpad_readonly ol ol ol ol li{ list-style-type: decimal !important; }
+.etherpad_readonly ol ol ol ol ol li{ list-style-type: lower-latin !important; }
+.etherpad_readonly ol ol ol ol ol ol li{ list-style-type: lower-roman !important; }
+.etherpad_readonly ol ol ol ol ol ol ol li{ list-style-type: decimal !important; }
+.etherpad_readonly ol ol ol ol ol ol ol ol li{ list-style-type: lower-latin !important; }
diff --git a/addons/pad/static/src/js/pad.js b/addons/pad/static/src/js/pad.js
index 2e5f8820ac4..3f13df45d48 100644
--- a/addons/pad/static/src/js/pad.js
+++ b/addons/pad/static/src/js/pad.js
@@ -1,18 +1,41 @@
openerp.pad = function(instance) {
-instance.web.Sidebar = instance.web.Sidebar.extend({
- init: function(parent) {
- this._super(parent);
- this.add_items('other',[{ label: "Pad", callback: this.on_add_pad }]);
- },
- on_add_pad: function() {
- var self = this;
- var view = this.getParent();
- var model = new instance.web.Model('ir.attachment');
- model.call('pad_get', [view.model ,view.datarecord.id],{}).then(function(r) {
- self.do_action({ type: "ir.actions.act_url", url: r });
- });
- }
-});
-
-};
+instance.web.form.FieldEtherpad = instance.web.form.AbstractField.extend(_.extend({}, instance.web.form.ReinitializeFieldMixin, {
+ template: 'FieldEtherpad',
+ initialize_content: function() {
+ this.$textarea = undefined;
+ this.$element.find('span').text(this.field.string);
+ this.$element.find('span').click(_.bind(function(ev){
+ this.$element.find('span').toggleClass('etherpad_zoom_head');
+ var iszoom = this.$element.find('span').hasClass('etherpad_zoom_head');
+ this.$element.find('span').text((iszoom?'Back to Task':this.field.string));
+ this.$element.find('div').toggleClass('etherpad_zoom');
+ $("body").toggleClass('etherpad_body');
+ },this));
+ },
+ set_value: function(value_) {
+ this._super(value_);
+ this.render_value();
+ },
+ render_value: function() {
+ var show_value = instance.web.format_value(this.get('value'), this, '');
+ if (!this.get("effective_readonly")) {
+ var pad_username = this.session.username;
+ this.$element.find('div').html('<iframe width="100%" height="100%" frameborder="0" src="'+show_value.split('\n')[0]+'?showChat=false&showLineNumbers=false&userName='+pad_username+'"></iframe>');
+ } else {
+ if(this.get('value') != false)
+ {
+ var self = this;
+ if(show_value.split('\n')[0] != '')
+ $.get(show_value.split('\n')[0]+'/export/html')
+ .success(function(data) { self.$element.html('<div class="etherpad_readonly">'+data+'</div>'); })
+ .error(function() { self.$element.text('Unable to load pad'); });
+ }
+ }
+ },
+ }));
+
+ instance.web.form.widgets = instance.web.form.widgets.extend({
+ 'etherpad': 'instance.web.form.FieldEtherpad',
+ });
+};
diff --git a/addons/pad/static/src/xml/pad.xml b/addons/pad/static/src/xml/pad.xml
index e922294d03d..334064e88a1 100644
--- a/addons/pad/static/src/xml/pad.xml
+++ b/addons/pad/static/src/xml/pad.xml
@@ -2,4 +2,14 @@
<!-- vim:fdl=1:
-->
<templates id="template" xml:space="preserve">
+
+<t t-name="FieldEtherpad">
+ <t t-if="!widget.get('effective_readonly')">
+ <div class="oe_form_field_text">
+ <span class="etherpad_head"></span>
+ <div class="etherpad_default" ></div>
+ </div>
+ </t>
+</t>
+
</templates>
diff --git a/addons/pad_project/__init__.py b/addons/pad_project/__init__.py
index d6bf9f9551c..098de31a5a4 100644
--- a/addons/pad_project/__init__.py
+++ b/addons/pad_project/__init__.py
@@ -19,6 +19,6 @@
#
##############################################################################
-import models
+import project_task
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/__openerp__.py b/addons/pad_project/__openerp__.py
index 8ca761d2737..61ebfa8f17f 100644
--- a/addons/pad_project/__openerp__.py
+++ b/addons/pad_project/__openerp__.py
@@ -31,9 +31,9 @@ This module adds a PAD in all project kanban views
'website': 'http://www.openerp.com',
'depends': ['project', 'pad'],
'init_xml': [],
- 'update_xml': ['models/project_task.xml'],
+ 'update_xml': ['project_task.xml'],
'demo_xml': [],
'installable': True,
- 'auto_install': False,
+ 'auto_install': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/models/__init__.py b/addons/pad_project/models/__init__.py
deleted file mode 100644
index 098de31a5a4..00000000000
--- a/addons/pad_project/models/__init__.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-import project_task
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/models/project_task.py b/addons/pad_project/models/project_task.py
deleted file mode 100644
index c215aed1325..00000000000
--- a/addons/pad_project/models/project_task.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-from tools.translate import _
-from osv import fields, osv
-
-class task(osv.osv):
- _inherit = "project.task"
-
- def pad_get(self, cr, uid, ids, context=None):
- """Get pad action
- """
- url = self.pool.get("ir.attachment").pad_get(cr, uid, self._name, ids[0])
- return {
- 'type': 'ir.actions.act_url',
- 'url': url
- }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/pad_project/models/project_task.xml b/addons/pad_project/models/project_task.xml
deleted file mode 100644
index 3c734cf3b97..00000000000
--- a/addons/pad_project/models/project_task.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<openerp>
- <data>
- <record id="view_task_kanban_with_pad" model="ir.ui.view">
- <field name="name">project.task.kanban.pad</field>
- <field name="model">project.task</field>
- <field name="type">kanban</field>
- <field name="inherit_id" ref="project.view_task_kanban"/>
- <field name="arch" type="xml">
- <xpath expr="//span[@class='oe_kanban_project_times']" position="before">
- <a name="pad_get" string="Pad" type="object" class="oe_kanban_button" style="margin-left: 5px;"><b>PAD</b></a>
- </xpath>
- </field>
- </record>
- </data>
-</openerp>
diff --git a/addons/pad_project/project_task.py b/addons/pad_project/project_task.py
new file mode 100644
index 00000000000..96e1ef86e4d
--- /dev/null
+++ b/addons/pad_project/project_task.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from tools.translate import _
+from osv import fields, osv
+
+class task(osv.osv):
+ _name = "project.task"
+ _inherit = ["project.task",'pad.common']
+ _pad_url = 'description'
+ _defaults = {
+ _pad_url: lambda self, cr, uid, context: self.pad_generate_url(cr, uid, self._name, context),
+ }
diff --git a/addons/pad_project/project_task.xml b/addons/pad_project/project_task.xml
new file mode 100644
index 00000000000..da9a9b2c3a1
--- /dev/null
+++ b/addons/pad_project/project_task.xml
@@ -0,0 +1,18 @@
+<openerp>
+ <data>
+ <record id="view_task_form_with_pad" model="ir.ui.view">
+ <field name="name">project.task.form.pad</field>
+ <field name="model">project.task</field>
+ <field name="type">form</field>
+ <field name="inherit_id" ref="project.view_task_form2"/>
+ <field name="arch" type="xml">
+ <field name="description" position="replace">
+ <field name="description"
+ attrs="{'readonly':[('state','=','done')]}"
+ widget="etherpad"
+ />
+ </field>
+ </field>
+ </record>
+ </data>
+</openerp>