Merge lp:~serpentcs/web-addons/multi_image_7.0 into lp:~webaddons-core-editors/web-addons/7.0
- multi_image_7.0
- Merge into 7.0
Status: | Work in progress |
---|---|
Proposed branch: | lp:~serpentcs/web-addons/multi_image_7.0 |
Merge into: | lp:~webaddons-core-editors/web-addons/7.0 |
Diff against target: |
1423 lines (+1313/-0) 13 files modified
multi_image/__init__.py (+25/-0) multi_image/__openerp__.py (+50/-0) multi_image/controllers/__init__.py (+25/-0) multi_image/controllers/main.py (+61/-0) multi_image/static/lib/lightbox/css/lightbox.css (+128/-0) multi_image/static/lib/lightbox/js/jquery.lightbox.js (+501/-0) multi_image/static/src/css/hoverbox.css (+52/-0) multi_image/static/src/js/multi_image.js (+227/-0) multi_image/static/src/xml/image_multi.xml (+126/-0) multi_image_sample/__init__.py (+25/-0) multi_image_sample/__openerp__.py (+39/-0) multi_image_sample/product.py (+34/-0) multi_image_sample/product_view.xml (+20/-0) |
To merge this branch: | bzr merge lp:~serpentcs/web-addons/multi_image_7.0 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexandre Fayolle - camptocamp | Abstain | ||
Nhomar - Vauxoo | Needs Fixing | ||
Serpent Consulting Services (community) | Needs Resubmitting | ||
Review via email: mp+179857@code.launchpad.net |
Commit message
Description of the change
Nhomar - Vauxoo (nhomar) wrote : | # |
Other point (writting in the speed i read the code)
To be a communitary module with a good approach like this i think it needs demo data what do you think?
Nhomar - Vauxoo (nhomar) wrote : | # |
Idea: We should have one module that just add the lightbox lib and the widget.
And other modules that enable this feature in different models.
Because theorically it is an special widget that can be used in almost any model right?
Nhomar - Vauxoo (nhomar) wrote : | # |
Problem.
If I am behind nginx with max_file_size setted on the web server the error is not correctly managed, the widget stay loading and the request response is not shown.
Nhomar - Vauxoo (nhomar) wrote : | # |
The aspect ratio have some little problems.
https:/
....
Nhomar - Vauxoo (nhomar) wrote : | # |
Some conclusions, IMHO you give me personally a good approach in terms of algorith to include this widget.
Can i improve it before merge? or split the job to make a better approach of this amazing feature?
Regards.
Nhomar - Vauxoo (nhomar) wrote : | # |
In Icons.
If you use class oe_e or the ui-icon-* (from bootstrap) in this way you dont need images.
BTW, openerp itself have all this images alreade availables on: /web/addons/
IMHO 2 options, or use fonts (who really see cool) or use the available icons.
Regards.
Nhomar - Vauxoo (nhomar) wrote : | # |
About This: Correction... To be a communitary module with a good approach like this i think it needs demo data what do you think?
It is done because you set the widget on Product, sorry my mistake, BTW documentation in __openerp__.py should be a little more complete.
Regards.
Serpent Consulting Services (serpent-consulting-services) wrote : | # |
Nhomar,
Yo!
Yogesh will take a look and proceed. I really appreciate your feedback, will help us improve and also will help this widget land into v8.
Thanks.
Nhomar - Vauxoo (nhomar) wrote : | # |
Other tip (I will make it anyway.)
https:/
This library mix bootstrap 2 with lightbox, as you should know boostrap 2 is almost embeded in openerp 7.0 and will be totally embeded in OpenERP 8.0 in its version 3.0 giving us a big power in terms of css.
I think we should:
1.- MAke a first module that just put available the library in openerp no more.
2.- Make a module that build the widget.
IMHO if we make in this way we can mix several concepts.
For example:
1.- You way to do things, list of texts to mix with the product view.
2.- Build some kind of "View Gallery" inheriting the kanban view.
3.- Use the library to build static content as helps, improve process view and so on.
We are working actually in 2 and 3 because we need internally, and you are working in multi_image widget.
We as team can not depend of your widget to have the lib available, and i think it is a dirty hacking just overwrit it.
I weill come back with a MP with a modules called web_bootstrap3 web_bootstrap2 and web_lightbox_
What do you think?.
REgards.
Yogesh (SerpentCS) (yogesh-serpentcs) wrote : | # |
Nhomar,
Thanks for your suggestion.
We will check it and Improve the module.
We will create separate module for multi image widget and multi image sample.
We are already in good stage for progress.
Serpent Consulting Services (serpent-consulting-services) wrote : | # |
Team,
Updates:
Improved the view of list of all images. now we didn't set static height.
Created separate module for widget and multi_image sample for adde field in product object.
Removed the image file in multi_image module and used icon of web module.
Thanks.
- 6. By Serpent Consulting Services
-
[FIX/IMP] updates for the improvement of widget
- 7. By Serpent Consulting Services
-
Merged with parent
Nhomar - Vauxoo (nhomar) wrote : | # |
Hello Jay/Husen
Thanks for take care about details mentioned, Just few remarks.
1.- The widget module should be called "web_*" to follow the line of web-specific modules.
2.- The "sample" can be called by its name, may be "product_
Some questions:
1.- I really dont like write thinks in the code path (even the official ftp module allow configure thing out the path) can we have some extra entry in the config file for it (or use one of the existing)
2.- You are using ID for positioning the "lightbox" thing, as i remember i think it is a bad practice due to the generic way how things are done in openerp, can you analyse how can we namespace this IDS with classes or with other strategy?
I think we should explain in the __openerp__.py a little deeper the behaviour i.e:
For the widget module: Explain basic things about how to use (i.e. what attribute i should use in xml definition), explain limitations and the way it technically works, reading the code is possible for sure i did myself, but as technical module and with apps without explanation in the terp file, people will no be able to use it.
For the product module: Explain that paths will be saved as text and blah blah blah.
Regards.
Nhomar - Vauxoo (nhomar) wrote : | # |
Now some technical remarks, after using it and check deeper.
1.-
In the save algorithm, you are verifying if the file is really an image i find an algorithm that i used frequently to do that:
http://
We should use something like this.
2.- I couldn't find the algorithm when somebody remove the file from list can you enlight me there please?
3.- Why the name is mixed with timestamp on server?
http://
In this thread there is a more ellegant way to solve the unique name part.
BTW: 2 and 3 are solved in document_* module we should is mix both.
TIP: We are trying to find what is the algorithm behind the mail module who makes something like i am asking for, may be is better study these in beep and not re - invent the wheel ;-).
If you think technically the document_* have some problem, it should be great if you comment about this and we can figure out a Final Solution for this.
Good Job and really thanks for the effort here friend.
Pedro Manuel Baeza (pedro.baeza) wrote : | # |
Hi, I want to test this interesting module, but I'll wait until you fix Nhomar remarks, so please comment this MP to get notified when you do the changes.
Nhomar - Vauxoo (nhomar) wrote : | # |
Hello Friend.
I found the support for the security issue, "at least from my point of view".
Point 1:
167 + file_name = current_dat_time + "_" + ufile.filename
With this line we brake a Python Standard, we have some libraries to manage the file names in a secure way, "Why use dates?".
One option:
http://
AFAIK It is already implemented on document_ftp
Point 2:
Your module "without ask the user or/and the technicians" is writing over the web/module, it is a big security issue even with community addons, you can find the support about why name space correctly where you put your files.
168 + addons_path = openerpweb.
Option 1:
In this case you can use the static_
Option 2:
Extend the document module giving the access to the folders to physical folders.
IOH, FYI, we are working on it, and we think it is a best approach, do you think we can merge the concepts in your module?
http://
IMHO, it should be done extending the dms in OpenERP (with your approach of upload and make public), if you have some point against it it should be great if you share your thoughts.
For now and until we can not solve the security issues (or support them)
ICONS: Please use generic icons with a little mention to your company specifying the use of the module, avoind use your branding __only__
Descriptors.
Can you please explain a little how use the module in the descriptor?
Conclusion,
For me it is a great approach __really__ but it should be great if you can argue my points or improve in your code, please (or better put the branch with openerp-community owner and we can help ;-) )
Nhomar - Vauxoo (nhomar) wrote : | # |
A little hole is:
158 + def upload_
As you can see it is not asking for the session object to validate ACL. I dob have time now to prepare an use case, but it is dangerous.
See how i think we have an important security hole with the approach as you solve it to upload files.
Yogesh (SerpentCS) (yogesh-serpentcs) wrote : | # |
> Hello Friend.
>
> I found the support for the security issue, "at least from my point of view".
>
> Point 1:
>
> 167 + file_name = current_dat_time + "_" + ufile.filename
>
> With this line we brake a Python Standard, we have some libraries to manage
> the file names in a secure way, "Why use dates?".
>
> One option:
>
> http://
> names-in-python
We set unique file name. if we use uuid python library then may be it will generate duplicate number so it will be conflicts with existing file name. let me check it there another lib for generate unique number not generate duplicate number in any case.
>
> AFAIK It is already implemented on document_ftp
>
> Point 2:
>
> Your module "without ask the user or/and the technicians" is writing over the
> web/module, it is a big security issue even with community addons, you can
> find the support about why name space correctly where you put your files.
>
> 168 + addons_path =
> openerpweb.
> "/web/static/
We must be store the image in openerp server directory we cannot set file any other directory because for displaying image we just give path for display image in web-browser.
>
> Option 1:
> In this case you can use the static_
> file, and if it is not setted ask for one with a raise may be.
> Option 2:
> Extend the document module giving the access to the folders to physical
> folders.
if we store file in any other directory on server like path store in config file or use static_
>
> IOH, FYI, we are working on it, and we think it is a best approach, do you
> think we can merge the concepts in your module?
>
>
> http://
>
> IMHO, it should be done extending the dms in OpenERP (with your approach of
> upload and make public), if you have some point against it it should be great
> if you share your thoughts.
DMS also store file in server directory with random unique file name.
We will improve module for security reason.
> For now and until we can not solve the security issues (or support them)
>
> ICONS: Please use generic icons with a little mention to your company
> specifying the use of the module, avoind use your branding __only__
>
> Descriptors.
>
> Can you please explain a little how use the module in the descriptor?
>
> Conclusion,
>
> For me it is a great approach __really__ but it should be great if you can
> argue my points or improve in your code, please (or better put the branch with
> openerp-community owner and we can help ;-) )
We will Improve code as per your suggestions and we will add description in openerp.py file too.
Thanks for nice suggestions.
Nhomar - Vauxoo (nhomar) wrote : | # |
Hello Yogesh.
COmments inline (it should be grate in the MP) ;-)
2013/9/28 Yogesh (SerpentCS) <email address hidden>
> > Hello Friend.
> >
> > I found the support for the security issue, "at least from my point of
> view".
> >
> > Point 1:
> >
> > 167 + file_name = current_dat_time + "_" + ufile.filename
> >
> > With this line we brake a Python Standard, we have some libraries to
> manage
> > the file names in a secure way, "Why use dates?".
> >
> > One option:
> >
> >
> http://
> > names-in-python
>
> We set unique file name. if we use uuid python library then may be it will
> generate duplicate number so it will be conflicts with existing file name.
> let me check it there another lib for generate unique number not generate
> duplicate number in any case.
>
Yes i got it, but the "datetime" imho is an ugly solution, we can use
hash, uuid, ond / or your own algorithm It is my point, in the link you
have the 3 options explained.
>
> >
> > AFAIK It is already implemented on document_ftp
> >
> > Point 2:
> >
> > Your module "without ask the user or/and the technicians" is writing
> over the
> > web/module, it is a big security issue even with community addons, you
> can
> > find the support about why name space correctly where you put your files.
> >
> > 168 + addons_path =
> > openerpweb.
> > "/web/static/
>
> We must be store the image in openerp server directory we cannot set file
> any other directory because for displaying image we just give path for
> display image in web-browser.
>
Noup, it is not true, you can use the "static" folder of any module, not
just from web, it means, if we install a new module, i can not "Without
ask" save in the server folder.
document module have a exchangeable folder with an configured by default,
if you think it is possible, We are working this week on it, we can share
efforts to do that.
> >
> > Option 1:
> > In this case you can use the static_
> config
> > file, and if it is not setted ask for one with a raise may be.
> > Option 2:
> > Extend the document module giving the access to the folders to physical
> > folders.
> if we store file in any other directory on server like path store in
> config file or use static_
> path so it's time consuming it's take much time for loading images. User
> open the all images then fetch the image datas using rpc call and display
> image base on datas.
>
Noup, I think i can not explain by myself well.
The document module give you the ability to "index" all uploaded files, the
file storage is extensible, and you can serve them directly http (exactly
as the static folder does) then, IMHO it is a matter of dedicate some time
to it.
Even we have a ir.attachment type called "url" that can be used to share it
trhought http.
It is a littel more complicated but by far more secure, due to in "Creation
TIme" you can manage the own ACL of OpenERP and in "Serve TIme" just serve
them with an standard http request, (the...
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote : | # |
Since this is a large MP, it would be very helpful for reviewers if you could take a few minutes to give an overview of the modules you are contributing in the 'description' section at the top of this page (listing the different addons and their purpose...)
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
According to message https:/
This is WIP
Unmerged revisions
- 7. By Serpent Consulting Services
-
Merged with parent
- 6. By Serpent Consulting Services
-
[FIX/IMP] updates for the improvement of widget
- 5. By Serpent Consulting Services
-
[ADD] Added multi_image module : more info at http://
www.serpentcs. com/serpentcs- openerp- multi-image- lightbox- widget
Preview Diff
1 | === added directory 'multi_image' |
2 | === added file 'multi_image/__init__.py' |
3 | --- multi_image/__init__.py 1970-01-01 00:00:00 +0000 |
4 | +++ multi_image/__init__.py 2013-09-11 08:32:35 +0000 |
5 | @@ -0,0 +1,25 @@ |
6 | +# -*- coding: utf-8 -*- |
7 | +############################################################################## |
8 | +# |
9 | +# OpenERP, Open Source Management Solution |
10 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
11 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
12 | +# |
13 | +# This program is free software: you can redistribute it and/or modify |
14 | +# it under the terms of the GNU Affero General Public License as |
15 | +# published by the Free Software Foundation, either version 3 of the |
16 | +# License, or (at your option) any later version. |
17 | +# |
18 | +# This program is distributed in the hope that it will be useful, |
19 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | +# GNU Affero General Public License for more details. |
22 | +# |
23 | +# You should have received a copy of the GNU Affero General Public License |
24 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
25 | +# |
26 | +############################################################################## |
27 | + |
28 | +import controllers |
29 | + |
30 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
31 | \ No newline at end of file |
32 | |
33 | === added file 'multi_image/__openerp__.py' |
34 | --- multi_image/__openerp__.py 1970-01-01 00:00:00 +0000 |
35 | +++ multi_image/__openerp__.py 2013-09-11 08:32:35 +0000 |
36 | @@ -0,0 +1,50 @@ |
37 | +# -*- coding: utf-8 -*- |
38 | +############################################################################## |
39 | +# |
40 | +# OpenERP, Open Source Management Solution |
41 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
42 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
43 | +# |
44 | +# This program is free software: you can redistribute it and/or modify |
45 | +# it under the terms of the GNU Affero General Public License as |
46 | +# published by the Free Software Foundation, either version 3 of the |
47 | +# License, or (at your option) any later version. |
48 | +# |
49 | +# This program is distributed in the hope that it will be useful, |
50 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
51 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
52 | +# GNU Affero General Public License for more details. |
53 | +# |
54 | +# You should have received a copy of the GNU Affero General Public License |
55 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
56 | +# |
57 | +############################################################################## |
58 | + |
59 | +{ |
60 | + "name" : "Multi Image", |
61 | + "version" : "1.0", |
62 | + "author" : "Serpent Consulting Services Pvt. Ltd.", |
63 | + "category": 'Image', |
64 | + 'complexity': "easy", |
65 | + 'depends': ['web'], |
66 | + "description": """ |
67 | + This module provides the functionality to store multiple images for one record. |
68 | + All images store in server directory. so database size doesnot increase. |
69 | + """, |
70 | + 'update_xml': [ |
71 | + ], |
72 | + 'js':[ |
73 | + "static/lib/lightbox/js/jquery.lightbox.js", |
74 | + "static/src/js/multi_image.js" |
75 | + ], |
76 | + 'css':[ |
77 | + "static/src/css/hoverbox.css", |
78 | + "static/lib/lightbox/css/lightbox.css", |
79 | + ], |
80 | + 'website': 'http://www.serpentcs.com', |
81 | + 'qweb': ['static/src/xml/image_multi.xml'], |
82 | + 'installable': True, |
83 | + 'auto_install': False, |
84 | +} |
85 | + |
86 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
87 | |
88 | === added directory 'multi_image/controllers' |
89 | === added file 'multi_image/controllers/__init__.py' |
90 | --- multi_image/controllers/__init__.py 1970-01-01 00:00:00 +0000 |
91 | +++ multi_image/controllers/__init__.py 2013-09-11 08:32:35 +0000 |
92 | @@ -0,0 +1,25 @@ |
93 | +# -*- coding: utf-8 -*- |
94 | +############################################################################## |
95 | +# |
96 | +# OpenERP, Open Source Management Solution |
97 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
98 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
99 | +# |
100 | +# This program is free software: you can redistribute it and/or modify |
101 | +# it under the terms of the GNU Affero General Public License as |
102 | +# published by the Free Software Foundation, either version 3 of the |
103 | +# License, or (at your option) any later version. |
104 | +# |
105 | +# This program is distributed in the hope that it will be useful, |
106 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
107 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
108 | +# GNU Affero General Public License for more details. |
109 | +# |
110 | +# You should have received a copy of the GNU Affero General Public License |
111 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
112 | +# |
113 | +############################################################################## |
114 | + |
115 | +from . import main |
116 | + |
117 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
118 | \ No newline at end of file |
119 | |
120 | === added file 'multi_image/controllers/main.py' |
121 | --- multi_image/controllers/main.py 1970-01-01 00:00:00 +0000 |
122 | +++ multi_image/controllers/main.py 2013-09-11 08:32:35 +0000 |
123 | @@ -0,0 +1,61 @@ |
124 | +# -*- coding: utf-8 -*- |
125 | +############################################################################## |
126 | +# |
127 | +# OpenERP, Open Source Management Solution |
128 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
129 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
130 | +# |
131 | +# This program is free software: you can redistribute it and/or modify |
132 | +# it under the terms of the GNU Affero General Public License as |
133 | +# published by the Free Software Foundation, either version 3 of the |
134 | +# License, or (at your option) any later version. |
135 | +# |
136 | +# This program is distributed in the hope that it will be useful, |
137 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
138 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
139 | +# GNU Affero General Public License for more details. |
140 | +# |
141 | +# You should have received a copy of the GNU Affero General Public License |
142 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
143 | +# |
144 | +############################################################################## |
145 | + |
146 | +from web import http |
147 | +from openerp.addons.web.controllers.main import Binary |
148 | +openerpweb = http |
149 | +import simplejson |
150 | +import time |
151 | +import openerp |
152 | +import os |
153 | +import StringIO |
154 | + |
155 | +class Binary_multi(Binary): |
156 | + |
157 | + @openerpweb.httprequest |
158 | + def upload_image_multi(self, req, callback, ufile): |
159 | + # TODO: might be useful to have a configuration flag for max-length file uploads |
160 | + out = """<script language="javascript" type="text/javascript"> |
161 | + var win = window.top.window; |
162 | + win.jQuery(win).trigger(%s, %s); |
163 | + </script>""" |
164 | + data = ufile.read() |
165 | + if data: |
166 | + current_dat_time = time.strftime("%d%m%y%H%M%S") |
167 | + file_name = current_dat_time + "_" + ufile.filename |
168 | + addons_path = openerpweb.addons_manifest['web']['addons_path'] + "/web/static/src/img/image_multi/" |
169 | + if not os.path.isdir(addons_path): |
170 | + os.mkdir(addons_path) |
171 | + addons_path += file_name |
172 | + buff = StringIO.StringIO() |
173 | + buff.write(data) |
174 | + buff.seek(0) |
175 | + file_name = "/web/static/src/img/image_multi/" + file_name |
176 | + file = open(addons_path, 'wb') |
177 | + file.write(buff.read()) |
178 | + file.close() |
179 | + args = [len(data), file_name, ufile.content_type, ufile.filename, time.strftime("%m/%d/%Y %H:%M:%S")] |
180 | + else: |
181 | + args = [] |
182 | + return out % (simplejson.dumps(callback), simplejson.dumps(args)) |
183 | + |
184 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
185 | \ No newline at end of file |
186 | |
187 | === added directory 'multi_image/static' |
188 | === added directory 'multi_image/static/lib' |
189 | === added directory 'multi_image/static/lib/lightbox' |
190 | === added directory 'multi_image/static/lib/lightbox/css' |
191 | === added file 'multi_image/static/lib/lightbox/css/lightbox.css' |
192 | --- multi_image/static/lib/lightbox/css/lightbox.css 1970-01-01 00:00:00 +0000 |
193 | +++ multi_image/static/lib/lightbox/css/lightbox.css 2013-09-11 08:32:35 +0000 |
194 | @@ -0,0 +1,128 @@ |
195 | +#lightbox{ |
196 | + position: absolute; |
197 | + left: 0; |
198 | + width: 100%; |
199 | + z-index: 100; |
200 | + text-align: center; |
201 | + line-height: 0; |
202 | + } |
203 | + |
204 | +#lightbox a img{ border: none; } |
205 | + |
206 | +#outerImageContainer{ |
207 | + position: relative; |
208 | + background-color: #fff; |
209 | + width: 250px; |
210 | + height: 250px; |
211 | + margin: 0 auto; |
212 | + } |
213 | + |
214 | +#imageContainer{ |
215 | + padding: 10px; |
216 | + } |
217 | + |
218 | +#loading{ |
219 | + position: absolute; |
220 | + top: 40%; |
221 | + left: 0%; |
222 | + height: 25%; |
223 | + width: 100%; |
224 | + text-align: center; |
225 | + line-height: 0; |
226 | + } |
227 | +#hoverNav{ |
228 | + position: absolute; |
229 | + top: 0; |
230 | + left: 0; |
231 | + height: 100%; |
232 | + width: 100%; |
233 | + z-index: 10; |
234 | + } |
235 | +#imageContainer>#hoverNav{ left: 0;} |
236 | +#hoverNav a{ outline: none;} |
237 | + |
238 | +#prevLink, #nextLink{ |
239 | + width: 49%; |
240 | + height: 100%; |
241 | + background: transparent url(../images/blank.gif) no-repeat; /* Trick IE into showing hover */ |
242 | + display: block; |
243 | + } |
244 | +#prevLink { left: 0; float: left;} |
245 | +#nextLink { right: 0; float: right;} |
246 | +#prevLink:hover, #prevLink:visited:hover { background: url(../images/prev.gif) left 50% no-repeat; } |
247 | +#nextLink:hover, #nextLink:visited:hover { background: url(../images/next.gif) right 50% no-repeat; } |
248 | +/*** START : next / previous text links ***/ |
249 | +nextLinkText, #prevLinkText{ |
250 | +color: #FF9834; |
251 | +font-weight:bold; |
252 | +text-decoration: none; |
253 | +} |
254 | +#nextLinkText{ |
255 | +padding-left: 20px; |
256 | +} |
257 | +#prevLinkText{ |
258 | +padding-right: 20px; |
259 | +} |
260 | +/*** END : next / previous text links ***/ |
261 | +/*** START : added padding when navbar is on top ***/ |
262 | + |
263 | +.ontop #imageData { |
264 | + padding-top: 5px; |
265 | +} |
266 | + |
267 | +/*** END : added padding when navbar is on top ***/ |
268 | + |
269 | +#imageDataContainer{ |
270 | + font: 10px Verdana, Helvetica, sans-serif; |
271 | + background-color: #fff; |
272 | + margin: 0 auto; |
273 | + line-height: 1.4em; |
274 | + } |
275 | + |
276 | +#imageData{ |
277 | + padding:0 10px; |
278 | + } |
279 | +#imageData #imageDetails{ width: 70%; float: left; text-align: left; } |
280 | +#imageData #caption{ font-weight: bold; } |
281 | +#imageData #numberDisplay{ display: block; clear: left; padding-bottom: 1.0em; } |
282 | +#imageData #numberDisplay a { color: black; padding-left: 5px; padding-right: 5px;} |
283 | +#imageData #bottomNavClose{float: right; padding-bottom: 0.7em; } |
284 | +#imageData #helpDisplay {clear: left; float: left; display: block; } |
285 | + |
286 | +#overlay{ |
287 | + position: absolute; |
288 | + top: 0; |
289 | + left: 0; |
290 | + z-index: 90; |
291 | + width: 100%; |
292 | + height: 500px; |
293 | + background-color: #000; |
294 | + filter:alpha(opacity=60); |
295 | + -moz-opacity: 0.6; |
296 | + opacity: 0.6 !important; |
297 | + display: none; |
298 | + } |
299 | + |
300 | + |
301 | +.clearfix:after { |
302 | + content: "."; |
303 | + display: block; |
304 | + height: 0; |
305 | + clear: both; |
306 | + visibility: hidden; |
307 | + } |
308 | + |
309 | +* html>body .clearfix { |
310 | + display: inline-block; |
311 | + width: 100%; |
312 | + } |
313 | + |
314 | +* html .clearfix { |
315 | + /* Hides from IE-mac \*/ |
316 | + height: 1%; |
317 | + /* End hide from IE-mac */ |
318 | + } |
319 | + |
320 | +#lightboxIframe { |
321 | + display: none; |
322 | +} |
323 | |
324 | === added directory 'multi_image/static/lib/lightbox/images' |
325 | === added file 'multi_image/static/lib/lightbox/images/blank.gif' |
326 | Binary files multi_image/static/lib/lightbox/images/blank.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/blank.gif 2013-09-11 08:32:35 +0000 differ |
327 | === added file 'multi_image/static/lib/lightbox/images/close.gif' |
328 | Binary files multi_image/static/lib/lightbox/images/close.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/close.gif 2013-09-11 08:32:35 +0000 differ |
329 | === added file 'multi_image/static/lib/lightbox/images/closelabel.gif' |
330 | Binary files multi_image/static/lib/lightbox/images/closelabel.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/closelabel.gif 2013-09-11 08:32:35 +0000 differ |
331 | === added file 'multi_image/static/lib/lightbox/images/loading.gif' |
332 | Binary files multi_image/static/lib/lightbox/images/loading.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/loading.gif 2013-09-11 08:32:35 +0000 differ |
333 | === added file 'multi_image/static/lib/lightbox/images/next.gif' |
334 | Binary files multi_image/static/lib/lightbox/images/next.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/next.gif 2013-09-11 08:32:35 +0000 differ |
335 | === added file 'multi_image/static/lib/lightbox/images/nextlabel.gif' |
336 | Binary files multi_image/static/lib/lightbox/images/nextlabel.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/nextlabel.gif 2013-09-11 08:32:35 +0000 differ |
337 | === added file 'multi_image/static/lib/lightbox/images/prev.gif' |
338 | Binary files multi_image/static/lib/lightbox/images/prev.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/prev.gif 2013-09-11 08:32:35 +0000 differ |
339 | === added file 'multi_image/static/lib/lightbox/images/prevlabel.gif' |
340 | Binary files multi_image/static/lib/lightbox/images/prevlabel.gif 1970-01-01 00:00:00 +0000 and multi_image/static/lib/lightbox/images/prevlabel.gif 2013-09-11 08:32:35 +0000 differ |
341 | === added directory 'multi_image/static/lib/lightbox/js' |
342 | === added file 'multi_image/static/lib/lightbox/js/jquery.lightbox.js' |
343 | --- multi_image/static/lib/lightbox/js/jquery.lightbox.js 1970-01-01 00:00:00 +0000 |
344 | +++ multi_image/static/lib/lightbox/js/jquery.lightbox.js 2013-09-11 08:32:35 +0000 |
345 | @@ -0,0 +1,501 @@ |
346 | +/** |
347 | + * jQuery Lightbox |
348 | + * @author Warren Krewenki |
349 | + * |
350 | + * This package is distributed under the BSD license. |
351 | + * For full license information, see LICENSE.TXT |
352 | + * |
353 | + * Based on Lightbox 2 by Lokesh Dhakar (http://www.huddletogether.com/projects/lightbox2/) |
354 | + * |
355 | + * |
356 | + **/ |
357 | + |
358 | +(function($) { |
359 | + $.fn.lightbox = function(options) { |
360 | + // build main options |
361 | + var opts = $.extend({}, $.fn.lightbox.defaults, options); |
362 | + |
363 | + $(window).resize(resizeOverlayToFitWindow); |
364 | + |
365 | + initialize(); |
366 | + showLightbox(this); |
367 | + /* |
368 | + # Initialize the lightbox by creating our html and reading some image data |
369 | + # This method is called by the constructor after any click events trigger it |
370 | + # You will never call it by itself, to my knowledge. |
371 | + */ |
372 | + function initialize() { |
373 | + $('#overlay, #lightbox').remove(); |
374 | + opts.inprogress = false; |
375 | + |
376 | + // if jsonData, build the imageArray from data provided in JSON format |
377 | + if (opts.jsonData && opts.jsonData.length > 0) { |
378 | + var parser = opts.jsonDataParser ? opts.jsonDataParser : $.fn.lightbox.parseJsonData; |
379 | + opts.imageArray = []; |
380 | + opts.imageArray = parser(opts.jsonData); |
381 | + } |
382 | + |
383 | + var outerImage = '<div id="outerImageContainer"><div id="imageContainer" style="height: 520px; width: 720px;"><iframe id="lightboxIframe"></iframe><img id="lightboxImage" /><div id="hoverNav"><a href="javascript://" title="' + opts.strings.prevLinkTitle + '" id="prevLink"></a><a href="javascript://" id="nextLink" title="' + opts.strings.nextLinkTitle + '"></a></div><div id="loading"><a href="javascript://" id="loadingLink"><img src="'+opts.fileLoadingImage+'"></a></div></div></div>'; |
384 | + var imageData = '<div id="imageDataContainer" class="clearfix"><div id="imageData"><div id="imageDetails"><span id="caption"></span><span id="numberDisplay"></span></div><div id="bottomNav">'; |
385 | + |
386 | +// var outerImage = '<div id="outerImageContainer"><div id="imageContainer" style="height: 520px; width: 720px;"><iframe id="lightboxIframe"></iframe><img id="lightboxImage" syle="vertical-align: middle;" /><div id="hoverNav"><a href="javascript://" title="' + opts.strings.prevLinkTitle + '" id="prevLink"></a><a href="javascript://" id="nextLink" title="' + opts.strings.nextLinkTitle + '"></a></div><div id="loading"><a href="javascript://" id="loadingLink"><img src="'+opts.fileLoadingImage+'"></a></div></div></div>'; |
387 | +// var imageData = '<div id="imageDataContainer" class="clearfix"><div id="imageData"><div id="imageDetails"><span id="caption"></span><span id="numberDisplay"></span></div><div id="bottomNav">'; |
388 | + |
389 | + if (opts.displayHelp) { |
390 | + imageData += '<span id="helpDisplay">' + opts.strings.help + '</span>'; |
391 | + } |
392 | + |
393 | + imageData += '<a href="javascript://" id="bottomNavClose" class="ui-dialog-titlebar-close ui-corner-all ui-state-hover" title="' + opts.strings.closeTitle + '"><span class="ui-icon ui-icon-closethick">close</span></a></div></div></div>'; |
394 | + |
395 | + var string; |
396 | + |
397 | + if (opts.navbarOnTop) { |
398 | + string = '<div id="overlay"></div><div id="lightbox">' + imageData + outerImage + '</div>'; |
399 | + $("body").append(string); |
400 | + $("#imageDataContainer").addClass('ontop'); |
401 | + } else { |
402 | + string = '<div id="overlay"></div><div id="lightbox">' + outerImage + imageData + '</div>'; |
403 | + $("body").append(string); |
404 | + } |
405 | + |
406 | + //$("#overlay, #lightbox").click(function(){ end(); }).hide(); |
407 | + $("#loadingLink, #bottomNavClose").click(function(){ end(); return false;}); |
408 | + $('#outerImageContainer').width(opts.widthCurrent).height(opts.heightCurrent); |
409 | + $('#imageDataContainer').width(opts.widthCurrent); |
410 | + |
411 | + if (!opts.imageClickClose) { |
412 | + $("#lightboxImage").click(function(){ return false; }); |
413 | + $("#hoverNav").click(function(){ return false; }); |
414 | + } |
415 | + |
416 | + return true; |
417 | + }; |
418 | + |
419 | + /* |
420 | + # Get the document and window width/heigh |
421 | + # |
422 | + # Examples |
423 | + # |
424 | + # getPageSize() |
425 | + # # => [1024,768,1024,768] |
426 | + # |
427 | + # Returns a numerically indexed array of document width/height and window width/height |
428 | + */ |
429 | + function getPageSize() { |
430 | + var jqueryPageSize = new Array($(document).width(),$(document).height(), $(window).width(), $(window).height()); |
431 | + return jqueryPageSize; |
432 | + }; |
433 | + |
434 | + function getPageScroll() { |
435 | + var xScroll, yScroll; |
436 | + |
437 | + if (self.pageYOffset) { |
438 | + yScroll = self.pageYOffset; |
439 | + xScroll = self.pageXOffset; |
440 | + } else if (document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict |
441 | + yScroll = document.documentElement.scrollTop; |
442 | + xScroll = document.documentElement.scrollLeft; |
443 | + } else if (document.body) {// all other Explorers |
444 | + yScroll = document.body.scrollTop; |
445 | + xScroll = document.body.scrollLeft; |
446 | + } |
447 | + |
448 | + var arrayPageScroll = new Array(xScroll,yScroll); |
449 | + return arrayPageScroll; |
450 | + }; |
451 | + |
452 | + /* |
453 | + # Deploy the sexy overlay and display the lightbox |
454 | + # |
455 | + # imageObject - the jQuery object passed via the click event in the constructor |
456 | + # |
457 | + # Examples |
458 | + # |
459 | + # showLightbox($('#CheesusCrust')) |
460 | + # |
461 | + # Returns a boolean true, because it's got nothing else to return. It should give visual feedback when run |
462 | + */ |
463 | + function showLightbox(imageObject) { |
464 | + /** |
465 | + * select, embed and object tags render over the lightbox in some browsers |
466 | + * Right now, the best way to fix it is to hide them, but that can trigger reloading of some flash content |
467 | + * I don't have a better fix for this right now, but I want ot leave this comment here so you and I both |
468 | + * know that i'm aware of it, and I would love to fix it, if you have any suggestions. |
469 | + **/ |
470 | + $("select, embed, object").hide(); |
471 | + |
472 | + // Resize and display the sexy, sexy overlay. |
473 | + resizeOverlayToFitWindow(); |
474 | + $("#overlay").hide().css({ opacity : opts.overlayOpacity }).fadeIn(); |
475 | + imageNum = 0; |
476 | + |
477 | + // if data is not provided by jsonData parameter |
478 | + if (!opts.jsonData) { |
479 | + opts.imageArray = []; |
480 | + // if image is NOT part of a set.. |
481 | + if ((!imageObject.rel || (imageObject.rel == '')) && !opts.allSet) { |
482 | + // add single image to Lightbox.imageArray |
483 | + opts.imageArray.push(new Array(imageObject.href, opts.displayTitle ? imageObject.title : '')); |
484 | + } else { |
485 | + // if image is part of a set.. |
486 | + $("a").each(function() { |
487 | + if(this.href && (this.rel == imageObject.rel)) { |
488 | + opts.imageArray.push(new Array(this.href, opts.displayTitle ? this.title : '')); |
489 | + } |
490 | + }); |
491 | + } |
492 | + } |
493 | + |
494 | + if (opts.imageArray.length > 1) { |
495 | + for (i = 0; i < opts.imageArray.length; i++) { |
496 | + for (j = opts.imageArray.length - 1; j > i; j--) { |
497 | + if (opts.imageArray[i][0] == opts.imageArray[j][0]) { |
498 | + opts.imageArray.splice(j, 1); |
499 | + } |
500 | + } |
501 | + } |
502 | + while (opts.imageArray[imageNum][0] != imageObject.href) { |
503 | + imageNum++; |
504 | + if (imageNum < opts.imageArray.length) { |
505 | + break; |
506 | + } |
507 | + } |
508 | + } |
509 | + |
510 | + // calculate top and left offset for the lightbox |
511 | + var arrayPageScroll = getPageScroll(); |
512 | + var lightboxTop = arrayPageScroll[1] + ($(window).height() / 10); |
513 | + var lightboxLeft = arrayPageScroll[0]; |
514 | + $('#lightbox').css({top: lightboxTop+'px', left: lightboxLeft+'px'}).show(); |
515 | + |
516 | + if (!opts.slideNavBar) { |
517 | + $('#imageData').hide(); |
518 | + } |
519 | + |
520 | + changeImage(imageNum); |
521 | + }; |
522 | + |
523 | + function changeImage(imageNum) { |
524 | + if (opts.inprogress == false) { |
525 | + opts.inprogress = true; |
526 | + |
527 | + // update global var |
528 | + opts.activeImage = imageNum; |
529 | + |
530 | + // hide elements during transition |
531 | + $('#loading').show(); |
532 | + $('#lightboxImage, #hoverNav, #prevLink, #nextLink').hide(); |
533 | + |
534 | + // delay preloading image until navbar will slide up |
535 | + if (opts.slideNavBar) { |
536 | + $('#imageDataContainer').hide(); |
537 | + $('#imageData').hide(); |
538 | + } |
539 | + doChangeImage(); |
540 | + } |
541 | + }; |
542 | + |
543 | + function doChangeImage() { |
544 | + imgPreloader = new Image(); |
545 | + |
546 | + // once image is preloaded, resize image container |
547 | + imgPreloader.onload = function() { |
548 | + var newWidth = imgPreloader.width; |
549 | + var newHeight = imgPreloader.height; |
550 | + |
551 | + if (opts.scaleImages) { |
552 | + newWidth = parseInt(opts.xScale * newWidth); |
553 | + newHeight = parseInt(opts.yScale * newHeight); |
554 | + } |
555 | + |
556 | + if (opts.fitToScreen) { |
557 | + var arrayPageSize = getPageSize(); |
558 | + var ratio; |
559 | + var initialPageWidth = arrayPageSize[2] - 2 * opts.borderSize; |
560 | + var initialPageHeight = arrayPageSize[3] - 200; |
561 | + |
562 | + var dI = initialPageWidth/initialPageHeight; |
563 | + var dP = imgPreloader.width/imgPreloader.height; |
564 | + |
565 | + if ((imgPreloader.height > initialPageHeight) || (imgPreloader.width > initialPageWidth)) { |
566 | + if (dI > dP) { |
567 | + newWidth = parseInt((initialPageHeight/imgPreloader.height) * imgPreloader.width); |
568 | + newHeight = initialPageHeight; |
569 | + } else { |
570 | + newHeight = parseInt((initialPageWidth/imgPreloader.width) * imgPreloader.height); |
571 | + newWidth = initialPageWidth; |
572 | + } |
573 | + } |
574 | + } |
575 | + if (newWidth > 700) { |
576 | + newWidth = 700 |
577 | + } |
578 | + if (newHeight > 500) { |
579 | + newHeight = 500 |
580 | + } |
581 | + var line_height = (newHeight / 100) * 7 + 24 |
582 | + $("#imageContainer").attr("style", "line-height:" + line_height) |
583 | + $("#lightboxImage").attr("style", "line-height:" + line_height) |
584 | + $('#lightboxImage'). |
585 | + attr('src', opts.imageArray[opts.activeImage][0]). |
586 | + width(newWidth). |
587 | + height(newHeight); |
588 | + |
589 | + resizeImageContainer(newWidth, newHeight); |
590 | + }; |
591 | + |
592 | + imgPreloader.src = opts.imageArray[opts.activeImage][0]; |
593 | + }; |
594 | + |
595 | + function end() { |
596 | + $('#overlay, #lightbox, #outerImageContainer, #imageDataContainer').remove(); |
597 | + }; |
598 | + |
599 | + function preloadNeighborImages() { |
600 | + if (opts.loopImages && opts.imageArray.length > 1) { |
601 | + preloadNextImage = new Image(); |
602 | + preloadNextImage.src = opts.imageArray[(opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1][0]; |
603 | + |
604 | + preloadPrevImage = new Image(); |
605 | + preloadPrevImage.src = opts.imageArray[(opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1][0]; |
606 | + } else { |
607 | + if ((opts.imageArray.length - 1) > opts.activeImage) { |
608 | + preloadNextImage = new Image(); |
609 | + preloadNextImage.src = opts.imageArray[opts.activeImage + 1][0]; |
610 | + } |
611 | + if (opts.activeImage > 0) { |
612 | + preloadPrevImage = new Image(); |
613 | + preloadPrevImage.src = opts.imageArray[opts.activeImage - 1][0]; |
614 | + } |
615 | + } |
616 | + }; |
617 | + |
618 | + function resizeImageContainer(imgWidth, imgHeight) { |
619 | + // get current width and height |
620 | + opts.widthCurrent = $("#outerImageContainer").outerWidth(); |
621 | + opts.heightCurrent = $("#outerImageContainer").outerHeight(); |
622 | + |
623 | + // get new width and height |
624 | + var widthNew = 730; |
625 | + var heightNew = 520; |
626 | + |
627 | + // calculate size difference between new and old image, and resize if necessary |
628 | + wDiff = opts.widthCurrent - widthNew; |
629 | + hDiff = opts.heightCurrent - heightNew; |
630 | + |
631 | + $('#imageDataContainer').animate({width: widthNew},opts.resizeSpeed,'linear'); |
632 | + $('#outerImageContainer').animate({width: widthNew},opts.resizeSpeed,'linear', function() { |
633 | + $('#outerImageContainer').animate({height: heightNew},opts.resizeSpeed,'linear', function() { |
634 | + showImage(); |
635 | + }); |
636 | + }); |
637 | + |
638 | + afterTimeout = function () { |
639 | + $('#prevLink').height(500); |
640 | + $('#nextLink').height(500); |
641 | + }; |
642 | + |
643 | + // if new and old image are same size and no scaling transition is necessary, |
644 | + // do a quick pause to prevent image flicker. |
645 | + if((hDiff == 0) && (wDiff == 0)) { |
646 | + if (jQuery.browser.msie) { |
647 | + setTimeout(afterTimeout, 250); |
648 | + } else { |
649 | + setTimeout(afterTimeout, 100); |
650 | + } |
651 | + } else { |
652 | + // otherwise just trigger the height and width change |
653 | + afterTimeout(); |
654 | + } |
655 | + |
656 | + }; |
657 | + |
658 | + function showImage() { |
659 | + $('#loading').hide(); |
660 | + $('#lightboxImage').fadeIn("fast"); |
661 | + updateDetails(); |
662 | + preloadNeighborImages(); |
663 | + |
664 | + opts.inprogress = false; |
665 | + }; |
666 | + |
667 | + function updateDetails() { |
668 | + $('#numberDisplay').html(''); |
669 | + |
670 | + if (opts.imageArray[opts.activeImage][1]) { |
671 | + $('#caption').html(opts.imageArray[opts.activeImage][1]).show(); |
672 | + } |
673 | + |
674 | + // if image is part of set display 'Image x of x' |
675 | + if (opts.imageArray.length > 1) { |
676 | + var nav_html; |
677 | + |
678 | + nav_html = opts.strings.image + (opts.activeImage + 1) + opts.strings.of + opts.imageArray.length; |
679 | + |
680 | + if (opts.displayDownloadLink) { |
681 | + nav_html += "<a href='" + opts.imageArray[opts.activeImage][0] + "'>" + opts.strings.download + "</a>"; |
682 | + } |
683 | + |
684 | + if (!opts.disableNavbarLinks) { |
685 | + // display previous / next text links |
686 | + if ((opts.activeImage) > 0 || opts.loopImages) { |
687 | + nav_html = '<a title="' + opts.strings.prevLinkTitle + '" href="#" id="prevLinkText">' + opts.strings.prevLinkText + "</a>" + nav_html; |
688 | + } |
689 | + |
690 | + if (((opts.activeImage + 1) < opts.imageArray.length) || opts.loopImages) { |
691 | + nav_html += '<a title="' + opts.strings.nextLinkTitle + '" href="#" id="nextLinkText">' + opts.strings.nextLinkText + "</a>"; |
692 | + } |
693 | + } |
694 | + |
695 | + $('#numberDisplay').html(nav_html).show(); |
696 | + } |
697 | + |
698 | + if (opts.slideNavBar) { |
699 | + $("#imageData").slideDown(opts.navBarSlideSpeed); |
700 | + } else { |
701 | + $("#imageData").show(); |
702 | + } |
703 | + |
704 | + resizeOverlayToFitWindow(); |
705 | + updateNav(); |
706 | + }; |
707 | + |
708 | + /* |
709 | + # Resize the sexy overlay to fit the constraints of your current viewing environment |
710 | + # |
711 | + # This should now happen whenever a window is resized, so you should always see a full overlay |
712 | + */ |
713 | + function resizeOverlayToFitWindow(){ |
714 | + $('#overlay').css({width: $(document).width(), height: $(document).height()}); |
715 | + // ^^^^^^^ <- sexy! |
716 | + }; |
717 | + |
718 | + function updateNav() { |
719 | + if (opts.imageArray.length > 1) { |
720 | + $('#hoverNav').show(); |
721 | + |
722 | + // if loopImages is true, always show next and prev image buttons |
723 | + if(opts.loopImages) { |
724 | + $('#prevLink,#prevLinkText').show().click(function() { |
725 | + changeImage((opts.activeImage == 0) ? (opts.imageArray.length - 1) : opts.activeImage - 1); |
726 | + return false; |
727 | + }); |
728 | + |
729 | + $('#nextLink,#nextLinkText').show().click(function() { |
730 | + changeImage((opts.activeImage == (opts.imageArray.length - 1)) ? 0 : opts.activeImage + 1); |
731 | + return false; |
732 | + }); |
733 | + } else { |
734 | + // if not first image in set, display prev image button |
735 | + if(opts.activeImage != 0) { |
736 | + $('#prevLink,#prevLinkText').show().click(function() { |
737 | + changeImage(opts.activeImage - 1); |
738 | + return false; |
739 | + }); |
740 | + } |
741 | + |
742 | + // if not last image in set, display next image button |
743 | + if(opts.activeImage != (opts.imageArray.length - 1)) { |
744 | + $('#nextLink,#nextLinkText').show().click(function() { |
745 | + changeImage(opts.activeImage +1); |
746 | + return false; |
747 | + }); |
748 | + } |
749 | + } |
750 | + |
751 | + enableKeyboardNav(); |
752 | + } |
753 | + }; |
754 | + |
755 | + function keyboardAction(e) { |
756 | + var o = e.data.opts; |
757 | + var keycode = e.keyCode; |
758 | + var escapeKey = 27; |
759 | + |
760 | + var key = String.fromCharCode(keycode).toLowerCase(); |
761 | + |
762 | + // close lightbox |
763 | + if ((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)) { |
764 | + end(); |
765 | + |
766 | + // display previous image |
767 | + } else if ((key == 'p') || (keycode == 37)) { |
768 | + if(o.loopImages) { |
769 | + disableKeyboardNav(); |
770 | + changeImage((o.activeImage == 0) ? (o.imageArray.length - 1) : o.activeImage - 1); |
771 | + } else if (o.activeImage != 0) { |
772 | + disableKeyboardNav(); |
773 | + changeImage(o.activeImage - 1); |
774 | + } |
775 | + |
776 | + // display next image |
777 | + } else if ((key == 'n') || (keycode == 39)) { |
778 | + if (opts.loopImages) { |
779 | + disableKeyboardNav(); |
780 | + changeImage((o.activeImage == (o.imageArray.length - 1)) ? 0 : o.activeImage + 1); |
781 | + } else if (o.activeImage != (o.imageArray.length - 1)) { |
782 | + disableKeyboardNav(); |
783 | + changeImage(o.activeImage + 1); |
784 | + } |
785 | + } |
786 | + }; |
787 | + |
788 | + function enableKeyboardNav() { |
789 | + $(document).bind('keydown', {opts: opts}, keyboardAction); |
790 | + }; |
791 | + |
792 | + function disableKeyboardNav() { |
793 | + $(document).unbind('keydown'); |
794 | + }; |
795 | + }; |
796 | + |
797 | + $.fn.lightbox.parseJsonData = function(data) { |
798 | + var imageArray = []; |
799 | + |
800 | + $.each(data, function() { |
801 | + imageArray.push(new Array(this.url, this.title)); |
802 | + }); |
803 | + |
804 | + return imageArray; |
805 | + }; |
806 | + $.fn.lightbox.defaults = { |
807 | + triggerEvent: "click", |
808 | + allSet: false, |
809 | + fileLoadingImage: '/multi_image/static/lib/lightbox/images/loading.gif', |
810 | + fileBottomNavCloseImage: '/multi_image/static/lib/lightbox/images/closelabel.gif', |
811 | + overlayOpacity: 0.6, |
812 | + borderSize: 10, |
813 | + imageArray: new Array, |
814 | + activeImage: null, |
815 | + inprogress: false, |
816 | + resizeSpeed: 350, |
817 | + widthCurrent: 250, |
818 | + heightCurrent: 250, |
819 | + scaleImages: false, |
820 | + xScale: 1, |
821 | + yScale: 1, |
822 | + displayTitle: true, |
823 | + navbarOnTop: true, |
824 | + displayDownloadLink: false, |
825 | + slideNavBar: false, |
826 | + navBarSlideSpeed: 350, |
827 | + displayHelp: false, |
828 | + strings: { |
829 | + help: ' \u2190 / P - previous image\u00a0\u00a0\u00a0\u00a0\u2192 / N - next image\u00a0\u00a0\u00a0\u00a0ESC / X - close image gallery', |
830 | + prevLinkTitle: 'previous image', |
831 | + nextLinkTitle: 'next image', |
832 | + prevLinkText: '« Previous', |
833 | + nextLinkText: 'Next »', |
834 | + closeTitle: 'close image gallery', |
835 | + image: 'Image ', |
836 | + of: ' of ', |
837 | + download: 'Download' |
838 | + }, |
839 | + fitToScreen: false, |
840 | + disableNavbarLinks: false, |
841 | + loopImages: false, |
842 | + imageClickClose: true, |
843 | + jsonData: null, |
844 | + jsonDataParser: null |
845 | + }; |
846 | +})(jQuery); |
847 | \ No newline at end of file |
848 | |
849 | === added directory 'multi_image/static/src' |
850 | === added directory 'multi_image/static/src/css' |
851 | === added file 'multi_image/static/src/css/hoverbox.css' |
852 | --- multi_image/static/src/css/hoverbox.css 1970-01-01 00:00:00 +0000 |
853 | +++ multi_image/static/src/css/hoverbox.css 2013-09-11 08:32:35 +0000 |
854 | @@ -0,0 +1,52 @@ |
855 | +.hoverbox a .preview |
856 | +{ |
857 | + display: none; |
858 | +} |
859 | + |
860 | +.hoverbox a:active .preview |
861 | +{ |
862 | + display: block; |
863 | + position: absolute; |
864 | + top: 0px; |
865 | + left: 0px; |
866 | + z-index: 1; |
867 | +} |
868 | + |
869 | +.hoverbox .list_image |
870 | +{ |
871 | + background: #fff; |
872 | + border-color: #aaa #ccc #ddd #bbb; |
873 | + border-style: solid; |
874 | + border-width: 1px; |
875 | + color: inherit; |
876 | + padding: 2px; |
877 | + vertical-align: top; |
878 | + width: 150px; |
879 | +} |
880 | + |
881 | +.hoverbox |
882 | +{ |
883 | + background: #eee; |
884 | + border-color: #ddd #bbb #aaa #ccc; |
885 | + border-style: solid; |
886 | + border-width: 1px; |
887 | + color: inherit; |
888 | + margin: 1px; |
889 | + padding: 0px; |
890 | + position: relative; |
891 | +} |
892 | + |
893 | +.hoverbox .preview |
894 | +{ |
895 | + border-color: #000; |
896 | + width: 320px; |
897 | +} |
898 | + |
899 | +.oe-remove-image |
900 | +{ |
901 | + cursor: pointer; |
902 | + vertical-align: middle; |
903 | + text-align: right; |
904 | + height: 15px; |
905 | + width: 15px; |
906 | +} |
907 | \ No newline at end of file |
908 | |
909 | === added directory 'multi_image/static/src/img' |
910 | === added file 'multi_image/static/src/img/icon.png' |
911 | Binary files multi_image/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and multi_image/static/src/img/icon.png 2013-09-11 08:32:35 +0000 differ |
912 | === added directory 'multi_image/static/src/js' |
913 | === added file 'multi_image/static/src/js/multi_image.js' |
914 | --- multi_image/static/src/js/multi_image.js 1970-01-01 00:00:00 +0000 |
915 | +++ multi_image/static/src/js/multi_image.js 2013-09-11 08:32:35 +0000 |
916 | @@ -0,0 +1,227 @@ |
917 | +openerp.multi_image = function(openerp) { |
918 | + var _t = openerp.web._t; |
919 | + var QWeb = openerp.web.qweb; |
920 | +openerp.web.form.FieldBinaryImageMulti = openerp.web.form.FieldBinaryImage.extend({ |
921 | + template: 'FieldBinaryImageMulti', |
922 | + init: function(field_manager, node) { |
923 | + var self = this; |
924 | + this._super(field_manager, node); |
925 | + this.binary_value = false; |
926 | + this.useFileAPI = !window.FileReader; |
927 | + this.max_upload_size = 25 * 1024 * 1024; // 25Mo |
928 | + if (!this.useFileAPI) { |
929 | + this.fileupload_id = _.uniqueId('oe_fileupload'); |
930 | + $(window).on(this.fileupload_id, function() { |
931 | + var args = [].slice.call(arguments).slice(1); |
932 | + self.on_file_uploaded.apply(self, args); |
933 | + }); |
934 | + } |
935 | + }, |
936 | + initialize_content: function() { |
937 | + var self = this; |
938 | + var dataset = new openerp.web.DataSetSearch(this, 'res.users', {}, []); |
939 | + dataset.read_ids([openerp.session.uid], ['name']).then(function(res) { |
940 | + if (res) |
941 | + self.user_name = res[0].name; |
942 | + }); |
943 | + this._super(); |
944 | + }, |
945 | + on_file_uploaded_and_valid: function(size, name, content_type, orignal_file_name, date) { |
946 | + if (name) { |
947 | + var data_dict = {"size": openerp.web.human_size(size), "name": name, "content_type": content_type, "date": date, "orignal_name": orignal_file_name, 'user':this.user_name}; |
948 | + var data = JSON.parse(this.get('value')); |
949 | + if (data) |
950 | + data.push(data_dict); |
951 | + else |
952 | + data = [data_dict]; |
953 | + this.internal_set_value(JSON.stringify(data)); |
954 | + this.binary_value = true; |
955 | + this.set_filename(name); |
956 | + this.render_value(); |
957 | + this.do_warn(_t("File Upload"), _t("File Upload Successfully !")); |
958 | + } |
959 | + else{ |
960 | + this.do_warn(_t("File Upload"), _t("There was a problem while uploading your file")); |
961 | + } |
962 | + }, |
963 | + on_list_image: function() { |
964 | + var images_list = this.get('value'); |
965 | + var self = this; |
966 | + if (!this.get('value')) { |
967 | + this.do_warn(_t("Image"), _t("Image not available !")); |
968 | + return false; |
969 | + } |
970 | + this.image_list_dialog = new openerp.web.Dialog(this, { |
971 | + title: _t("Image List"), |
972 | + width: '700px', |
973 | + height: '70%', |
974 | + min_width: '600px', |
975 | + min_height: '500px', |
976 | + buttons: [ |
977 | + {text: _t("Close"), click: function() { self.image_list_dialog.close();}} |
978 | + ] |
979 | + }).open(); |
980 | + this.on_render_dialog(); |
981 | + }, |
982 | + on_render_dialog: function() { |
983 | + var images_list = JSON.parse(this.get('value')); |
984 | + var self = this; |
985 | + var url_list = []; |
986 | + if (images_list) { |
987 | + _.each(images_list, function (index) { |
988 | + if (index) { |
989 | + if(index['name_1']){ |
990 | + url_list.push({'name' : index['name_1'], 'path' : index['name']}) |
991 | + }else{ |
992 | + url_list.push({'name' : index['orignal_name'], 'path' : index['name']}) |
993 | + } |
994 | + } |
995 | + }); |
996 | + } |
997 | + else { return false; } |
998 | + var image_list = []; |
999 | + var start = 0; |
1000 | + for(var i=1; i <= Math.ceil(url_list.length/4); i++) { |
1001 | + image_list.push(url_list.slice(start, start + 4)) |
1002 | + start = i * 4; |
1003 | + } |
1004 | + this.image_list_dialog.$el.html(QWeb.render('DialogImageList', {'widget': this, 'image_list': image_list})); |
1005 | + this.image_list_dialog.$el.find(".oe-remove-image").click(function() { |
1006 | + self.do_remove_image(this, true); |
1007 | + }); |
1008 | + }, |
1009 | + |
1010 | + render_value: function() { |
1011 | + var self = this; |
1012 | + this.$el.find('.oe-image-preview').click(this.on_preview_button); |
1013 | + this.$el.find('.oe_image_list').click(this.on_list_image); |
1014 | + var images_list = JSON.parse(this.get('value')); |
1015 | + this.$el.find('#imagedescription').remove(); |
1016 | + var $img = QWeb.render("ImageDescription", { image_list: images_list, widget: this}); |
1017 | + this.$el.append($img); |
1018 | + this.$el.find(".oe_image_row").click(function() { |
1019 | + if (this.id) { |
1020 | + var clicked = this.id; |
1021 | + var name_desc = ""; |
1022 | + _.each(images_list, function (index) { |
1023 | + if (index['name'] == clicked ) { |
1024 | + var title = index['name_1'] ? index['name_1'] : '' |
1025 | + var description = index['description'] ? index['description'] : '' |
1026 | + name_desc = 'Title:-' + title + '<br/>Description:-' +description |
1027 | + } |
1028 | + }); |
1029 | + self.do_display_image(this, name_desc); |
1030 | + } |
1031 | + }); |
1032 | + this.$el.find(".oe_list_record_delete").click(function() { |
1033 | + if (this.id) { |
1034 | + self.do_remove_image(this, false); |
1035 | + } |
1036 | + }); |
1037 | + this.$el.find(".oe-record-edit-link").click(function() { |
1038 | + var self_1 = this; |
1039 | + var data = JSON.parse(self.get('value')); |
1040 | + _.each(data, function(d){ |
1041 | + if(d.name == self_1.id){ |
1042 | + self.name_display = d.name_1 ? d.name_1 : ''; |
1043 | + self.description_display =d.description ? d.description : ''; |
1044 | + } |
1045 | + }); |
1046 | + self.select_mo_dialog = $(QWeb.render('edit_name_description', {widget:self})).dialog({ |
1047 | + resizable: false, |
1048 | + modal: true, |
1049 | + title: _t("Image Description"), |
1050 | + width: 500, |
1051 | + buttons: { |
1052 | + "Ok": function() { |
1053 | + var new_list = []; |
1054 | + var data = JSON.parse(self.get('value')); |
1055 | + if (self_1.id && data) { |
1056 | + _.each(data, function (index) { |
1057 | + if (index['name'] != self_1.id ) { |
1058 | + new_list.push(index) |
1059 | + } |
1060 | + else { |
1061 | + index["name_1"] = self.select_mo_dialog.find('#name_1').val() |
1062 | + index["description"] = self.select_mo_dialog.find('#description').val() |
1063 | + new_list.push(index) |
1064 | + } |
1065 | + }); |
1066 | + self.internal_set_value(JSON.stringify(new_list)); |
1067 | + self.invalid = false |
1068 | + self.dirty = true |
1069 | + self.render_value(); |
1070 | + $(this).dialog( "close" ); |
1071 | + } |
1072 | + }, |
1073 | + "Close": function() { |
1074 | + $(this).dialog( "close" ); |
1075 | + } |
1076 | + }, |
1077 | + }); |
1078 | + }); |
1079 | + }, |
1080 | + do_display_image: function(curr_id, name_desc) { |
1081 | + this.$el.find('.oe-image-preview').lightbox({ |
1082 | + fitToScreen: true, |
1083 | + jsonData: [{"url" :curr_id.id, "title": name_desc}], |
1084 | + loopImages: true, |
1085 | + imageClickClose: false, |
1086 | + disableNavbarLinks: true |
1087 | + }); |
1088 | + }, |
1089 | + do_remove_image: function(curr_id, dialog) { |
1090 | + var self = this; |
1091 | + var images_list = JSON.parse(this.get('value')); |
1092 | + if (images_list) { |
1093 | + var new_list = []; |
1094 | + if (confirm(_t("Are you sure to remove this image?"))) { |
1095 | + _.each(images_list, function (index) { |
1096 | + if (index['name'] != curr_id.id ) { |
1097 | + new_list.push(index) |
1098 | + } |
1099 | + }); |
1100 | + self.internal_set_value(JSON.stringify(new_list)); |
1101 | + this.invalid = false |
1102 | + this.dirty = true |
1103 | + if (dialog) { |
1104 | + this.on_render_dialog(); |
1105 | + } |
1106 | + else{ |
1107 | + this.render_value(); |
1108 | + } |
1109 | + } |
1110 | + } |
1111 | + }, |
1112 | + on_preview_button: function() { |
1113 | + console.log(this.get('value')) |
1114 | + var images_list = JSON.parse(this.get('value')); |
1115 | + var url_list = []; |
1116 | + var self = this; |
1117 | + if (images_list) { |
1118 | + _.each(images_list, function (index) { |
1119 | + if (index) { |
1120 | + var title = index['name_1'] ? index['name_1'] : '' |
1121 | + var description = index['description'] ? index['description'] : '' |
1122 | + url_list.push({"url" :index['name'], "title": 'Title:-' + title + '<br/>Description:-' +description}) |
1123 | + } |
1124 | + }); |
1125 | + } |
1126 | + else { |
1127 | + this.do_warn("Image", "Image not available !"); |
1128 | + return false; |
1129 | + } |
1130 | + this.$el.find('.oe-image-preview').lightbox({ |
1131 | + fitToScreen: true, |
1132 | + jsonData: url_list, |
1133 | + loopImages: true, |
1134 | + imageClickClose: false, |
1135 | + disableNavbarLinks: true |
1136 | + }); |
1137 | + }, |
1138 | +}); |
1139 | + |
1140 | +openerp.web.form.widgets = openerp.web.form.widgets.extend({ |
1141 | + 'image_multi' : 'openerp.web.form.FieldBinaryImageMulti', |
1142 | +}); |
1143 | +} |
1144 | |
1145 | === added directory 'multi_image/static/src/xml' |
1146 | === added file 'multi_image/static/src/xml/image_multi.xml' |
1147 | --- multi_image/static/src/xml/image_multi.xml 1970-01-01 00:00:00 +0000 |
1148 | +++ multi_image/static/src/xml/image_multi.xml 2013-09-11 08:32:35 +0000 |
1149 | @@ -0,0 +1,126 @@ |
1150 | +<?xml version="1.0" encoding="UTF-8"?> |
1151 | +<templates id="template" xml:space="preserve"> |
1152 | + |
1153 | + <t t-name="HiddenInputMultiFile"> |
1154 | + <div t-attf-class="oe_hidden_input_file #{fileupload_class or ''}" t-att-style="fileupload_style"> |
1155 | + <form class="oe_form_binary_form" t-att-target="fileupload_id" |
1156 | + method="post" enctype="multipart/form-data" action="/web/binary/upload_image_multi"> |
1157 | + <input type="hidden" name="session_id" value=""/> |
1158 | + <input type="hidden" name="callback" t-att-value="fileupload_id"/> |
1159 | + <t t-raw="__content__"/> |
1160 | + <input type="file" class="oe_form_binary_file" name="ufile" accept="image/*"/> |
1161 | + </form> |
1162 | + <iframe t-att-id="fileupload_id" t-att-name="fileupload_id" style="display: none"/> |
1163 | + </div> |
1164 | + </t> |
1165 | + |
1166 | + <t t-name="FieldBinaryImageMulti"> |
1167 | + <table class="oe_form_field oe_form_field_binary" cellpadding="0" cellspacing="0" border="0" t-att-style="widget.node.attrs.style"> |
1168 | + <tr> |
1169 | + <td class="oe_form_binary" nowrap="true"> |
1170 | + <table cellspacing="0" cellpadding="0" border="0"> |
1171 | + <tr> |
1172 | + <td> |
1173 | + <t t-if="!widget.get('effective_readonly')"> |
1174 | + <t t-call="HiddenInputMultiFile"> |
1175 | + <t t-set="fileupload_id" t-value="widget.fileupload_id"/> |
1176 | + <t t-set="fileupload_style" t-translation="off">width: 83px;</t> |
1177 | + <button class="oe_button oe_field_button" type="button"> |
1178 | + <img t-att-src='_s + "/web/static/src/img/icons/STOCK_ADD.png"'/> |
1179 | + <span>ADD</span> |
1180 | + </button> |
1181 | + </t> |
1182 | + </t> |
1183 | + </td> |
1184 | + <td> |
1185 | + <button class="oe-image-preview oe_button oe_field_button oe_form_binary" type="button" title="Preview"> |
1186 | + <img t-att-src='_s + "/web/static/src/img/icons/gtk-zoom-fit.png"'/> |
1187 | + <span>Image Preview</span> |
1188 | + </button> |
1189 | + </td> |
1190 | + <td> |
1191 | + <button class="oe_image_list oe_button oe_field_button oe_form_binary" type="button" title="All Image"> |
1192 | + <img t-att-src='_s + "/web/static/src/img/icons/STOCK_DND_MULTIPLE.png"'/> |
1193 | + <span>List All Image</span> |
1194 | + </button> |
1195 | + </td> |
1196 | + </tr> |
1197 | + </table> |
1198 | + </td> |
1199 | + <td class="oe_form_binary_progress" style="display: none" nowrap="true"> |
1200 | + <div class="oe_form_binary_progress" style="display: none"> |
1201 | + <img t-att-src='_s + "/web/static/src/img/throbber.gif"' width="16" height="16"/> |
1202 | + <b>Uploading ...</b> |
1203 | + </div> |
1204 | + </td> |
1205 | + </tr> |
1206 | + </table> |
1207 | + </t> |
1208 | + |
1209 | + <t t-name="DialogImageList"> |
1210 | + <table id="DialogImageList"> |
1211 | + <tr t-foreach="image_list" t-as="row"> |
1212 | + <td t-foreach="row" t-as="column" > |
1213 | + <table class="hoverbox"> |
1214 | + <tr background-color="white"> |
1215 | + <t t-if="!widget.get('effective_readonly')"> |
1216 | + <td style="height:17px;"> |
1217 | + <span class="oe-remove-image oe_i" t-att-id="column.path" title="Delete Image" style="float:right;margin-top: -4px;">d</span> |
1218 | + </td> |
1219 | + </t> |
1220 | + </tr> |
1221 | + <tr> |
1222 | + <td> |
1223 | + <a style="cursor: default;" href='#' id="image_preview"> |
1224 | + <img class="list_image" t-att-src="column.path" t-att-title="column.name"/> <img t-att-title="column.name" t-att-src="column.path" class="preview list_image" /></a> |
1225 | + </td> |
1226 | + </tr> |
1227 | + </table> |
1228 | + </td> |
1229 | + </tr> |
1230 | + </table> |
1231 | + </t> |
1232 | + |
1233 | + <t t-name="ImageDescription"> |
1234 | + <div id="imagedescription" class="openerp oe_list oe_view" style="display: block; height:160px;width:100%;overflow: scroll"> |
1235 | + <table class="openerp oe_list_content"> |
1236 | + <thead> |
1237 | + <tr class="oe_list_header_columns"> |
1238 | + <th class="oe_list_header_char" t-if="!widget.get('effective_readonly')" style="width:3%;"></th> |
1239 | + <th class="oe_list_header_char" style="width:12%;">File Name</th> |
1240 | + <th class="oe_list_header_char" style="width:12%;">Title</th> |
1241 | + <th class="oe_list_header_char" style="width:25%;">Description</th> |
1242 | + <th class="oe_list_header_char" style="width:10%;">Size</th> |
1243 | + <th class="oe_list_header_char" style="width:20%;">Date</th> |
1244 | + <th class="oe_list_header_char" style="width:15%;">User</th> |
1245 | + <th class="oe_list_header_char" t-if="!widget.get('effective_readonly')" style="width:3%;"></th> |
1246 | + </tr> |
1247 | + </thead> |
1248 | + <tbody> |
1249 | + <tr t-foreach="image_list" t-as="row"> |
1250 | + <td width="1" t-att-id="row.name" class="oe-record-edit-link" t-if="!widget.get('effective_readonly')" style="width:3%;"> |
1251 | + <img t-if="!widget.get('effective_readonly')" src="/web/static/src/img/pencil.gif" /> |
1252 | + </td> |
1253 | + <td class="oe_image_row" t-att-id="row.name" style="width:12%;"><t t-esc="row.orignal_name" /></td> |
1254 | + <td class="oe_image_row" t-att-id="row.name" style="width:12%;"><t t-esc="row.name_1"/></td> |
1255 | + <td class="oe_image_row" t-att-id="row.name" style="width:25%;"><t t-esc="row.description"/></td> |
1256 | + <td class="oe_image_row" t-att-id="row.name" style="width:10%;"><t t-esc="row.size"/></td> |
1257 | + <td class="oe_image_row" t-att-id="row.name" style="width:20%;"><t t-esc="row.date"/></td> |
1258 | + <td class="oe_image_row" t-att-id="row.name" style="width:15%"><t t-esc="row.user"/></td> |
1259 | + <td class='oe_list_record_delete' width="3%" t-att-id="row.name" t-if="!widget.get('effective_readonly')"> |
1260 | + <button t-if="!widget.get('effective_readonly')" type="button" name="delete" class="oe_i">d</button> |
1261 | + </td> |
1262 | + </tr> |
1263 | + </tbody> |
1264 | + </table> |
1265 | + </div> |
1266 | + </t> |
1267 | + |
1268 | + <t t-name="edit_name_description"> |
1269 | + <div> |
1270 | + <h3>Title : <input t-att-value="widget.name_display" type="textbox" class="name_textbox" id="name_1" style="display: block; height:20px; width:450px;overflow: scroll"/></h3> |
1271 | + <h3>Description : <textarea type="textarea" class="field_text" id="description" style="display: text; height:160px;width:450px;overflow: scroll"><t t-esc="widget.description_display" /></textarea></h3> |
1272 | + </div> |
1273 | + </t> |
1274 | + |
1275 | +</templates> |
1276 | \ No newline at end of file |
1277 | |
1278 | === added directory 'multi_image_sample' |
1279 | === added file 'multi_image_sample/__init__.py' |
1280 | --- multi_image_sample/__init__.py 1970-01-01 00:00:00 +0000 |
1281 | +++ multi_image_sample/__init__.py 2013-09-11 08:32:35 +0000 |
1282 | @@ -0,0 +1,25 @@ |
1283 | +# -*- coding: utf-8 -*- |
1284 | +############################################################################## |
1285 | +# |
1286 | +# OpenERP, Open Source Management Solution |
1287 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
1288 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
1289 | +# |
1290 | +# This program is free software: you can redistribute it and/or modify |
1291 | +# it under the terms of the GNU Affero General Public License as |
1292 | +# published by the Free Software Foundation, either version 3 of the |
1293 | +# License, or (at your option) any later version. |
1294 | +# |
1295 | +# This program is distributed in the hope that it will be useful, |
1296 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1297 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1298 | +# GNU Affero General Public License for more details. |
1299 | +# |
1300 | +# You should have received a copy of the GNU Affero General Public License |
1301 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1302 | +# |
1303 | +############################################################################## |
1304 | + |
1305 | +import product |
1306 | + |
1307 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1308 | \ No newline at end of file |
1309 | |
1310 | === added file 'multi_image_sample/__openerp__.py' |
1311 | --- multi_image_sample/__openerp__.py 1970-01-01 00:00:00 +0000 |
1312 | +++ multi_image_sample/__openerp__.py 2013-09-11 08:32:35 +0000 |
1313 | @@ -0,0 +1,39 @@ |
1314 | +# -*- coding: utf-8 -*- |
1315 | +############################################################################## |
1316 | +# |
1317 | +# OpenERP, Open Source Management Solution |
1318 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
1319 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
1320 | +# |
1321 | +# This program is free software: you can redistribute it and/or modify |
1322 | +# it under the terms of the GNU Affero General Public License as |
1323 | +# published by the Free Software Foundation, either version 3 of the |
1324 | +# License, or (at your option) any later version. |
1325 | +# |
1326 | +# This program is distributed in the hope that it will be useful, |
1327 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1328 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1329 | +# GNU Affero General Public License for more details. |
1330 | +# |
1331 | +# You should have received a copy of the GNU Affero General Public License |
1332 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1333 | +# |
1334 | +############################################################################## |
1335 | + |
1336 | +{ |
1337 | + "name" : "Multi Image Sample", |
1338 | + "version" : "1.0", |
1339 | + "author" : "Serpent Consulting Services Pvt. Ltd.", |
1340 | + 'website': 'http://www.serpentcs.com', |
1341 | + "category": 'Image', |
1342 | + 'complexity': "easy", |
1343 | + 'depends': ['multi_image', 'product'], |
1344 | + "description": """ |
1345 | + This module is used for added multi image widget in product. |
1346 | + """, |
1347 | + 'update_xml': ['product_view.xml'], |
1348 | + 'installable': True, |
1349 | + 'auto_install': False, |
1350 | +} |
1351 | + |
1352 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1353 | |
1354 | === added file 'multi_image_sample/product.py' |
1355 | --- multi_image_sample/product.py 1970-01-01 00:00:00 +0000 |
1356 | +++ multi_image_sample/product.py 2013-09-11 08:32:35 +0000 |
1357 | @@ -0,0 +1,34 @@ |
1358 | +# -*- coding: utf-8 -*- |
1359 | +############################################################################## |
1360 | +# |
1361 | +# OpenERP, Open Source Management Solution |
1362 | +# Copyright (C) 2004-2010 OpenERP SA (<http://www.openerp.com>) |
1363 | +# Copyright (C) 2011-2013 Serpent Consulting Services Pvt. Ltd. (<http://www.serpentcs.com>). |
1364 | +# |
1365 | +# This program is free software: you can redistribute it and/or modify |
1366 | +# it under the terms of the GNU Affero General Public License as |
1367 | +# published by the Free Software Foundation, either version 3 of the |
1368 | +# License, or (at your option) any later version. |
1369 | +# |
1370 | +# This program is distributed in the hope that it will be useful, |
1371 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1372 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1373 | +# GNU Affero General Public License for more details. |
1374 | +# |
1375 | +# You should have received a copy of the GNU Affero General Public License |
1376 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1377 | +# |
1378 | +############################################################################## |
1379 | + |
1380 | +from openerp.osv import fields, osv |
1381 | + |
1382 | +class product_product(osv.osv): |
1383 | + _inherit = "product.product" |
1384 | + |
1385 | + _columns = { |
1386 | + 'multi_images': fields.text("Multi Images"), |
1387 | + } |
1388 | + |
1389 | +product_product() |
1390 | + |
1391 | +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
1392 | \ No newline at end of file |
1393 | |
1394 | === added file 'multi_image_sample/product_view.xml' |
1395 | --- multi_image_sample/product_view.xml 1970-01-01 00:00:00 +0000 |
1396 | +++ multi_image_sample/product_view.xml 2013-09-11 08:32:35 +0000 |
1397 | @@ -0,0 +1,20 @@ |
1398 | +<?xml version="1.0" encoding="utf-8"?> |
1399 | +<openerp> |
1400 | + <data> |
1401 | + |
1402 | + <record id="product_normal_multi_imageform_view" model="ir.ui.view"> |
1403 | + <field name="name">product.normal..multi.image.form.inherit</field> |
1404 | + <field name="model">product.product</field> |
1405 | + <field name="priority">5</field> |
1406 | + <field name="inherit_id" ref="product.product_normal_form_view"/> |
1407 | + <field name="arch" type="xml"> |
1408 | + <notebook position="inside"> |
1409 | + <page string="Images"> |
1410 | + <field name="multi_images" widget="image_multi"/> |
1411 | + </page> |
1412 | + </notebook> |
1413 | + </field> |
1414 | + </record> |
1415 | + |
1416 | + </data> |
1417 | +</openerp> |
1418 | |
1419 | === added directory 'multi_image_sample/static' |
1420 | === added directory 'multi_image_sample/static/src' |
1421 | === added directory 'multi_image_sample/static/src/img' |
1422 | === added file 'multi_image_sample/static/src/img/icon.png' |
1423 | Binary files multi_image_sample/static/src/img/icon.png 1970-01-01 00:00:00 +0000 and multi_image_sample/static/src/img/icon.png 2013-09-11 08:32:35 +0000 differ |
Hello.
I am testing this development.
I have some comments.
We are saving files wired in a folder inside the server code, IMHO it is a bad practice, we have a config on server:
--static- http-document- root=STATIC_ HTTP_DOCUMENT_ ROOT
specify the directory containing your static HTML
files (e.g '/var/www/') http-url- prefix= STATIC_ HTTP_URL_ PREFIX
specify the URL root prefix where you want web
browsers to access your static HTML files (e.g '/')
--static-
IMHO it should be saves there, with the unix security it will be safe enought i think.
I really like this development but why not use the attachment approach in the core?
I was working in our side behind OpenERP and i think it can be done in a generic widget that only show list of "url" this url can be uploaded files, i think work with a wired path in the server side is too dangerous.
What do you think?
I continue working on it to see more thing.
BTW EXCELLENT job.