rm files, move postload hook
authorAntony Lesuisse <al@openerp.com>
Sat, 6 Oct 2012 17:10:53 +0000 (19:10 +0200)
committerAntony Lesuisse <al@openerp.com>
Sat, 6 Oct 2012 17:10:53 +0000 (19:10 +0200)
bzr revid: al@openerp.com-20121006171053-qggp1r5263h7v7vd

63 files changed:
LICENSE.web [deleted file]
Makefile [deleted file]
README.web [deleted file]
addons/web/__init__.py
addons/web/common/http.py
addons/web/doc/Makefile [new file with mode: 0644]
addons/web/doc/_static/openerp.png [new file with mode: 0644]
addons/web/doc/_templates/sidebarintro.html [new file with mode: 0644]
addons/web/doc/_templates/sidebarlogo.html [new file with mode: 0644]
addons/web/doc/_themes/LICENSE [new file with mode: 0644]
addons/web/doc/_themes/README [new file with mode: 0644]
addons/web/doc/_themes/flask/layout.html [new file with mode: 0644]
addons/web/doc/_themes/flask/relations.html [new file with mode: 0644]
addons/web/doc/_themes/flask/static/flasky.css_t [new file with mode: 0644]
addons/web/doc/_themes/flask/static/small_flask.css [new file with mode: 0644]
addons/web/doc/_themes/flask/theme.conf [new file with mode: 0644]
addons/web/doc/_themes/flask_small/layout.html [new file with mode: 0644]
addons/web/doc/_themes/flask_small/static/flasky.css_t [new file with mode: 0644]
addons/web/doc/_themes/flask_small/theme.conf [new file with mode: 0644]
addons/web/doc/_themes/flask_theme_support.py [new file with mode: 0644]
addons/web/doc/addon-structure.txt [new file with mode: 0644]
addons/web/doc/async.rst [new file with mode: 0644]
addons/web/doc/changelog-7.0.rst [new file with mode: 0644]
addons/web/doc/conf.py [new file with mode: 0644]
addons/web/doc/form-notes.rst [new file with mode: 0644]
addons/web/doc/guides/client-action.rst [new file with mode: 0644]
addons/web/doc/index.rst [new file with mode: 0644]
addons/web/doc/list-view.rst [new file with mode: 0644]
addons/web/doc/make.bat [new file with mode: 0644]
addons/web/doc/rpc.rst [new file with mode: 0644]
addons/web/doc/search-view.rst [new file with mode: 0644]
addons/web/doc/widget.rst [new file with mode: 0644]
doc/Makefile [deleted file]
doc/_static/openerp.png [deleted file]
doc/_templates/sidebarintro.html [deleted file]
doc/_templates/sidebarlogo.html [deleted file]
doc/_themes/LICENSE [deleted file]
doc/_themes/README [deleted file]
doc/_themes/flask/layout.html [deleted file]
doc/_themes/flask/relations.html [deleted file]
doc/_themes/flask/static/flasky.css_t [deleted file]
doc/_themes/flask/static/small_flask.css [deleted file]
doc/_themes/flask/theme.conf [deleted file]
doc/_themes/flask_small/layout.html [deleted file]
doc/_themes/flask_small/static/flasky.css_t [deleted file]
doc/_themes/flask_small/theme.conf [deleted file]
doc/_themes/flask_theme_support.py [deleted file]
doc/addon-structure.txt [deleted file]
doc/async.rst [deleted file]
doc/changelog-7.0.rst [deleted file]
doc/conf.py [deleted file]
doc/form-notes.rst [deleted file]
doc/guides/client-action.rst [deleted file]
doc/index.rst [deleted file]
doc/list-view.rst [deleted file]
doc/make.bat [deleted file]
doc/rpc.rst [deleted file]
doc/search-view.rst [deleted file]
doc/widget.rst [deleted file]
logging.json [deleted file]
openerp-web [deleted file]
openerp-web.cfg [deleted file]
setup.py [deleted file]

diff --git a/LICENSE.web b/LICENSE.web
deleted file mode 100644 (file)
index dba13ed..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-                    GNU AFFERO GENERAL PUBLIC LICENSE
-                       Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
-  A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate.  Many developers of free software are heartened and
-encouraged by the resulting cooperation.  However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
-  The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community.  It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server.  Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
-  An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals.  This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU Affero General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Remote Network Interaction; Use with the GNU General Public License.
-
-  Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software.  This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time.  Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source.  For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code.  There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 4beb20d..0000000
--- a/Makefile
+++ /dev/null
@@ -1,34 +0,0 @@
-.PHONY: all doc release clean
-
-HOST = 127.0.0.1
-PORT = 8080
-
-all: run
-
-run:
-       python openerp-web.py -a ${HOST} -p ${PORT}
-
-release:
-       python setup.py sdist
-
-install:
-       python setup.py install
-
-clean:
-       @find . -name '*.pyc' -exec rm -f {} +
-       @find . -name '*.pyo' -exec rm -f {} +
-       @find . -name '*.swp' -exec rm -f {} +
-       @find . -name '*~' -exec rm -f {} +
-       @rm -rf build
-       @rm -rf dist
-       @rm -rf *.egg-info
-
-doc:
-       make -C doc html
-
-cloc:
-       cloc addons/*/common/*.py addons/*/controllers/*.py addons/*/static/src/*.js addons/*/static/src/js/*.js addons/*/static/src/css/*.css addons/*/static/src/xml/*.xml
-
-blamestat:
-       echo addons/*/common/*.py addons/*/controllers/*.py addons/*/static/src/js/*.js addons/*/static/src/css/*.css addons/*/static/src/xml/*.xml  | xargs -t -n 1 bzr blame -v --long --all |  awk '{print $2}' | sort | uniq -c | sort -n
-
diff --git a/README.web b/README.web
deleted file mode 100644 (file)
index 72393ba..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-OpenERP Web
------------
-
-To build the documentation use:
-
-$ make doc
-
-then look at doc/build/html/index.html
-
index 621931e..c4337b3 100644 (file)
@@ -1,31 +1,4 @@
-import logging
-
-from . import common
-from . import controllers
-
-_logger = logging.getLogger(__name__)
-
-class Options(object):
-    pass
-
-def wsgi_postload():
-    import openerp
-    import os
-    import tempfile
-    import getpass
-    _logger.info("embedded mode")
-    o = Options()
-    o.dbfilter = openerp.tools.config['dbfilter']
-    o.server_wide_modules = openerp.conf.server_wide_modules or ['web']
-    try:
-        username = getpass.getuser()
-    except Exception:
-        username = "unknown"
-    o.session_storage = os.path.join(tempfile.gettempdir(), "oe-sessions-" + username)
-    o.addons_path = openerp.modules.module.ad_paths
-    o.serve_static = True
-    o.backend = 'local'
-
-    app = common.http.Root(o)
-    openerp.wsgi.register_wsgi_handler(app)
+import common
+import controllers
 
+wsgi_postload = common.http.wsgi_postload
index 4955876..3b9fdf3 100644 (file)
@@ -579,4 +579,28 @@ class Root(object):
                     ps = '/'
         return None
 
+class Options(object):
+    pass
+
+def wsgi_postload():
+    import openerp
+    import tempfile
+    import getpass
+    _logger.info("embedded mode")
+    o = Options()
+    o.dbfilter = openerp.tools.config['dbfilter']
+    o.server_wide_modules = openerp.conf.server_wide_modules or ['web']
+    try:
+        username = getpass.getuser()
+    except Exception:
+        username = "unknown"
+    o.session_storage = os.path.join(tempfile.gettempdir(), "oe-sessions-" + username)
+    o.addons_path = openerp.modules.module.ad_paths
+    o.serve_static = True
+    o.backend = 'local'
+
+    app = Root(o)
+    openerp.wsgi.register_wsgi_handler(app)
+
+
 # vim:et:ts=4:sw=4:
diff --git a/addons/web/doc/Makefile b/addons/web/doc/Makefile
new file mode 100644 (file)
index 0000000..c1eff18
--- /dev/null
@@ -0,0 +1,154 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    = -q
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+# the i18n builder cannot share the environment and doctrees with the others
+I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
+
+help:
+       @echo "Please use \`make <target>' where <target> is one of"
+       @echo "  html       to make standalone HTML files"
+       @echo "  dirhtml    to make HTML files named index.html in directories"
+       @echo "  singlehtml to make a single large HTML file"
+       @echo "  pickle     to make pickle files"
+       @echo "  json       to make JSON files"
+       @echo "  htmlhelp   to make HTML files and a HTML help project"
+       @echo "  qthelp     to make HTML files and a qthelp project"
+       @echo "  devhelp    to make HTML files and a Devhelp project"
+       @echo "  epub       to make an epub"
+       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+       @echo "  text       to make text files"
+       @echo "  man        to make manual pages"
+       @echo "  texinfo    to make Texinfo files"
+       @echo "  info       to make Texinfo files and run them through makeinfo"
+       @echo "  gettext    to make PO message catalogs"
+       @echo "  changes    to make an overview of all changed/added/deprecated items"
+       @echo "  linkcheck  to check all external links for integrity"
+       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+       -rm -rf $(BUILDDIR)/*
+
+html:
+       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+       sed -i '/-99999/d' _build/dirhtml/_static/flasky.css
+       @echo
+       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+       @echo
+       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+       @echo
+       @echo "Build finished; now you can process the pickle files."
+
+json:
+       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+       @echo
+       @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+       @echo
+       @echo "Build finished; now you can run HTML Help Workshop with the" \
+             ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+       @echo
+       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhcp"
+       @echo "To view the help file:"
+       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhc"
+
+devhelp:
+       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+       @echo
+       @echo "Build finished."
+       @echo "To view the help file:"
+       @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation"
+       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation"
+       @echo "# devhelp"
+
+epub:
+       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+       @echo
+       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo
+       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+       @echo "Run \`make' in that directory to run these through (pdf)latex" \
+             "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+       @echo "Running LaTeX files through pdflatex..."
+       $(MAKE) -C $(BUILDDIR)/latex all-pdf
+       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+       @echo
+       @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+       @echo
+       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+texinfo:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo
+       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
+       @echo "Run \`make' in that directory to run these through makeinfo" \
+             "(use \`make info' here to do that automatically)."
+
+info:
+       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
+       @echo "Running Texinfo files through makeinfo..."
+       make -C $(BUILDDIR)/texinfo info
+       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
+
+gettext:
+       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
+       @echo
+       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
+
+changes:
+       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+       @echo
+       @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+       @echo
+       @echo "Link check complete; look for any errors in the above output " \
+             "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+       @echo "Testing of doctests in the sources finished, look at the " \
+             "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/addons/web/doc/_static/openerp.png b/addons/web/doc/_static/openerp.png
new file mode 100644 (file)
index 0000000..d6dbd9d
Binary files /dev/null and b/addons/web/doc/_static/openerp.png differ
diff --git a/addons/web/doc/_templates/sidebarintro.html b/addons/web/doc/_templates/sidebarintro.html
new file mode 100644 (file)
index 0000000..ecd5198
--- /dev/null
@@ -0,0 +1,16 @@
+<p class="logo"><a href="http://doc.openerp.com/">
+  <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/>
+</a></p>
+
+<h3>Other Docs</h3>
+<ul>
+  <li><a href="http://doc.openerp.com/trunk/developers">OpenERP Developers Documentation</a></li>
+  <li><a href="http://doc.openerp.com/trunk/developers/server">OpenERP Server Developers Documentation</a></li>
+  <li><a href="http://doc.openerp.com/trunk/users">OpenERP Users Documentation</a></li>
+</ul>
+
+<h3>Useful Links</h3>
+<ul>
+  <li><a href="http://www.openerp.com/">The OpenERP website</a></li>
+  <li><a href="http://python.org/">The Python programming language</a></li>
+</ul>
diff --git a/addons/web/doc/_templates/sidebarlogo.html b/addons/web/doc/_templates/sidebarlogo.html
new file mode 100644 (file)
index 0000000..de6e3e5
--- /dev/null
@@ -0,0 +1,3 @@
+<p class="logo"><a href="{{ pathto(master_doc) }}">
+  <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/>
+</a></p>
diff --git a/addons/web/doc/_themes/LICENSE b/addons/web/doc/_themes/LICENSE
new file mode 100644 (file)
index 0000000..8daab7e
--- /dev/null
@@ -0,0 +1,37 @@
+Copyright (c) 2010 by Armin Ronacher.
+
+Some rights reserved.
+
+Redistribution and use in source and binary forms of the theme, with or
+without modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the following
+  disclaimer in the documentation and/or other materials provided
+  with the distribution.
+
+* The names of the contributors may not be used to endorse or
+  promote products derived from this software without specific
+  prior written permission.
+
+We kindly ask you to only use these themes in an unmodified manner just
+for Flask and Flask-related products, not for unrelated projects.  If you
+like the visual style and want to use it for your own projects, please
+consider making some larger changes to the themes (such as changing
+font faces, sizes, colors or margins).
+
+THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/addons/web/doc/_themes/README b/addons/web/doc/_themes/README
new file mode 100644 (file)
index 0000000..b3292bd
--- /dev/null
@@ -0,0 +1,31 @@
+Flask Sphinx Styles
+===================
+
+This repository contains sphinx styles for Flask and Flask related
+projects.  To use this style in your Sphinx documentation, follow
+this guide:
+
+1. put this folder as _themes into your docs folder.  Alternatively
+   you can also use git submodules to check out the contents there.
+2. add this to your conf.py:
+
+   sys.path.append(os.path.abspath('_themes'))
+   html_theme_path = ['_themes']
+   html_theme = 'flask'
+
+The following themes exist:
+
+- 'flask' - the standard flask documentation theme for large
+  projects
+- 'flask_small' - small one-page theme.  Intended to be used by
+  very small addon libraries for flask.
+
+The following options exist for the flask_small theme:
+
+   [options]
+   index_logo = ''              filename of a picture in _static
+                                to be used as replacement for the
+                                h1 in the index.rst file.
+   index_logo_height = 120px    height of the index logo
+   github_fork = ''             repository name on github for the
+                                "fork me" badge
diff --git a/addons/web/doc/_themes/flask/layout.html b/addons/web/doc/_themes/flask/layout.html
new file mode 100644 (file)
index 0000000..ad08ecc
--- /dev/null
@@ -0,0 +1,25 @@
+{%- extends "basic/layout.html" %}
+{%- block extrahead %}
+  {{ super() }}
+  {% if theme_touch_icon %}
+  <link rel="apple-touch-icon" href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}" />
+  {% endif %}
+  <link media="only screen and (max-device-width: 480px)" href="{{
+    pathto('_static/small_flask.css', 1) }}" type= "text/css" rel="stylesheet" />
+{% endblock %}
+{%- block relbar2 %}{% endblock %}
+{% block header %}
+  {{ super() }}
+  {% if pagename == 'index' %}
+  <div class=indexwrapper>
+  {% endif %}
+{% endblock %}
+{%- block footer %}
+  <div class="footer">
+    &copy; Copyright {{ copyright }}
+    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> and a modified <a href="https://github.com/mitsuhiko/flask-sphinx-themes">Flask theme</a>.
+  </div>
+  {% if pagename == 'index' %}
+  </div>
+  {% endif %}
+{%- endblock %}
diff --git a/addons/web/doc/_themes/flask/relations.html b/addons/web/doc/_themes/flask/relations.html
new file mode 100644 (file)
index 0000000..3bbcde8
--- /dev/null
@@ -0,0 +1,19 @@
+<h3>Related Topics</h3>
+<ul>
+  <li><a href="{{ pathto(master_doc) }}">Documentation overview</a><ul>
+  {%- for parent in parents %}
+  <li><a href="{{ parent.link|e }}">{{ parent.title }}</a><ul>
+  {%- endfor %}
+    {%- if prev %}
+      <li>Previous: <a href="{{ prev.link|e }}" title="{{ _('previous chapter')
+        }}">{{ prev.title }}</a></li>
+    {%- endif %}
+    {%- if next %}
+      <li>Next: <a href="{{ next.link|e }}" title="{{ _('next chapter')
+        }}">{{ next.title }}</a></li>
+    {%- endif %}
+  {%- for parent in parents %}
+  </ul></li>
+  {%- endfor %}
+  </ul></li>
+</ul>
diff --git a/addons/web/doc/_themes/flask/static/flasky.css_t b/addons/web/doc/_themes/flask/static/flasky.css_t
new file mode 100644 (file)
index 0000000..0280e15
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ * flasky.css_t
+ * ~~~~~~~~~~~~
+ *
+ * :copyright: Copyright 2010 by Armin Ronacher.
+ * :license: Flask Design License, see LICENSE for details.
+ */
+
+{% set page_width = '80em' %}
+{% set sidebar_width = '16em' %}
+@import url("basic.css");
+/* -- page layout ----------------------------------------------------------- */
+body {
+    font-family: 'Georgia', serif;
+    font-size: 15px;
+    background-color: white;
+    color: #000;
+    margin: 0;
+    padding: 0;
+}
+
+div.document {
+    width: {{ page_width }};
+    margin: 30px auto 0 auto;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 0 0 0 {{ sidebar_width }};
+}
+
+div.sphinxsidebar {
+    width: {{ sidebar_width }};
+}
+
+hr {
+    border: 1px solid #B1B4B6;
+}
+div.body {
+    background-color: #ffffff;
+    color: #3E4349;
+    padding: 0 0px 0 0px;
+}
+
+img.floatingflask {
+    padding: 0 0 10px 10px;
+    float: right;
+}
+div.footer {
+    width: {{ page_width }};
+    margin: 20px auto 30px auto;
+    font-size: 12px;
+    color: #888;
+    text-align: right;
+}
+
+div.footer a {
+    color: #888;
+}
+
+div.related {
+    display: none;
+}
+div.sphinxsidebar a {
+    color: #444;
+    text-decoration: none;
+    border-bottom: 1px dotted #999;
+}
+
+div.sphinxsidebar a:hover {
+    border-bottom: 1px solid #999;
+}
+div.sphinxsidebar {
+    font-size: 12px;
+    line-height: 1.5;
+}
+
+div.sphinxsidebarwrapper {
+    padding: 0px 10px;
+}
+
+div.sphinxsidebarwrapper p.logo {
+    padding: 0 0 20px 0;
+    margin: 0;
+    text-align: center;
+}
+div.sphinxsidebar h3,
+div.sphinxsidebar h4 {
+    font-family: 'Garamond', 'Georgia', serif;
+    color: #444;
+    font-size: 22px;
+    font-weight: normal;
+    margin: 0 0 5px 0;
+    padding: 0;
+}
+
+div.sphinxsidebar h4 {
+    font-size: 18px;
+}
+div.sphinxsidebar h3 a {
+    color: #444;
+}
+
+div.sphinxsidebar p.logo a,
+div.sphinxsidebar h3 a,
+div.sphinxsidebar p.logo a:hover,
+div.sphinxsidebar h3 a:hover {
+    border: none;
+}
+div.sphinxsidebar p {
+    color: #555;
+    margin: 10px 0;
+}
+
+div.sphinxsidebar ul {
+    margin: 10px 0;
+    padding: 0;
+    color: #000;
+}
+div.sphinxsidebar input {
+    border: 1px solid #ccc;
+    font-family: 'Georgia', serif;
+    font-size: 1em;
+}
+/* -- body styles ----------------------------------------------------------- */
+a {
+    color: #004B6B;
+    text-decoration: underline;
+}
+a:hover {
+    color: #6D4100;
+    text-decoration: underline;
+}
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Garamond', 'Georgia', serif;
+    font-weight: normal;
+    margin: 30px 0px 10px 0px;
+    padding: 0;
+}
+
+{% if theme_index_logo %}
+div.indexwrapper h1 {
+    text-indent: -999999px;
+    background: url({{ theme_index_logo }}) no-repeat center center;
+    height: {{ theme_index_logo_height }};
+}
+{% endif %}
+div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
+div.body h2 { font-size: 180%; }
+div.body h3 { font-size: 150%; }
+div.body h4 { font-size: 130%; }
+div.body h5 { font-size: 100%; }
+div.body h6 { font-size: 100%; }
+a.headerlink {
+    color: #ddd;
+    padding: 0 4px;
+    text-decoration: none;
+}
+a.headerlink:hover {
+    color: #444;
+    background: #eaeaea;
+}
+div.body p, div.body dd, div.body li {
+    line-height: 1.4em;
+}
+
+div.admonition {
+    background: #fafafa;
+    margin: 20px -30px;
+    padding: 10px 30px;
+    border-top: 1px solid #ccc;
+    border-bottom: 1px solid #ccc;
+}
+
+div.admonition tt.xref, div.admonition a tt {
+    border-bottom: 1px solid #fafafa;
+}
+
+dd div.admonition {
+    margin-left: -60px;
+    padding-left: 60px;
+}
+
+div.admonition p.admonition-title {
+    font-family: 'Garamond', 'Georgia', serif;
+    font-weight: normal;
+    font-size: 22px;
+    margin: 0 0 10px 0;
+    padding: 0;
+    line-height: 1;
+}
+
+div.admonition p.last {
+    margin-bottom: 0;
+}
+
+div.highlight {
+    background-color: white;
+}
+
+dt:target, .highlight {
+    background: #FAF3E8;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+div.topic {
+    background-color: #eee;
+}
+p.admonition-title {
+    display: inline;
+}
+p.admonition-title:after {
+    content: ":";
+}
+
+pre, tt {
+    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.9em;
+}
+
+img.screenshot {
+}
+
+tt.descname, tt.descclassname {
+    font-size: 0.95em;
+}
+
+tt.descname {
+    padding-right: 0.08em;
+}
+
+img.screenshot {
+    -moz-box-shadow: 2px 2px 4px #eee;
+    -webkit-box-shadow: 2px 2px 4px #eee;
+    box-shadow: 2px 2px 4px #eee;
+}
+
+table.docutils {
+    border: 1px solid #888;
+    -moz-box-shadow: 2px 2px 4px #eee;
+    -webkit-box-shadow: 2px 2px 4px #eee;
+    box-shadow: 2px 2px 4px #eee;
+}
+
+table.docutils td, table.docutils th {
+    border: 1px solid #888;
+    padding: 0.25em 0.7em;
+}
+
+table.field-list, table.footnote {
+    border: none;
+    -moz-box-shadow: none;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+}
+
+table.footnote {
+    margin: 15px 0;
+    width: 100%;
+    border: 1px solid #eee;
+    background: #fdfdfd;
+    font-size: 0.9em;
+}
+
+table.footnote + table.footnote {
+    margin-top: -15px;
+    border-top: none;
+}
+
+table.field-list th {
+    padding: 0 0.8em 0 0;
+}
+
+table.field-list td {
+    padding: 0;
+}
+
+table.footnote td.label {
+    width: 0px;
+    padding: 0.3em 0 0.3em 0.5em;
+}
+
+table.footnote td {
+    padding: 0.3em 0.5em;
+}
+
+dl {
+    margin: 0;
+    padding: 0;
+}
+
+dl dd {
+    margin-left: 30px;
+}
+
+blockquote {
+    margin: 0 0 0 30px;
+    padding: 0;
+}
+
+ul, ol {
+    margin: 10px 0 10px 30px;
+    padding: 0;
+}
+pre {
+    background: #eee;
+    padding: 7px 30px;
+    margin: 15px -30px;
+    line-height: 1.3em;
+}
+
+dl pre, blockquote pre, li pre {
+    margin-left: -60px;
+    padding-left: 60px;
+}
+
+dl dl pre {
+    margin-left: -90px;
+    padding-left: 90px;
+}
+tt {
+    background-color: #ecf0f3;
+    color: #222;
+    /* padding: 1px 2px; */
+}
+
+tt.xref, a tt {
+    background-color: #FBFBFB;
+    border-bottom: 1px solid white;
+}
+
+a.reference {
+    text-decoration: none;
+    border-bottom: 1px dotted #004B6B;
+}
+
+a.reference:hover {
+    border-bottom: 1px solid #6D4100;
+}
+
+a.footnote-reference {
+    text-decoration: none;
+    font-size: 0.7em;
+    vertical-align: top;
+    border-bottom: 1px dotted #004B6B;
+}
+
+a.footnote-reference:hover {
+    border-bottom: 1px solid #6D4100;
+}
+
+a:hover tt {
+    background: #EEE;
+}
diff --git a/addons/web/doc/_themes/flask/static/small_flask.css b/addons/web/doc/_themes/flask/static/small_flask.css
new file mode 100644 (file)
index 0000000..1c6df30
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * small_flask.css_t
+ * ~~~~~~~~~~~~~~~~~
+ *
+ * :copyright: Copyright 2010 by Armin Ronacher.
+ * :license: Flask Design License, see LICENSE for details.
+ */
+
+body {
+    margin: 0;
+    padding: 20px 30px;
+}
+
+div.documentwrapper {
+    float: none;
+    background: white;
+}
+
+div.sphinxsidebar {
+    display: block;
+    float: none;
+    width: 102.5%;
+    margin: 50px -30px -20px -30px;
+    padding: 10px 20px;
+    background: #333;
+    color: white;
+}
+
+div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
+div.sphinxsidebar h3 a {
+    color: white;
+}
+
+div.sphinxsidebar a {
+    color: #aaa;
+}
+
+div.sphinxsidebar p.logo {
+    display: none;
+}
+
+div.document {
+    width: 100%;
+    margin: 0;
+}
+
+div.related {
+    display: block;
+    margin: 0;
+    padding: 10px 0 20px 0;
+}
+
+div.related ul,
+div.related ul li {
+    margin: 0;
+    padding: 0;
+}
+
+div.footer {
+    display: none;
+}
+
+div.bodywrapper {
+    margin: 0;
+}
+
+div.body {
+    min-height: 0;
+    padding: 0;
+}
diff --git a/addons/web/doc/_themes/flask/theme.conf b/addons/web/doc/_themes/flask/theme.conf
new file mode 100644 (file)
index 0000000..18c720f
--- /dev/null
@@ -0,0 +1,9 @@
+[theme]
+inherit = basic
+stylesheet = flasky.css
+pygments_style = flask_theme_support.FlaskyStyle
+
+[options]
+index_logo = ''
+index_logo_height = 120px
+touch_icon = 
diff --git a/addons/web/doc/_themes/flask_small/layout.html b/addons/web/doc/_themes/flask_small/layout.html
new file mode 100644 (file)
index 0000000..aa1716a
--- /dev/null
@@ -0,0 +1,22 @@
+{% extends "basic/layout.html" %}
+{% block header %}
+  {{ super() }}
+  {% if pagename == 'index' %}
+  <div class=indexwrapper>
+  {% endif %}
+{% endblock %}
+{% block footer %}
+  {% if pagename == 'index' %}
+  </div>
+  {% endif %}
+{% endblock %}
+{# do not display relbars #}
+{% block relbar1 %}{% endblock %}
+{% block relbar2 %}
+  {% if theme_github_fork %}
+    <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;"
+    src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
+  {% endif %}
+{% endblock %}
+{% block sidebar1 %}{% endblock %}
+{% block sidebar2 %}{% endblock %}
diff --git a/addons/web/doc/_themes/flask_small/static/flasky.css_t b/addons/web/doc/_themes/flask_small/static/flasky.css_t
new file mode 100644 (file)
index 0000000..fe2141c
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * flasky.css_t
+ * ~~~~~~~~~~~~
+ *
+ * Sphinx stylesheet -- flasky theme based on nature theme.
+ *
+ * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+@import url("basic.css");
+/* -- page layout ----------------------------------------------------------- */
+body {
+    font-family: 'Georgia', serif;
+    font-size: 17px;
+    color: #000;
+    background: white;
+    margin: 0;
+    padding: 0;
+}
+
+div.documentwrapper {
+    float: left;
+    width: 100%;
+}
+
+div.bodywrapper {
+    margin: 40px auto 0 auto;
+    width: 700px;
+}
+
+hr {
+    border: 1px solid #B1B4B6;
+}
+div.body {
+    background-color: #ffffff;
+    color: #3E4349;
+    padding: 0 30px 30px 30px;
+}
+
+img.floatingflask {
+    padding: 0 0 10px 10px;
+    float: right;
+}
+div.footer {
+    text-align: right;
+    color: #888;
+    padding: 10px;
+    font-size: 14px;
+    width: 650px;
+    margin: 0 auto 40px auto;
+}
+div.footer a {
+    color: #888;
+    text-decoration: underline;
+}
+div.related {
+    line-height: 32px;
+    color: #888;
+}
+
+div.related ul {
+    padding: 0 0 0 10px;
+}
+div.related a {
+    color: #444;
+}
+/* -- body styles ----------------------------------------------------------- */
+a {
+    color: #004B6B;
+    text-decoration: underline;
+}
+a:hover {
+    color: #6D4100;
+    text-decoration: underline;
+}
+
+div.body {
+    padding-bottom: 40px; /* saved for footer */
+}
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+    font-family: 'Garamond', 'Georgia', serif;
+    font-weight: normal;
+    margin: 30px 0px 10px 0px;
+    padding: 0;
+}
+
+{% if theme_index_logo %}
+div.indexwrapper h1 {
+    text-indent: -999999px;
+    background: url({{ theme_index_logo }}) no-repeat center center;
+    height: {{ theme_index_logo_height }};
+}
+{% endif %}
+div.body h2 { font-size: 180%; }
+div.body h3 { font-size: 150%; }
+div.body h4 { font-size: 130%; }
+div.body h5 { font-size: 100%; }
+div.body h6 { font-size: 100%; }
+a.headerlink {
+    color: white;
+    padding: 0 4px;
+    text-decoration: none;
+}
+a.headerlink:hover {
+    color: #444;
+    background: #eaeaea;
+}
+div.body p, div.body dd, div.body li {
+    line-height: 1.4em;
+}
+
+div.admonition {
+    background: #fafafa;
+    margin: 20px -30px;
+    padding: 10px 30px;
+    border-top: 1px solid #ccc;
+    border-bottom: 1px solid #ccc;
+}
+
+div.admonition p.admonition-title {
+    font-family: 'Garamond', 'Georgia', serif;
+    font-weight: normal;
+    font-size: 24px;
+    margin: 0 0 10px 0;
+    padding: 0;
+    line-height: 1;
+}
+
+div.admonition p.last {
+    margin-bottom: 0;
+}
+
+div.highlight{
+    background-color: white;
+}
+
+dt:target, .highlight {
+    background: #FAF3E8;
+}
+
+div.note {
+    background-color: #eee;
+    border: 1px solid #ccc;
+}
+div.seealso {
+    background-color: #ffc;
+    border: 1px solid #ff6;
+}
+div.topic {
+    background-color: #eee;
+}
+div.warning {
+    background-color: #ffe4e4;
+    border: 1px solid #f66;
+}
+p.admonition-title {
+    display: inline;
+}
+p.admonition-title:after {
+    content: ":";
+}
+
+pre, tt {
+    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
+    font-size: 0.85em;
+}
+
+img.screenshot {
+}
+
+tt.descname, tt.descclassname {
+    font-size: 0.95em;
+}
+
+tt.descname {
+    padding-right: 0.08em;
+}
+
+img.screenshot {
+    -moz-box-shadow: 2px 2px 4px #eee;
+    -webkit-box-shadow: 2px 2px 4px #eee;
+    box-shadow: 2px 2px 4px #eee;
+}
+
+table.docutils {
+    border: 1px solid #888;
+    -moz-box-shadow: 2px 2px 4px #eee;
+    -webkit-box-shadow: 2px 2px 4px #eee;
+    box-shadow: 2px 2px 4px #eee;
+}
+
+table.docutils td, table.docutils th {
+    border: 1px solid #888;
+    padding: 0.25em 0.7em;
+}
+
+table.field-list, table.footnote {
+    border: none;
+    -moz-box-shadow: none;
+    -webkit-box-shadow: none;
+    box-shadow: none;
+}
+
+table.footnote {
+    margin: 15px 0;
+    width: 100%;
+    border: 1px solid #eee;
+}
+
+table.field-list th {
+    padding: 0 0.8em 0 0;
+}
+
+table.field-list td {
+    padding: 0;
+}
+
+table.footnote td {
+    padding: 0.5em;
+}
+
+dl {
+    margin: 0;
+    padding: 0;
+}
+
+dl dd {
+    margin-left: 30px;
+}
+pre {
+    padding: 0;
+    margin: 15px -30px;
+    padding: 8px;
+    line-height: 1.3em;
+    padding: 7px 30px;
+    background: #eee;
+    border-radius: 2px;
+    -moz-border-radius: 2px;
+    -webkit-border-radius: 2px;
+}
+
+dl pre {
+    margin-left: -60px;
+    padding-left: 60px;
+}
+
+tt {
+    background-color: #ecf0f3;
+    color: #222;
+    /* padding: 1px 2px; */
+}
+
+tt.xref, a tt {
+    background-color: #FBFBFB;
+}
+
+a:hover tt {
+    background: #EEE;
+}
diff --git a/addons/web/doc/_themes/flask_small/theme.conf b/addons/web/doc/_themes/flask_small/theme.conf
new file mode 100644 (file)
index 0000000..542b462
--- /dev/null
@@ -0,0 +1,10 @@
+[theme]
+inherit = basic
+stylesheet = flasky.css
+nosidebar = true
+pygments_style = flask_theme_support.FlaskyStyle
+
+[options]
+index_logo = ''
+index_logo_height = 120px
+github_fork = ''
diff --git a/addons/web/doc/_themes/flask_theme_support.py b/addons/web/doc/_themes/flask_theme_support.py
new file mode 100644 (file)
index 0000000..33f4744
--- /dev/null
@@ -0,0 +1,86 @@
+# flasky extensions.  flasky pygments style based on tango style
+from pygments.style import Style
+from pygments.token import Keyword, Name, Comment, String, Error, \
+     Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
+
+
+class FlaskyStyle(Style):
+    background_color = "#f8f8f8"
+    default_style = ""
+
+    styles = {
+        # No corresponding class for the following:
+        #Text:                     "", # class:  ''
+        Whitespace:                "underline #f8f8f8",      # class: 'w'
+        Error:                     "#a40000 border:#ef2929", # class: 'err'
+        Other:                     "#000000",                # class 'x'
+
+        Comment:                   "italic #8f5902", # class: 'c'
+        Comment.Preproc:           "noitalic",       # class: 'cp'
+
+        Keyword:                   "bold #004461",   # class: 'k'
+        Keyword.Constant:          "bold #004461",   # class: 'kc'
+        Keyword.Declaration:       "bold #004461",   # class: 'kd'
+        Keyword.Namespace:         "bold #004461",   # class: 'kn'
+        Keyword.Pseudo:            "bold #004461",   # class: 'kp'
+        Keyword.Reserved:          "bold #004461",   # class: 'kr'
+        Keyword.Type:              "bold #004461",   # class: 'kt'
+
+        Operator:                  "#582800",   # class: 'o'
+        Operator.Word:             "bold #004461",   # class: 'ow' - like keywords
+
+        Punctuation:               "bold #000000",   # class: 'p'
+
+        # because special names such as Name.Class, Name.Function, etc.
+        # are not recognized as such later in the parsing, we choose them
+        # to look the same as ordinary variables.
+        Name:                      "#000000",        # class: 'n'
+        Name.Attribute:            "#c4a000",        # class: 'na' - to be revised
+        Name.Builtin:              "#004461",        # class: 'nb'
+        Name.Builtin.Pseudo:       "#3465a4",        # class: 'bp'
+        Name.Class:                "#000000",        # class: 'nc' - to be revised
+        Name.Constant:             "#000000",        # class: 'no' - to be revised
+        Name.Decorator:            "#888",           # class: 'nd' - to be revised
+        Name.Entity:               "#ce5c00",        # class: 'ni'
+        Name.Exception:            "bold #cc0000",   # class: 'ne'
+        Name.Function:             "#000000",        # class: 'nf'
+        Name.Property:             "#000000",        # class: 'py'
+        Name.Label:                "#f57900",        # class: 'nl'
+        Name.Namespace:            "#000000",        # class: 'nn' - to be revised
+        Name.Other:                "#000000",        # class: 'nx'
+        Name.Tag:                  "bold #004461",   # class: 'nt' - like a keyword
+        Name.Variable:             "#000000",        # class: 'nv' - to be revised
+        Name.Variable.Class:       "#000000",        # class: 'vc' - to be revised
+        Name.Variable.Global:      "#000000",        # class: 'vg' - to be revised
+        Name.Variable.Instance:    "#000000",        # class: 'vi' - to be revised
+
+        Number:                    "#990000",        # class: 'm'
+
+        Literal:                   "#000000",        # class: 'l'
+        Literal.Date:              "#000000",        # class: 'ld'
+
+        String:                    "#4e9a06",        # class: 's'
+        String.Backtick:           "#4e9a06",        # class: 'sb'
+        String.Char:               "#4e9a06",        # class: 'sc'
+        String.Doc:                "italic #8f5902", # class: 'sd' - like a comment
+        String.Double:             "#4e9a06",        # class: 's2'
+        String.Escape:             "#4e9a06",        # class: 'se'
+        String.Heredoc:            "#4e9a06",        # class: 'sh'
+        String.Interpol:           "#4e9a06",        # class: 'si'
+        String.Other:              "#4e9a06",        # class: 'sx'
+        String.Regex:              "#4e9a06",        # class: 'sr'
+        String.Single:             "#4e9a06",        # class: 's1'
+        String.Symbol:             "#4e9a06",        # class: 'ss'
+
+        Generic:                   "#000000",        # class: 'g'
+        Generic.Deleted:           "#a40000",        # class: 'gd'
+        Generic.Emph:              "italic #000000", # class: 'ge'
+        Generic.Error:             "#ef2929",        # class: 'gr'
+        Generic.Heading:           "bold #000080",   # class: 'gh'
+        Generic.Inserted:          "#00A000",        # class: 'gi'
+        Generic.Output:            "#888",           # class: 'go'
+        Generic.Prompt:            "#745334",        # class: 'gp'
+        Generic.Strong:            "bold #000000",   # class: 'gs'
+        Generic.Subheading:        "bold #800080",   # class: 'gu'
+        Generic.Traceback:         "bold #a40000",   # class: 'gt'
+    }
diff --git a/addons/web/doc/addon-structure.txt b/addons/web/doc/addon-structure.txt
new file mode 100644 (file)
index 0000000..3815174
--- /dev/null
@@ -0,0 +1,12 @@
+<addon name>
+  +-- __openerp__.py
+  +-- controllers/
+  +-- static/
+       +-- lib/
+       +-- src/
+            +-- css/
+            +-- img/
+            +-- js/
+            +-- xml/
+       +-- test/
+  +-- test/
diff --git a/addons/web/doc/async.rst b/addons/web/doc/async.rst
new file mode 100644 (file)
index 0000000..23b3409
--- /dev/null
@@ -0,0 +1,353 @@
+Don't stop the world now: asynchronous development and Javascript
+=================================================================
+
+As a language (and runtime), javascript is fundamentally
+single-threaded. This means any blocking request or computation will
+blocks the whole page (and, in older browsers, the software itself
+even preventing users from switching to an other tab): a javascript
+environment can be seen as an event-based runloop where application
+developers have no control over the runloop itself.
+
+As a result, performing long-running synchronous network requests or
+other types of complex and expensive accesses is frowned upon and
+asynchronous APIs are used instead.
+
+Asynchronous code rarely comes naturally, especially for developers
+used to synchronous server-side code (in Python, Java or C#) where the
+code will just block until the deed is gone. This is increased further
+when asynchronous programming is not a first-class concept and is
+instead implemented on top of callbacks-based programming, which is
+the case in javascript.
+
+The goal of this guide is to provide some tools to deal with
+asynchronous systems, and warn against systematic issues or dangers.
+
+Deferreds
+---------
+
+Deferreds are a form of `promises`_. OpenERP Web currently uses
+`jQuery's deferred`_, but any `CommonJS Promises/A`_ implementation
+should work.
+
+The core idea of deferreds is that potentially asynchronous methods
+will return a :js:class:`Deferred` object instead of an arbitrary
+value or (most commonly) nothing.
+
+This object can then be used to track the end of the asynchronous
+operation by adding callbacks onto it, either success callbacks or
+error callbacks.
+
+A great advantage of deferreds over simply passing callback functions
+directly to asynchronous methods is the ability to :ref:`compose them
+<deferred-composition>`.
+
+Using deferreds
+~~~~~~~~~~~~~~~
+
+`CommonJS Promises/A`_ deferreds have only one method of importance:
+:js:func:`Deferred.then`. This method is used to attach new callbacks
+to the deferred object.
+
+* the first parameter attaches a success callback, called when the
+  deferred object is successfully resolved and provided with the
+  resolved value(s) for the asynchronous operation.
+
+* the second parameter attaches a failure callback, called when the
+  deferred object is rejected and provided with rejection values
+  (often some sort of error message).
+
+Callbacks attached to deferreds are never "lost": if a callback is
+attached to an already resolved or rejected deferred, the callback
+will be called (or ignored) immediately. A deferred is also only ever
+resolved or rejected once, and is either resolved or rejected: a given
+deferred can not call a single success callback twice, or call both a
+success and a failure callbacks.
+
+:js:func:`~Deferred.then` should be the method you'll use most often
+when interacting with deferred objects (and thus asynchronous APIs).
+
+Building deferreds
+~~~~~~~~~~~~~~~~~~
+
+After using asynchronous APIs may come the time to build them: for
+`mocks`_, to compose deferreds from multiple source in a complex
+manner, in order to let the current operations repaint the screen or
+give other events the time to unfold, ...
+
+This is easy using jQuery's deferred objects.
+
+.. note:: this section is an implementation detail of jQuery Deferred
+          objects, the creation of promises is not part of any
+          standard (even tentative) that I know of. If you are using
+          deferred objects which are not jQuery's, their API may (and
+          often will) be completely different.
+
+Deferreds are created by invoking their constructor [#]_ without any
+argument. This creates a :js:class:`Deferred` instance object with the
+following methods:
+
+:js:func:`Deferred.resolve`
+
+    As its name indicates, this method moves the deferred to the
+    "Resolved" state. It can be provided as many arguments as
+    necessary, these arguments will be provided to any pending success
+    callback.
+
+:js:func:`Deferred.reject`
+
+    Similar to :js:func:`~Deferred.resolve`, but moves the deferred to
+    the "Rejected" state and calls pending failure handlers.
+
+:js:func:`Deferred.promise`
+
+    Creates a readonly view of the deferred object. It is generally a
+    good idea to return a promise view of the deferred to prevent
+    callers from resolving or rejecting the deferred in your stead.
+
+:js:func:`~Deferred.reject` and :js:func:`~Deferred.resolve` are used
+to inform callers that the asynchronous operation has failed (or
+succeeded). These methods should simply be called when the
+asynchronous operation has ended, to notify anybody interested in its
+result(s).
+
+.. _deferred-composition:
+
+Composing deferreds
+~~~~~~~~~~~~~~~~~~~
+
+What we've seen so far is pretty nice, but mostly doable by passing
+functions to other functions (well adding functions post-facto would
+probably be a chore... still, doable).
+
+Deferreds truly shine when code needs to compose asynchronous
+operations in some way or other, as they can be used as a basis for
+such composition.
+
+There are two main forms of compositions over deferred: multiplexing
+and piping/cascading.
+
+Deferred multiplexing
+`````````````````````
+
+The most common reason for multiplexing deferred is simply performing
+2+ asynchronous operations and wanting to wait until all of them are
+done before moving on (and executing more stuff).
+
+The jQuery multiplexing function for promises is :js:func:`when`.
+
+.. note:: the multiplexing behavior of jQuery's :js:func:`when` is an
+          (incompatible, mostly) extension of the behavior defined in
+          `CommonJS Promises/B`_.
+
+This function can take any number of promises [#]_ and will return a
+promise.
+
+This returned promise will be resolved when *all* multiplexed promises
+are resolved, and will be rejected as soon as one of the multiplexed
+promises is rejected (it behaves like Python's ``all()``, but with
+promise objects instead of boolean-ish).
+
+The resolved values of the various promises multiplexed via
+:js:func:`when` are mapped to the arguments of :js:func:`when`'s
+success callback, if they are needed. The resolved values of a promise
+are at the same index in the callback's arguments as the promise in
+the :js:func:`when` call so you will have:
+
+.. code-block:: javascript
+
+    $.when(p0, p1, p2, p3).then(
+            function (results0, results1, results2, results3) {
+        // code
+    });
+
+.. warning::
+
+    in a normal mapping, each parameter to the callback would be an
+    array: each promise is conceptually resolved with an array of 0..n
+    values and these values are passed to :js:func:`when`'s
+    callback. But jQuery treats deferreds resolving a single value
+    specially, and "unwraps" that value.
+
+    For instance, in the code block above if the index of each promise
+    is the number of values it resolves (0 to 3), ``results0`` is an
+    empty array, ``results2`` is an array of 2 elements (a pair) but
+    ``results1`` is the actual value resolved by ``p1``, not an array.
+
+Deferred chaining
+`````````````````
+
+A second useful composition is starting an asynchronous operation as
+the result of an other asynchronous operation, and wanting the result
+of both: :js:func:`Deferred.then` returns the deferred on which it was
+called, so handle e.g. OpenERP's search/read sequence with this would
+require something along the lines of:
+
+.. code-block:: javascript
+
+    var result = $.Deferred();
+    Model.search(condition).then(function (ids) {
+        Model.read(ids, fields).then(function (records) {
+            result.resolve(records);
+        });
+    });
+    return result.promise();
+
+While it doesn't look too bad for trivial code, this quickly gets
+unwieldy.
+
+Instead, jQuery provides a tool to handle this kind of chains:
+:js:func:`Deferred.pipe`.
+
+:js:func:`~Deferred.pipe` has the same signature as
+:js:func:`~Deferred.then` and could be used in the same manner
+provided its return value was not used.
+
+It differs from :js:func:`~Deferred.then` in two ways: it returns a
+new promise object, not the one it was called with, and the return
+values of the callbacks is actually important to it: whichever
+callback is called,
+
+* If the callback is not set (not provided or left to null), the
+  resolution or rejection value(s) is simply forwarded to
+  :js:func:`~Deferred.pipe`'s promise (it's essentially a noop)
+
+* If the callback is set and does not return an observable object (a
+  deferred or a promise), the value it returns (``undefined`` if it
+  does not return anything) will replace the value it was given, e.g.
+
+  .. code-block:: javascript
+
+      promise.pipe(function () {
+          console.log('called');
+      });
+
+  will resolve with the sole value ``undefined``.
+
+* If the callback is set and returns an observable object, that object
+  will be the actual resolution (and result) of the pipe. This means a
+  resolved promise from the failure callback will resolve the pipe,
+  and a failure promise from the success callback will reject the
+  pipe.
+
+  This provides an easy way to chain operation successes, and the
+  previous piece of code can now be rewritten:
+
+  .. code-block:: javascript
+
+      return Model.search(condition).pipe(function (ids) {
+          return Model.read(ids, fields);
+      });
+
+  the result of the whole expression will encode failure if either
+  ``search`` or ``read`` fails (with the right rejection values), and
+  will be resolved with ``read``'s resolution values if the chain
+  executes correctly.
+
+:js:func:`~Deferred.pipe` is also useful to adapt third-party
+promise-based APIs, in order to filter their resolution value counts
+for instance (to take advantage of :js:func:`when` 's special treatment
+of single-value promises).
+
+jQuery.Deferred API
+~~~~~~~~~~~~~~~~~~~
+
+.. js:function:: when(deferreds…)
+
+    :param deferreds: deferred objects to multiplex
+    :returns: a multiplexed deferred
+    :rtype: :js:class:`Deferred`
+
+.. js:class:: Deferred
+
+    .. js:function:: Deferred.then(doneCallback[, failCallback])
+
+        Attaches new callbacks to the resolution or rejection of the
+        deferred object. Callbacks are executed in the order they are
+        attached to the deferred.
+
+        To provide only a failure callback, pass ``null`` as the
+        ``doneCallback``, to provide only a success callback the
+        second argument can just be ignored (and not passed at all).
+
+        :param doneCallback: function called when the deferred is resolved
+        :type doneCallback: Function
+        :param failCallback: function called when the deferred is rejected
+        :type failCallback: Function
+        :returns: the deferred object on which it was called
+        :rtype: :js:class:`Deferred`
+
+    .. js:function:: Deferred.done(doneCallback)
+
+        Attaches a new success callback to the deferred, shortcut for
+        ``deferred.then(doneCallback)``.
+
+        This is a jQuery extension to `CommonJS Promises/A`_ providing
+        little value over calling :js:func:`~Deferred.then` directly,
+        it should be avoided.
+
+        :param doneCallback: function called when the deferred is resolved
+        :type doneCallback: Function
+        :returns: the deferred object on which it was called
+        :rtype: :js:class:`Deferred`
+
+    .. js:function:: Deferred.fail(failCallback)
+
+        Attaches a new failure callback to the deferred, shortcut for
+        ``deferred.then(null, failCallback)``.
+
+        A second jQuery extension to `Promises/A <CommonJS
+        Promises/A>`_. Although it provides more value than
+        :js:func:`~Deferred.done`, it still is not much and should be
+        avoided as well.
+
+        :param failCallback: function called when the deferred is rejected
+        :type failCallback: Function
+        :returns: the deferred object on which it was called
+        :rtype: :js:class:`Deferred`
+
+    .. js:function:: Deferred.promise()
+
+        Returns a read-only view of the deferred object, with all
+        mutators (resolve and reject) methods removed.
+
+    .. js:function:: Deferred.resolve(value…)
+
+        Called to resolve a deferred, any value provided will be
+        passed onto the success handlers of the deferred object.
+
+        Resolving a deferred which has already been resolved or
+        rejected has no effect.
+
+    .. js:function:: Deferred.reject(value…)
+
+        Called to reject (fail) a deferred, any value provided will be
+        passed onto the failure handler of the deferred object.
+
+        Rejecting a deferred which has already been resolved or
+        rejected has no effect.
+
+    .. js:function:: Deferred.pipe(doneFilter[, failFilter])
+
+        Filters the result of a deferred, able to transform a success
+        into failure and a failure into success, or to delay
+        resolution further.
+
+.. [#] or simply calling :js:class:`Deferred` as a function, the
+       result is the same
+
+.. [#] or not-promises, the `CommonJS Promises/B`_ role of
+       :js:func:`when` is to be able to treat values and promises
+       uniformly: :js:func:`when` will pass promises through directly,
+       but non-promise values and objects will be transformed into a
+       resolved promise (resolving themselves with the value itself).
+
+       jQuery's :js:func:`when` keeps this behavior making deferreds
+       easy to build from "static" values, or allowing defensive code
+       where expected promises are wrapped in :js:func:`when` just in
+       case.
+
+.. _promises: http://en.wikipedia.org/wiki/Promise_(programming)
+.. _jQuery's deferred: http://api.jquery.com/category/deferred-object/
+.. _CommonJS Promises/A: http://wiki.commonjs.org/wiki/Promises/A
+.. _CommonJS Promises/B: http://wiki.commonjs.org/wiki/Promises/B
+.. _mocks: http://en.wikipedia.org/wiki/Mock_object
diff --git a/addons/web/doc/changelog-7.0.rst b/addons/web/doc/changelog-7.0.rst
new file mode 100644 (file)
index 0000000..00d0236
--- /dev/null
@@ -0,0 +1,108 @@
+API changes from OpenERP Web 6.1 to 7.0
+=======================================
+
+DataSet -> Model
+----------------
+
+The 6.1 ``DataSet`` API has been deprecated in favor of the smaller
+and more orthogonal :doc:`Model </rpc>` API, which more closely
+matches the API in OpenERP Web's Python side and in OpenObject addons
+and removes most stateful behavior of DataSet.
+
+Migration guide
+~~~~~~~~~~~~~~~
+
+* Actual arbitrary RPC calls can just be remapped on a
+  :js:class:`~openerp.web.Model` instance:
+
+  .. code-block:: javascript
+
+      dataset.call(method, args)
+
+  or
+
+  .. code-block:: javascript
+
+      dataset.call_and_eval(method, args)
+
+  can be replaced by calls to :js:func:`openerp.web.Model.call`:
+
+  .. code-block:: javascript
+
+      model.call(method, args)
+
+  If callbacks are passed directly to the older methods, they need to
+  be added to the new one via ``.then()``.
+
+  .. note::
+
+      The ``context_index`` and ``domain_index`` features were not
+      ported, context and domain now need to be passed in "in full",
+      they won't be automatically filled with the user's current
+      context.
+
+* Shorcut methods (``name_get``, ``name_search``, ``unlink``,
+  ``write``, ...) should be ported to
+  :js:func:`openerp.web.Model.call`, using the server's original
+  signature. On the other hand, the non-shortcut equivalents can now
+  use keyword arguments (see :js:func:`~openerp.web.Model.call`'s
+  signature for details)
+
+* ``read_slice``, which allowed a single round-trip to perform a
+  search and a read, should be reimplemented via
+  :js:class:`~openerp.web.Query` objects (see:
+  :js:func:`~openerp.web.Model.query`) for clearer and simpler
+  code. ``read_index`` should be replaced by a
+  :js:class:`~openerp.web.Query` as well, combining
+  :js:func:`~openerp.web.Query.offset` and
+  :js:func:`~openerp.web.Query.first`.
+
+Rationale
+~~~~~~~~~
+
+Renaming
+
+    The name *DataSet* exists in the CS community consciousness, and
+    (as its name implies) it's a set of data (often fetched from a
+    database, maybe lazily). OpenERP Web's dataset behaves very
+    differently as it does not store (much) data (only a bunch of ids
+    and just enough state to break things). The name "Model" matches
+    the one used on the Python side for the task of building an RPC
+    proxy to OpenERP objects.
+
+API simplification
+
+    ``DataSet`` has a number of methods which serve as little more
+    than shortcuts, or are there due to domain and context evaluation
+    issues in 6.1.
+
+    The shortcuts really add little value, and OpenERP Web 6.2 embeds
+    a restricted Python evaluator (in javascript) meaning most of the
+    context and domain parsing & evaluation can be moved to the
+    javascript code and does not require cooperative RPC bridging.
+
+DataGroup -> also Model
+-----------------------
+
+Alongside the deprecation of ``DataSet`` for
+:js:class:`~openerp.web.Model`, OpenERP Web 7.0 also deprecates
+``DataGroup`` and its subtypes in favor of a single method on
+:js:class:`~openerp.web.Query`:
+:js:func:`~openerp.web.Query.group_by`.
+
+Migration guide
+~~~~~~~~~~~~~~~
+
+Rationale
+~~~~~~~~~
+
+While the ``DataGroup`` API worked (mostly), it is quite odd and
+alien-looking, a bit too Smalltalk-inspired (behaves like a
+self-contained flow-control structure for reasons which may or may not
+have been good).
+
+Because it is heavily related to ``DataSet`` (as it *yields*
+``DataSet`` objects), deprecating ``DataSet`` automatically deprecates
+``DataGroup`` (if we want to stay consistent), which is a good time to
+make the API more imperative and look more like what most developers
+are used to.
diff --git a/addons/web/doc/conf.py b/addons/web/doc/conf.py
new file mode 100644 (file)
index 0000000..83fc969
--- /dev/null
@@ -0,0 +1,257 @@
+# -*- coding: utf-8 -*-
+#
+# OpenERP Technical Documentation configuration file, created by
+# sphinx-quickstart on Fri Feb 17 16:14:06 2012.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+sys.path.append(os.path.abspath('_themes'))
+sys.path.insert(0, os.path.abspath('../addons'))
+sys.path.insert(0, os.path.abspath('..'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'OpenERP Web Developers Documentation'
+copyright = u'2012, OpenERP s.a.'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '7.0'
+# The full version, including alpha/beta/rc tags.
+release = '7.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'flask'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+html_theme_path = ['_themes']
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+html_sidebars = {
+    'index':    ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'],
+    '**':       ['sidebarlogo.html', 'localtoc.html', 'relations.html',
+                 'sourcelink.html', 'searchbox.html']
+}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'openerp-web-doc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'openerp-web-doc.tex', u'OpenERP Web Developers Documentation',
+   u'OpenERP s.a.', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'openerp-web-doc', u'OpenERP Web Developers Documentation',
+     [u'OpenERP s.a.'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output ------------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+  ('index', 'OpenERPWebDocumentation', u'OpenERP Web Developers Documentation',
+   u'OpenERP s.a.', 'OpenERPWebDocumentation', 'Developers documentation for the openerp-web project.',
+   'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+todo_include_todos = True
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {
+    'python': ('http://docs.python.org/', None),
+    'openerpserver': ('http://doc.openerp.com/trunk/developers/server', None),
+    'openerpdev': ('http://doc.openerp.com/trunk/developers', None),
+}
diff --git a/addons/web/doc/form-notes.rst b/addons/web/doc/form-notes.rst
new file mode 100644 (file)
index 0000000..98d4a4d
--- /dev/null
@@ -0,0 +1,55 @@
+Notes on the usage of the Form View as a sub-widget
+===================================================
+
+Undocumented stuff
+------------------
+
+* ``initial_mode`` *option* defines the starting mode of the form
+  view, one of ``view`` and ``edit`` (?). Default value is ``view``
+  (non-editable form).
+
+* ``embedded_view`` *attribute* has to be set separately when
+  providing a view directly, no option available for that usage.
+
+  * View arch **must** contain node with
+    ``@class="oe_form_container"``, otherwise everything will break
+    without any info
+
+  * Root element of view arch not being ``form`` may or may not work
+    correctly, no idea.
+
+  * Freeform views => ``@version="7.0"``
+
+* Form is not entirely loaded (some widgets may not appear) unless
+  ``on_record_loaded`` is called (or ``do_show``, which itself calls
+  ``on_record_loaded``).
+
+* "Empty" form => ``on_button_new`` (...), or manually call
+  ``default_get`` + ``on_record_loaded``
+
+* Form fields default to width: 100%, padding, !important margin, can
+  be reached via ``.oe_form_field``
+
+* Form *will* render buttons and a pager, offers options to locate
+  both outside of form itself (``$buttons`` and ``$pager``), providing
+  empty jquery objects (``$()``) seems to stop displaying both but not
+  sure if there are deleterious side-effects.
+
+  Other options:
+
+  * Pass in ``$(document.createDocumentFragment)`` to ensure it's a
+    DOM-compatible tree completely outside of the actual DOM.
+
+  * ???
+
+* readonly fields probably don't have a background, beware if need of
+  overlay
+
+  * What is the difference between ``readonly`` and
+    ``effective_readonly``?
+
+* No facilities for DOM events handling/delegations e.g. handling
+  keyup/keydown/keypress from a form fields into the form's user.
+
+  * Also no way to reverse from a DOM node (e.g. DOMEvent#target) back to a
+    form view field easily
diff --git a/addons/web/doc/guides/client-action.rst b/addons/web/doc/guides/client-action.rst
new file mode 100644 (file)
index 0000000..30f0c7e
--- /dev/null
@@ -0,0 +1,112 @@
+.. highlight:: javascript
+
+Creating a new client action
+============================
+
+Client actions are the client-side version of OpenERP's "Server
+Actions": instead of allowing for semi-arbitrary code to be executed
+in the server, they allow for execution of client-customized code.
+
+On the server side, a client action is an action of type
+``ir.actions.client``, which has (at most) two properties: a mandatory
+``tag``, which is an arbitrary string by which the client will
+identify the action, and an optional ``params`` which is simply a map
+of keys and values sent to the client as-is (this way, client actions
+can be made generic and reused in multiple contexts).
+
+General Structure
+-----------------
+
+In the OpenERP Web code, a client action only requires two pieces of
+information:
+
+* Mapping the action's ``tag`` to an object
+
+* Providing said object. Two different types of objects can be mapped
+  to a client action:
+
+  * An OpenERP Web widget, which must inherit from
+    :js:class:`openerp.web.Widget`
+
+  * A regular javascript function
+
+The major difference is in the lifecycle of these:
+
+* if the client action maps to a function, the function will simply be
+  called when executing the action. The function can have no further
+  interaction with the Web Client itself, although it can return an
+  action which will be executed after it.
+
+* if, on the other hand, the client action maps to a
+  :js:class:`~openerp.web.Widget`, that
+  :js:class:`~openerp.web.Widget` will be instantiated and added to
+  the web client's canvas, with the usual
+  :js:class:`~openerp.web.Widget` lifecycle (essentially, it will
+  either take over the content area of the client or it will be
+  integrated within a dialog).
+
+For example, to create a client action displaying a ``res.widget``
+object::
+
+    // Registers the object 'openerp.web_dashboard.Widget' to the client
+    // action tag 'board.home.widgets'
+    instance.web.client_actions.add(
+        'board.home.widgets', 'openerp.web_dashboard.Widget');
+    instance.web_dashboard.Widget = instance.web.Widget.extend({
+        template: 'HomeWidget'
+    });
+
+At this point, the generic :js:class:`~openerp.web.Widget` lifecycle
+takes over, the template is rendered, inserted in the client DOM,
+bound on the object's ``$el`` property and the object is started.
+
+If the client action takes parameters, these parameters are passed in as a
+second positional parameter to the constructor::
+
+    init: function (parent, params) {
+        // execute the Widget's init
+        this._super(parent);
+        // board.home.widgets only takes a single param, the identifier of the
+        // res.widget object it should display. Store it for later
+        this.widget_id = params.widget_id;
+    }
+
+More complex initialization (DOM manipulations, RPC requests, ...)
+should be performed in the :js:func:`~openerp.web.Widget.start()`
+method.
+
+.. note::
+
+    As required by :js:class:`~openerp.web.Widget`'s contract, if
+    :js:func:`~openerp.web.Widget.start()` executes any asynchronous
+    code it should return a ``$.Deferred`` so callers know when it's
+    ready for interaction.
+
+    Although generally speaking client actions are not really
+    interacted with.
+
+.. code-block:: javascript
+
+    start: function () {
+        return $.when(
+            this._super(),
+            // Simply read the res.widget object this action should display
+            new instance.web.Model('res.widget').call(
+                'read', [[this.widget_id], ['title']])
+                .then(this.proxy('on_widget_loaded'));
+    }
+
+The client action can then behave exactly as it wishes to within its
+root (``this.$el``). In this case, it performs further renderings once
+its widget's content is retrieved::
+
+    on_widget_loaded: function (widgets) {
+        var widget = widgets[0];
+        var url = _.sprintf(
+            '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
+            this.session.session_id, widget.id);
+        this.$el.html(QWeb.render('HomeWidget.content', {
+            widget: widget,
+            url: url
+        }));
+    }
diff --git a/addons/web/doc/index.rst b/addons/web/doc/index.rst
new file mode 100644 (file)
index 0000000..6a0d8de
--- /dev/null
@@ -0,0 +1,32 @@
+.. OpenERP Web documentation master file, created by
+   sphinx-quickstart on Fri Mar 18 16:31:55 2011.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to OpenERP Web's documentation!
+=======================================
+
+Contents:
+
+.. toctree::
+    :maxdepth: 1
+
+    changelog-7.0
+
+    async
+    rpc
+
+    widget
+    search-view
+
+    list-view
+    form-notes
+
+    guides/client-action
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/addons/web/doc/list-view.rst b/addons/web/doc/list-view.rst
new file mode 100644 (file)
index 0000000..b7cdc1c
--- /dev/null
@@ -0,0 +1,531 @@
+List View
+=========
+
+Style Hooks
+-----------
+
+The list view provides a few style hook classes for re-styling of list views in
+various situations:
+
+``.oe_list``
+
+    The root element of the list view, styling rules should be rooted
+    on that class.
+
+``table.oe_list_content``
+
+    The root table for the listview, accessory components may be
+    generated or added outside this section, this is the list view
+    "proper".
+
+``.oe_list_buttons``
+
+    The action buttons array for the list view, with its sub-elements
+
+    ``.oe_list_add``
+
+        The default "Create"/"Add" button of the list view
+
+    ``.oe_alternative``
+
+        The "alternative choice" for the list view, by default text
+        along the lines of "or import" with a link.
+
+``.oe_list_field_cell``
+
+    The cell (``td``) for a given field of the list view, cells which
+    are *not* fields (e.g. name of a group, or number of items in a
+    group) will not have this class. The field cell can be further
+    specified:
+
+    ``.oe_number``
+
+        Numeric cell types (integer and float)
+
+    ``.oe_button``
+
+        Action button (``button`` tag in the view) inside the cell
+
+    ``.oe_readonly``
+
+        Readonly field cell
+
+    ``.oe_list_field_$type``
+
+        Additional class for the precise type of the cell, ``$type``
+        is the field's @widget if there is one, otherwise it's the
+        field's type.
+
+``.oe_list_record_selector``
+
+    Selector cells
+
+Editable list view
+++++++++++++++++++
+
+The editable list view module adds a few supplementary style hook
+classes, for edition situations:
+
+``.oe_list_editable``
+
+    Added to the ``.oe_list`` when the list is editable (however that
+    was done). The class may be removed on-the-fly if the list becomes
+    non-editable.
+
+``.oe_editing``
+
+    Added to both ``.oe_list`` and ``.oe_list_button`` (as the
+    buttons may be outside of the list view) when a row of the list is
+    currently being edited.
+
+``tr.oe_edition``
+
+    Class set on the row being edited itself. Note that the edition
+    form is *not* contained within the row, this allows for styling or
+    modifying the row while it's being edited separately. Mostly for
+    fields which can not be edited (e.g. read-only fields).
+
+Columns display customization
+-----------------------------
+
+The list view provides a registry to
+:js:class:`openerp.web.list.Column` objects allowing for the
+customization of a column's display (e.g. so that a binary field is
+rendered as a link to the binary file directly in the list view).
+
+The registry is ``instance.web.list.columns``, the keys are of the
+form ``tag.type`` where ``tag`` can be ``field`` or ``button``, and
+``type`` can be either the field's type or the field's ``@widget`` (in
+the view).
+
+Most of the time, you'll want to define a ``tag.widget`` key
+(e.g. ``field.progressbar``).
+
+.. js:class:: openerp.web.list.Column(id, tag, attrs)
+
+    .. js:function:: openerp.web.list.Column.format(record_data, options)
+
+        Top-level formatting method, returns an empty string if the
+        column is invisible (unless the ``process_modifiers=false``
+        option is provided); returns ``options.value_if_empty`` or an
+        empty string if there is no value in the record for the
+        column.
+
+        Otherwise calls :js:func:`~openerp.web.list.Column._format`
+        and returns its result.
+
+        This method only needs to be overridden if the column has no
+        concept of values (and needs to bypass that check), for a
+        button for instance.
+
+        Otherwise, custom columns should generally override
+        :js:func:`~openerp.web.list.Column._format` instead.
+
+        :returns: String
+
+    .. js:function:: openerp.web.list.Column._format(record_data, options)
+
+        Never called directly, called if the column is visible and has
+        a value.
+
+        The default implementation calls
+        :js:func:`~openerp.web.format_value` and htmlescapes the
+        result (via ``_.escape``).
+
+        Note that the implementation of
+        :js:func:`~openerp.web.list.Column._format` *must* escape the
+        data provided to it, its output will *not* be escaped by
+        :js:func:`~openerp.web.list.Column.format`.
+
+        :returns: String
+
+Editable list view
+------------------
+
+List view edition is an extension to the base listview providing the
+capability of inline record edition by delegating to an embedded form
+view.
+
+Editability status
+++++++++++++++++++
+
+The editability status of a list view can be queried through the
+:js:func:`~openerp.web.ListView.editable` method, will return a falsy
+value if the listview is not currently editable.
+
+The editability status is based on three flags:
+
+``tree/@editable``
+
+    If present, can be either ``"top"`` or ``"bottom"``. Either will
+    make the list view editable, with new records being respectively
+    created at the top or at the bottom of the view.
+
+``context.set_editable``
+
+    Boolean flag extracted from a search context (during the
+    :js:func:`~openerp.web.ListView.do_search`` handler), ``true``
+    will make the view editable (from the top), ``false`` or the
+    absence of the flag is a noop.
+
+``defaults.editable``
+
+    Like ``tree/@editable``, one of absent (``null``)), ``"top"`` or
+    ``"bottom"``, fallback for the list view if none of the previous
+    two flags are set.
+
+These three flags can only *make* a listview editable, they can *not*
+override a previously set flag. To do that, a listview user should
+instead cancel :ref:`the edit:before event <listview-edit-before>`.
+
+The editable list view module adds a number of methods to the list
+view, on top of implementing the :js:class:`EditorDelegate` protocol:
+
+Interaction Methods
++++++++++++++++++++
+
+.. js:function:: openerp.web.ListView.ensure_saved
+
+    Attempts to resolve the pending edition, if any, by saving the
+    edited row's current state.
+
+    :returns: delegate resolving to all editions having been saved, or
+              rejected if a pending edition could not be saved
+              (e.g. validation failure)
+
+.. js:function:: openerp.web.ListView.start_edition([record][, options])
+
+    Starts editing the provided record inline, through an overlay form
+    view of editable fields in the record.
+
+    If no record is provided, creates a new one according to the
+    editability configuration of the list view.
+
+    This method resolves any pending edition when invoked, before
+    starting a new edition.
+
+    :param record: record to edit, or null to create a new record
+    :type record: :js:class:`~openerp.web.list.Record`
+    :param EditOptions options:
+    :returns: delegate to the form used for the edition
+
+.. js:function:: openerp.web.ListView.save_edition
+
+    Resolves the pending edition.
+
+    :returns: delegate to the save being completed, resolves to an
+              object with two attributes ``created`` (flag indicating
+              whether the saved record was just created or was
+              updated) and ``record`` the reloaded record having been
+              edited.
+
+.. js:function:: openerp.web.ListView.cancel_edition([force=false])
+
+    Cancels pending edition, cleans up the list view in case of
+    creation (removes the empty record being created).
+
+    :param Boolean force: doesn't check if the user has added any
+                          data, discards the edition unconditionally
+
+Utility Methods
++++++++++++++++
+
+.. js:function:: openerp.web.ListView.get_cells_for(row)
+
+    Extracts the cells from a listview row, and puts them in a
+    {fieldname: cell} mapping for analysis and manipulation.
+
+    :param jQuery row:
+    :rtype: Object
+
+.. js:function:: openerp.web.ListView.with_event(event_name, event, action[, args][, trigger_params])
+
+    Executes ``action`` in the context of the view's editor,
+    bracketing it with cancellable event signals.
+
+    :param String event_name: base name for the bracketing event, will
+                              be postfixed by ``:before`` and
+                              ``:after`` before being called
+                              (respectively before and after
+                              ``action`` is executed)
+    :param Object event: object passed to the ``:before`` event
+                         handlers.
+    :param Function action: function called with the view's editor as
+                            its ``this``. May return a deferred.
+    :param Array args: arguments passed to ``action``
+    :param Array trigger_params: arguments passed to the ``:after``
+                                 event handler alongside the results
+                                 of ``action``
+
+Behavioral Customizations
++++++++++++++++++++++++++
+
+.. js:function:: openerp.web.ListView.handle_onwrite(record)
+
+    Implements the handling of the ``onwrite`` listview attribute:
+    calls the RPC methods specified by ``@onwrite``, and if that
+    method returns an array of ids loads or reloads the records
+    corresponding to those ids.
+
+    :param record: record being written having triggered the
+                   ``onwrite`` callback
+    :type record: openerp.web.list.Record
+    :returns: deferred to all reloadings being done
+
+Events
+++++++
+
+For simpler interactions by/with external users of the listview, the
+view provides a number of dedicated events to its lifecycle.
+
+.. note:: if an event is defined as *cancellable*, it means its first
+          parameter is an object on which the ``cancel`` attribute can
+          be set. If the ``cancel`` attribute is set, the view will
+          abort its current behavior as soon as possible, and rollback
+          any state modification.
+
+          Generally speaking, an event should only be cancelled (by
+          setting the ``cancel`` flag to ``true``), uncancelling an
+          event is undefined as event handlers are executed on a
+          first-come-first-serve basis and later handlers may
+          re-cancel an uncancelled event.
+
+.. _listview-edit-before:
+
+``edit:before`` *cancellable*
+
+    Invoked before the list view starts editing a record.
+
+    Provided with an event object with a single property ``record``,
+    holding the attributes of the record being edited (``record`` is
+    empty *but not null* for a new record)
+
+``edit:after``
+
+    Invoked after the list view has gone into an edition state,
+    provided with the attributes of the record being edited (see
+    ``edit:before``) as first parameter and the form used for the
+    edition as second parameter.
+
+``save:before`` *cancellable*
+
+    Invoked right before saving a pending edition, provided with an
+    event object holding the listview's editor (``editor``) and the
+    edition form (``form``)
+
+``save:after``
+
+    Invoked after a save has been completed
+
+``cancel:before`` *cancellable*
+
+    Invoked before cancelling a pending edition, provided with the
+    same information as ``save:before``.
+
+``cancel:after``
+
+    Invoked after a pending edition has been cancelled.
+
+DOM events
+++++++++++
+
+The list view has grown hooks for the ``keyup`` event on its edition
+form (during edition): any such event bubbling out of the edition form
+will be forwarded to a method ``keyup_EVENTNAME``, where ``EVENTNAME``
+is the name of the key in ``$.ui.keyCode``.
+
+The method will also get the event object (originally passed to the
+``keyup`` handler) as its sole parameter.
+
+The base editable list view has handlers for the ``ENTER`` and
+``ESCAPE`` keys.
+
+Editor
+------
+
+The list-edition modules does not generally interact with the embedded
+formview, delegating instead to its
+:js:class:`~openerp.web.list.Editor`.
+
+.. js:class:: openerp.web.list.Editor(parent[, options])
+
+    The editor object provides a more convenient interface to form
+    views, and simplifies the usage of form views for semi-arbitrary
+    edition of stuff.
+
+    However, the editor does *not* task itself with being internally
+    consistent at this point: calling
+    e.g. :js:func:`~openerp.web.list.Editor.edit` multiple times in a
+    row without saving or cancelling each edit is undefined.
+
+    :param parent:
+    :type parent: :js:class:`~openerp.web.Widget`
+    :param EditorOptions options:
+
+    .. js:function:: openerp.web.list.Editor.is_editing([record_state])
+
+        Indicates whether the editor is currently in the process of
+        providing edition for a record.
+
+        Can be filtered by the state of the record being edited
+        (whether it's a record being *created* or a record being
+        *altered*), in which case it asserts both that an edition is
+        underway and that the record being edited respectively does
+        not yet exist in the database or already exists there.
+
+        :param record_state: state of the record being edited.
+                             Either ``"new"`` or ``"edit"``.
+        :type record_state: String
+        :rtype: Boolean
+
+    .. js:function:: openerp.web.list.Editor.edit(record, configureField[, options])
+
+        Loads the provided record into the internal form view and
+        displays the form view.
+
+        Will also attempt to focus the first visible field of the form
+        view.
+
+        :param Object record: record to load into the form view
+                              (key:value mapping similar to the result
+                              of a ``read``)
+        :param configureField: function called with each field of the
+                               form view right after the form is
+                               displayed, lets whoever called this
+                               method do some last-minute
+                               configuration of form fields.
+        :type configureField: Function<String, openerp.web.form.Field>
+        :param EditOptions options:
+        :returns: jQuery delegate to the form object
+
+    .. js:function:: openerp.web.list.Editor.save
+
+        Attempts to save the internal form, then hide it
+
+        :returns: delegate to the record under edition (with ``id``
+                  added for a creation). The record is not updated
+                  from when it was passed in, aside from the ``id``
+                  attribute.
+
+    .. js:function:: openerp.web.list.Editor.cancel([force=false])
+
+        Attemps to cancel the edition of the internal form, then hide
+        the form
+
+        :param Boolean force: unconditionally cancels the edition of
+                              the internal form, even if the user has
+                              already entered data in it.
+        :returns: delegate to the record under edition
+
+.. js:class:: EditorOptions
+
+    .. js:attribute:: EditorOptions.formView
+
+        Form view (sub)-class to instantiate and delegate edition to.
+
+        By default, :js:class:`~openerp.web.FormView`
+
+    .. js:attribute:: EditorOptions.delegate
+
+        Object used to get various bits of information about how to
+        display stuff.
+
+        By default, uses the editor's parent widget. See
+        :js:class:`EditorDelegate` for the methods and attributes to
+        provide.
+
+.. js:class:: EditorDelegate
+
+    Informal protocol defining the methods and attributes expected of
+    the :js:class:`~openerp.web.list.Editor`'s delegate.
+
+    .. js:attribute:: EditorDelegate.dataset
+
+        The dataset passed to the form view to synchronize the form
+        view and the outer widget.
+
+    .. js:function:: EditorDelegate.edition_view(editor)
+
+        Called by the :js:class:`~openerp.web.list.Editor` object to
+        get a form view (JSON) to pass along to the form view it
+        created.
+
+        The result should be a valid form view, see :doc:`Form Notes
+        <form-notes>` for various peculiarities of the form view
+        format.
+
+        :param editor: editor object asking for the view
+        :type editor: :js:class:`~openerp.web.list.Editor`
+        :returns: form view
+        :rtype: Object
+
+    .. js:function:: EditorDelegate.prepends_on_create
+
+        By default, the :js:class:`~openerp.web.list.Editor` will
+        append the ids of newly created records to the
+        :js:attr:`EditorDelegate.dataset`. If this method returns
+        ``true``, it will prepend these ids instead.
+
+        :returns: whether new records should be prepended to the
+                  dataset (instead of appended)
+        :rtype: Boolean
+
+
+.. js:class:: EditOptions
+
+    Options object optionally passed into a method starting an edition
+    to configure its setup and behavior
+
+    .. js:attribute:: focus_field
+
+        Name of the field to set focus on after setting up the edition
+        of the record.
+
+        If this option is not provided, or the requested field can not
+        be focused (invisible, readonly or not in the view), the first
+        visible non-readonly field is focused.
+
+Changes from 6.1
+----------------
+
+* The editable listview behavior has been rewritten pretty much from
+  scratch, any code touching on editability will have to be modified
+
+  * The overloading of :js:class:`~openerp.web.ListView.Groups` and
+    :js:class:`~openerp.web.ListView.List` for editability has been
+    drastically simplified, and most of the behavior has been moved to
+    the list view itself. Only
+    :js:func:`~openerp.web.ListView.List.row_clicked` is still
+    overridden.
+
+  * A new method ``get_row_for(record) -> jQuery(tr) | null`` has been
+    added to both ListView.List and ListView.Group, it can be called
+    from the list view to get the table row matching a record (if such
+    a row exists).
+
+* :js:func:`~openerp.web.ListView.do_button_action`'s core behavior
+  has been split away to
+  :js:func:`~openerp.web.ListView.handle_button`. This allows bypassing
+  overrides of :js:func:`~openerp.web.ListView.do_button_action` in a
+  parent class.
+
+  Ideally, :js:func:`~openerp.web.ListView.handle_button` should not be
+  overridden.
+
+* Modifiers handling has been improved (all modifiers information
+  should now be available through :js:func:`~Column.modifiers_for`,
+  not just ``invisible``)
+
+* Changed some handling of the list view's record: a record may now
+  have no id, and the listview will handle that correctly (for new
+  records being created) as well as correctly handle the ``id`` being
+  set.
+
+* Extended the internal collections structure of the list view with
+  `#find`_, `#succ`_ and `#pred`_.
+
+.. _#find: http://underscorejs.org/#find
+
+.. _#succ: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:succ
+
+.. _#pred: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:pred
diff --git a/addons/web/doc/make.bat b/addons/web/doc/make.bat
new file mode 100644 (file)
index 0000000..3e72cad
--- /dev/null
@@ -0,0 +1,170 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+       set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+       set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+       :help
+       echo.Please use `make ^<target^>` where ^<target^> is one of
+       echo.  html       to make standalone HTML files
+       echo.  dirhtml    to make HTML files named index.html in directories
+       echo.  singlehtml to make a single large HTML file
+       echo.  pickle     to make pickle files
+       echo.  json       to make JSON files
+       echo.  htmlhelp   to make HTML files and a HTML help project
+       echo.  qthelp     to make HTML files and a qthelp project
+       echo.  devhelp    to make HTML files and a Devhelp project
+       echo.  epub       to make an epub
+       echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+       echo.  text       to make text files
+       echo.  man        to make manual pages
+       echo.  changes    to make an overview over all changed/added/deprecated items
+       echo.  linkcheck  to check all external links for integrity
+       echo.  doctest    to run all doctests embedded in the documentation if enabled
+       goto end
+)
+
+if "%1" == "clean" (
+       for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+       del /q /s %BUILDDIR%\*
+       goto end
+)
+
+if "%1" == "html" (
+       %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+       goto end
+)
+
+if "%1" == "dirhtml" (
+       %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+       goto end
+)
+
+if "%1" == "singlehtml" (
+       %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+       goto end
+)
+
+if "%1" == "pickle" (
+       %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished; now you can process the pickle files.
+       goto end
+)
+
+if "%1" == "json" (
+       %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished; now you can process the JSON files.
+       goto end
+)
+
+if "%1" == "htmlhelp" (
+       %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+       goto end
+)
+
+if "%1" == "qthelp" (
+       %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+       echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenERPWeb.qhcp
+       echo.To view the help file:
+       echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenERPWeb.ghc
+       goto end
+)
+
+if "%1" == "devhelp" (
+       %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished.
+       goto end
+)
+
+if "%1" == "epub" (
+       %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished. The epub file is in %BUILDDIR%/epub.
+       goto end
+)
+
+if "%1" == "latex" (
+       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+       goto end
+)
+
+if "%1" == "text" (
+       %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished. The text files are in %BUILDDIR%/text.
+       goto end
+)
+
+if "%1" == "man" (
+       %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Build finished. The manual pages are in %BUILDDIR%/man.
+       goto end
+)
+
+if "%1" == "changes" (
+       %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.The overview file is in %BUILDDIR%/changes.
+       goto end
+)
+
+if "%1" == "linkcheck" (
+       %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+       goto end
+)
+
+if "%1" == "doctest" (
+       %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+       if errorlevel 1 exit /b 1
+       echo.
+       echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+       goto end
+)
+
+:end
diff --git a/addons/web/doc/rpc.rst b/addons/web/doc/rpc.rst
new file mode 100644 (file)
index 0000000..4787978
--- /dev/null
@@ -0,0 +1,276 @@
+Outside the box: network interactions
+=====================================
+
+Building static displays is all nice and good and allows for neat
+effects (and sometimes you're given data to display from third parties
+so you don't have to make any effort), but a point generally comes
+where you'll want to talk to the world and make some network requests.
+
+OpenERP Web provides two primary APIs to handle this, a low-level
+JSON-RPC based API communicating with the Python section of OpenERP
+Web (and of your addon, if you have a Python part) and a high-level
+API above that allowing your code to talk directly to the OpenERP
+server, using familiar-looking calls.
+
+All networking APIs are :doc:`asynchronous </async>`. As a result, all
+of them will return :js:class:`Deferred` objects (whether they resolve
+those with values or not). Understanding how those work before before
+moving on is probably necessary.
+
+High-level API: calling into OpenERP models
+-------------------------------------------
+
+Access to OpenERP object methods (made available through XML-RPC from
+the server) is done via the :js:class:`openerp.web.Model` class. This
+class maps onto the OpenERP server objects via two primary methods,
+:js:func:`~openerp.web.Model.call` and
+:js:func:`~openerp.web.Model.query`.
+
+:js:func:`~openerp.web.Model.call` is a direct mapping to the
+corresponding method of the OpenERP server object. Its usage is
+similar to that of the OpenERP Model API, with three differences:
+
+* The interface is :doc:`asynchronous </async>`, so instead of
+  returning results directly RPC method calls will return
+  :js:class:`Deferred` instances, which will themselves resolve to the
+  result of the matching RPC call.
+
+* Because ECMAScript 3/Javascript 1.5 doesnt feature any equivalent to
+  ``__getattr__`` or ``method_missing``, there needs to be an explicit
+  method to dispatch RPC methods.
+
+* No notion of pooler, the model proxy is instantiated where needed,
+  not fetched from an other (somewhat global) object
+
+.. code-block:: javascript
+
+    var Users = new Model('res.users');
+
+    Users.call('change_password', ['oldpassword', 'newpassword'],
+                      {context: some_context}).then(function (result) {
+        // do something with change_password result
+    });
+
+:js:func:`~openerp.web.Model.query` is a shortcut for a builder-style
+interface to searches (``search`` + ``read`` in OpenERP RPC terms). It
+returns a :js:class:`~openerp.web.Query` object which is immutable but
+allows building new :js:class:`~openerp.web.Query` instances from the
+first one, adding new properties or modifiying the parent object's:
+
+.. code-block:: javascript
+
+    Users.query(['name', 'login', 'user_email', 'signature'])
+         .filter([['active', '=', true], ['company_id', '=', main_company]])
+         .limit(15)
+         .all().then(function (users) {
+        // do work with users records
+    });
+
+The query is only actually performed when calling one of the query
+serialization methods, :js:func:`~openerp.web.Query.all` and
+:js:func:`~openerp.web.Query.first`. These methods will perform a new
+RPC call every time they are called.
+
+For that reason, it's actually possible to keep "intermediate" queries
+around and use them differently/add new specifications on them.
+
+.. js:class:: openerp.web.Model(name)
+
+    .. js:attribute:: openerp.web.Model.name
+
+        name of the OpenERP model this object is bound to
+
+    .. js:function:: openerp.web.Model.call(method[, args][, kwargs])
+
+         Calls the ``method`` method of the current model, with the
+         provided positional and keyword arguments.
+
+         :param String method: method to call over rpc on the
+                               :js:attr:`~openerp.web.Model.name`
+         :param Array<> args: positional arguments to pass to the
+                              method, optional
+         :param Object<> kwargs: keyword arguments to pass to the
+                                 method, optional
+         :rtype: Deferred<>         
+
+    .. js:function:: openerp.web.Model.query(fields)
+
+         :param Array<String> fields: list of fields to fetch during
+                                      the search
+         :returns: a :js:class:`~openerp.web.Query` object
+                   representing the search to perform
+
+.. js:class:: openerp.web.Query(fields)
+
+    The first set of methods is the "fetching" methods. They perform
+    RPC queries using the internal data of the object they're called
+    on.
+
+    .. js:function:: openerp.web.Query.all()
+
+        Fetches the result of the current
+        :js:class:`~openerp.web.Query` object's search.
+
+        :rtype: Deferred<Array<>>
+
+    .. js:function:: openerp.web.Query.first()
+
+       Fetches the **first** result of the current
+       :js:class:`~openerp.web.Query`, or ``null`` if the current
+       :js:class:`~openerp.web.Query` does have any result.
+
+       :rtype: Deferred<Object | null>
+
+    .. js:function:: openerp.web.Query.count()
+
+       Fetches the number of records the current
+       :js:class:`~openerp.web.Query` would retrieve.
+
+       :rtype: Deferred<Number>
+
+    .. js:function:: openerp.web.Query.group_by(grouping...)
+
+       Fetches the groups for the query, using the first specified
+       grouping parameter
+
+       :param Array<String> grouping: Lists the levels of grouping
+                                      asked of the server. Grouping
+                                      can actually be an array or
+                                      varargs.
+       :rtype: Deferred<Array<openerp.web.QueryGroup>> | null
+
+    The second set of methods is the "mutator" methods, they create a
+    **new** :js:class:`~openerp.web.Query` object with the relevant
+    (internal) attribute either augmented or replaced.
+
+    .. js:function:: openerp.web.Query.context(ctx)
+
+       Adds the provided ``ctx`` to the query, on top of any existing
+       context
+
+    .. js:function:: openerp.web.Query.filter(domain)
+
+       Adds the provided domain to the query, this domain is
+       ``AND``-ed to the existing query domain.
+
+    .. js:function:: opeenrp.web.Query.offset(offset)
+
+       Sets the provided offset on the query. The new offset
+       *replaces* the old one.
+
+    .. js:function:: openerp.web.Query.limit(limit)
+
+       Sets the provided limit on the query. The new limit *replaces*
+       the old one.
+
+    .. js:function:: openerp.web.Query.order_by(fields…)
+
+       Overrides the model's natural order with the provided field
+       specifications. Behaves much like Django's `QuerySet.order_by
+       <https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by>`_:
+
+       * Takes 1..n field names, in order of most to least importance
+         (the first field is the first sorting key). Fields are
+         provided as strings.
+
+       * A field specifies an ascending order, unless it is prefixed
+         with the minus sign "``-``" in which case the field is used
+         in the descending order
+
+       Divergences from Django's sorting include a lack of random sort
+       (``?`` field) and the inability to "drill down" into relations
+       for sorting.
+
+Aggregation (grouping)
+~~~~~~~~~~~~~~~~~~~~~~
+
+OpenERP has powerful grouping capacities, but they are kind-of strange
+in that they're recursive, and level n+1 relies on data provided
+directly by the grouping at level n. As a result, while ``read_group``
+works it's not a very intuitive API.
+
+OpenERP Web 7.0 eschews direct calls to ``read_group`` in favor of
+calling a method of :js:class:`~openerp.web.Query`, `much in the way
+it is one in SQLAlchemy
+<http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.group_by>`_ [#]_:
+
+.. code-block:: javascript
+
+    some_query.group_by(['field1', 'field2']).then(function (groups) {
+        // do things with the fetched groups
+    });
+
+This method is asynchronous when provided with 1..n fields (to group
+on) as argument, but it can also be called without any field (empty
+fields collection or nothing at all). In this case, instead of
+returning a Deferred object it will return ``null``.
+
+When grouping criterion come from a third-party and may or may not
+list fields (e.g. could be an empty list), this provides two ways to
+test the presence of actual subgroups (versus the need to perform a
+regular query for records):
+
+* A check on ``group_by``'s result and two completely separate code
+  paths
+
+  .. code-block:: javascript
+
+      var groups;
+      if (groups = some_query.group_by(gby)) {
+          groups.then(function (gs) {
+              // groups
+          });
+      }
+      // no groups
+
+* Or a more coherent code path using :js:func:`when`'s ability to
+  coerce values into deferreds:
+
+  .. code-block:: javascript
+
+      $.when(some_query.group_by(gby)).then(function (groups) {
+          if (!groups) {
+              // No grouping
+          } else {
+              // grouping, even if there are no groups (groups
+              // itself could be an empty array)
+          }
+      });
+
+The result of a (successful) :js:func:`~openerp.web.Query.group_by` is
+an array of :js:class:`~openerp.web.QueryGroup`.
+
+Low-level API: RPC calls to Python side
+---------------------------------------
+
+While the previous section is great for calling core OpenERP code
+(models code), it does not work if you want to call the Python side of
+OpenERP Web.
+
+For this, a lower-level API exists on on
+:js:class:`~openerp.web.Connection` objects (usually available through
+``openerp.connection``): the ``rpc`` method.
+
+This method simply takes an absolute path (which is the combination of
+the Python controller's ``_cp_path`` attribute and the name of the
+method you want to call) and a mapping of attributes to values (applied
+as keyword arguments on the Python method [#]_). This function fetches
+the return value of the Python methods, converted to JSON.
+
+For instance, to call the ``eval_domain_and_context`` of the
+:class:`~web.controllers.main.Session` controller:
+
+.. code-block:: javascript
+
+    openerp.connection.rpc('/web/session/eval_domain_and_context', {
+        domains: ds,
+        contexts: cs
+    }).then(function (result) {
+        // handle result
+    });
+
+.. [#] with a small twist: SQLAlchemy's ``orm.query.Query.group_by``
+       is not terminal, it returns a query which can still be altered.
+
+.. [#] except for ``context``, which is extracted and stored in the
+       request object itself.
diff --git a/addons/web/doc/search-view.rst b/addons/web/doc/search-view.rst
new file mode 100644 (file)
index 0000000..16a91c5
--- /dev/null
@@ -0,0 +1,549 @@
+Search View
+===========
+
+OpenERP Web 7.0 implements a unified facets-based search view instead
+of the previous form-like search view (composed of buttons and
+multiple fields). The goal for this change is twofold:
+
+* Avoid the common issue of users confusing the search view with a
+  form view and trying to create their records through it (or entering
+  all their data, hitting the ``Create`` button expecting their record
+  to be created and losing everything).
+
+* Improve the looks and behaviors of the view, and the fit within
+  OpenERP Web's new design.
+
+The internal structure of the faceted search is inspired by
+`VisualSearch <http://documentcloud.github.com/visualsearch/>`_
+[#previous]_.
+
+As does VisualSearch, the new search view is based on `Backbone`_ and
+makes significant use of Backbone's models and collections (OpenERP
+Web's widgets make a good replacement for Backbone's own views). As a
+result, understanding the implementation details of the OpenERP Web 7
+search view also requires a basic understanding of Backbone's models,
+collections and events.
+
+.. note::
+
+    This document may mention *fetching* data. This is a shortcut for
+    "returning a :js:class:`Deferred` to [whatever is being
+    fetched]". Unless further noted, the function or method may opt to
+    return nothing by fetching ``null`` (which can easily be done by
+    returning ``$.when(null)``, which simply wraps the ``null`` in a
+    Deferred).
+
+Working with the search view: creating new inputs
+-------------------------------------------------
+
+The primary component of search views, as with all other OpenERP
+views, are inputs. The search view has two types of inputs — filters
+and fields — but only one is easly customizable: fields.
+
+The mapping from OpenERP field types (and widgets) to search view
+objects is stored in the ``openerp.web.search.fields``
+:js:class:`~openerp.web.Registry` where new field types and widgets
+can be added.
+
+Search view inputs have four main roles:
+
+Loading defaults
+++++++++++++++++
+
+Once the search view has initialized all its inputs, it will call
+:js:func:`~openerp.web.search.Input.facet_for_defaults` on each input,
+passing it a mapping (a javascript object) of ``name:value`` extracted
+from the action's context.
+
+This method should fetch a :js:class:`~openerp.web.search.Facet` (or
+an equivalent object) for the field's default value if applicable (if
+a default value for the field is found in the ``defaults`` mapping).
+
+A default implementation is provided which checks if ``defaults``
+contains a non-falsy value for the field's ``@name`` and calls
+:js:func:`openerp.web.search.Input.facet_for` with that value.
+
+There is no default implementation of
+:js:func:`openerp.web.search.Input.facet_for` [#no_impl]_, but
+:js:class:`openerp.web.search.Field` provides one, which uses the
+value as-is to fetch a :js:class:`~openerp.web.search.Facet`.
+
+Providing completions
++++++++++++++++++++++
+
+An important component of the new search view is the auto-completion
+pane, and the task of providing completion items is delegated to
+inputs through the :js:func:`~openerp.web.search.Input.complete`
+method.
+
+This method should take a single argument (the string being typed by
+the user) and should fetch an ``Array`` of possible completions
+[#completion]_.
+
+A default implementation is provided which fetches nothing.
+
+A completion item is a javascript object with two keys (technically it
+can have any number of keys, but only these two will be used by the
+search view):
+
+``label``
+
+    The string which will be displayed in the completion pane. It may
+    be formatted using HTML (inline only), as a result if ``value`` is
+    interpolated into it it *must* be escaped. ``_.escape`` can be
+    used for this.
+
+``facet``
+
+    Either a :js:class:`~openerp.web.search.Facet` object or (more
+    commonly) the corresponding attributes object. This is the facet
+    which will be inserted into the search query if the completion
+    item is selected by the user.
+
+If the ``facet`` is not provided (not present, ``null``, ``undefined``
+or any other falsy value), the completion item will not be selectable
+and will act as a section title of sort (the ``label`` will be
+formatted differently). If an input *may* fetch multiple completion
+items, it *should* prefix those with a section title using its own
+name. This has no technical consequence but is clearer for users.
+
+Providing drawer/supplementary UI
++++++++++++++++++++++++++++++++++
+
+For some inputs (fields or not), interaction via autocompletion may be
+awkward or even impossible.
+
+These may opt to being rendered in a "drawer" as well or instead. In
+that case, they will undergo the normal widget lifecycle and be
+rendered inside the drawer.
+
+.. Found no good type-based way to handle this, since there is no MI
+   (so no type-tagging) and it's possible for both Field and non-Field
+   input to be put into the drawer, for whatever reason (e.g. some
+   sort of auto-detector completion item for date widgets, but a
+   second more usual calendar widget in the drawer for more
+   obvious/precise interactions)
+
+Any input can note its desire to be rendered in the drawer by
+returning a truthy value from
+:js:func:`~openerp.web.search.Input.in_drawer`.
+
+By default, :js:func:`~openerp.web.search.Input.in_drawer` returns the
+value of :js:attr:`~openerp.web.search.Input._in_drawer`, which is
+``false``. The behavior can be toggled either by redefining the
+attribute to ``true`` (either on the class or on the input), or by
+overriding :js:func:`~openerp.web.search.Input.in_drawer` itself.
+
+The input will be rendered in the full width of the drawer, it will be
+started only once (per view).
+
+.. todo:: drawer API (if a widget wants to close the drawer in some
+          way), part of the low-level SearchView API/interactions?
+
+
+.. todo:: handle filters and filter groups via a "driver" input which
+          dynamically collects, lays out and renders filters? =>
+          exercises drawer thingies
+
+Converting from facet objects
++++++++++++++++++++++++++++++
+
+Ultimately, the point of the search view is to allow searching. In
+OpenERP this is done via :ref:`domains <openerpserver:domains>`. On
+the other hand, the OpenERP Web 7 search view's state is modelled
+after a collection of :js:class:`~openerp.web.search.Facet`, and each
+field of a search view may have special requirements when it comes to
+the domains it produces [#special]_.
+
+So there needs to be some way of mapping
+:js:class:`~openerp.web.search.Facet` objects to OpenERP search data.
+
+This is done via an input's
+:js:func:`~openerp.web.search.Input.get_domain` and
+:js:func:`~openerp.web.search.Input.get_context`. Each takes a
+:js:class:`~openerp.web.search.Facet` and returns whatever it's
+supposed to generate (a domain or a context, respectively). Either can
+return ``null`` if the current value does not map to a domain or
+context, and can throw an :js:class:`~openerp.web.search.Invalid`
+exception if the value is not valid at all for the field.
+
+.. note::
+
+    The :js:class:`~openerp.web.search.Facet` object can have any
+    number of values (from 1 upwards)
+
+.. note::
+
+    There is a third conversion method,
+    :js:func:`~openerp.web.search.Input.get_groupby`, which returns an
+    ``Array`` of groupby domains rather than a single context. At this
+    point, it is only implemented on (and used by) filters.
+
+Programmatic interactions: internal model
+-----------------------------------------
+
+This new searchview is built around an instance of
+:js:class:`~openerp.web.search.SearchQuery` available as
+:js:attr:`openerp.web.SearchView.query`.
+
+The query is a `backbone collection`_ of
+:js:class:`~openerp.web.search.Facet` objects, which can be interacted
+with directly by external objects or search view controls
+(e.g. widgets displayed in the drawer).
+
+.. js:class:: openerp.web.search.SearchQuery
+
+    The current search query of the search view, provides convenience
+    behaviors for manipulating :js:class:`~openerp.web.search.Facet`
+    on top of the usual `backbone collection`_ methods.
+
+    The query ensures all of its facets contain at least one
+    :js:class:`~openerp.web.search.FacetValue` instance. Otherwise,
+    the facet is automatically removed from the query.
+
+    .. js:function:: openerp.web.search.SearchQuery.add(values, options)
+
+        Overridden from the base ``add`` method so that adding a facet
+        which is *already* in the collection will merge the value of
+        the new facet into the old one rather than add a second facet
+        with different values.
+
+        :param values: facet, facet attributes or array thereof
+        :returns: the collection itself
+
+    .. js:function:: openerp.web.search.SearchQuery.toggle(value, options)
+
+        Convenience method for toggling facet values in a query:
+        removes the values (through the facet itself) if they are
+        present, adds them if they are not. If the facet itself is not
+        in the collection, adds it automatically.
+
+        A toggling is atomic: only one change event will be triggered
+        on the facet regardless of the number of values added to or
+        removed from the facet (if the facet already exists), and the
+        facet is only removed from the query if it has no value *at
+        the end* of the toggling.
+
+        :param value: facet or facet attributes
+        :returns: the collection
+
+.. js:class:: openerp.web.search.Facet
+
+    A `backbone model`_ representing a single facet of the current
+    research. May map to a search field, or to a more complex or
+    fuzzier input (e.g. a custom filter or an advanced search).
+
+    .. js:attribute:: category
+
+        The displayed name of the facet, as a ``String``. This is a
+        backbone model attribute.
+
+    .. js:attribute:: field
+
+        The :js:class:`~openerp.web.search.Input` instance which
+        originally created the facet [#facet-field]_, used to delegate
+        some operations (such as serializing the facet's values to
+        domains and contexts). This is a backbone model attribute.
+
+    .. js:attribute:: values
+
+        :js:class:`~openerp.web.search.FacetValues` as a javascript
+        attribute, stores all the values for the facet and helps
+        propagate their events to the facet. Is also available as a
+        backbone attribute (via ``#get`` and ``#set``) in which cases
+        it serializes to and deserializes from javascript arrays (via
+        ``Collection#toJSON`` and ``Collection#reset``).
+
+    .. js:attribute:: [icon]
+
+        optional, a single ASCII letter (a-z or A-Z) mapping to the
+        bundled mnmliconsRegular icon font.
+
+        When a facet with an ``icon`` attribute is rendered, the icon
+        is displayed (in the icon font) in the first section of the
+        facet instead of the ``category``.
+
+        By default, only filters make use of this facility.
+
+.. js:class:: openerp.web.search.FacetValues
+
+    `Backbone collection`_ of
+    :js:class:`~openerp.web.search.FacetValue` instances.
+
+.. js:class:: openerp.web.search.FacetValue
+
+    `Backbone model`_ representing a single value within a facet,
+    represents a pair of (displayed name, logical value).
+
+    .. js:attribute:: label
+
+        Backbone model attribute storing the "displayable"
+        representation of the value, visually output to the
+        user. Must be a string.
+
+    .. js:attribute:: value
+
+        Backbone model attribute storing the logical/internal value
+        (of itself), will be used by
+        :js:class:`~openerp.web.search.Input` to serialize to domains
+        and contexts.
+
+        Can be of any type.
+
+Field services
+--------------
+
+:js:class:`~openerp.web.search.Field` provides a default
+implementation of :js:func:`~openerp.web.search.Input.get_domain` and
+:js:func:`~openerp.web.search.Input.get_context` taking care of most
+of the peculiarities pertaining to OpenERP's handling of fields in
+search views. It also provides finer hooks to let developers of new
+fields and widgets customize the behavior they want without
+necessarily having to reimplement all of
+:js:func:`~openerp.web.search.Input.get_domain` or
+:js:func:`~openerp.web.search.Input.get_context`:
+
+.. js:function:: openerp.web.search.Field.get_context(facet)
+
+    If the field has no ``@context``, simply returns
+    ``null``. Otherwise, calls
+    :js:func:`~openerp.web.search.Field.value_from` once for each
+    :js:class:`~openerp.web.search.FacetValue` of the current
+    :js:class:`~openerp.web.search.Facet` (in order to extract the
+    basic javascript object from the
+    :js:class:`~openerp.web.search.FacetValue` then evaluates
+    ``@context`` with each of these values set as ``self``, and
+    returns the union of all these contexts.
+
+    :param facet:
+    :type facet: openerp.web.search.Facet
+    :returns: a context (literal or compound)
+
+.. js:function:: openerp.web.search.Field.get_domain(facet)
+
+    If the field has no ``@filter_domain``, calls
+    :js:func:`~openerp.web.search.Field.make_domain` once with each
+    :js:class:`~openerp.web.search.FacetValue` of the current
+    :js:class:`~openerp.web.search.Facet` as well as the field's
+    ``@name`` and either its ``@operator`` or
+    :js:attr:`~openerp.web.search.Field.default_operator`.
+
+    If the field has an ``@filter_value``, calls
+    :js:func:`~openerp.web.search.Field.value_from` once per
+    :js:class:`~openerp.web.search.FacetValue` and evaluates
+    ``@filter_value`` with each of these values set as ``self``.
+
+    In either case, "ors" all of the resulting domains (using ``|``)
+    if there is more than one
+    :js:class:`~openerp.web.search.FacetValue` and returns the union
+    of the result.
+
+    :param facet:
+    :type facet: openerp.web.search.Facet
+    :returns: a domain (literal or compound)
+
+.. js:function:: openerp.web.search.Field.make_domain(name, operator, facetValue)
+
+    Builds a literal domain from the provided data. Calls
+    :js:func:`~openerp.web.search.Field.value_from` on the
+    :js:class:`~openerp.web.search.FacetValue` and evaluates and sets
+    it as the domain's third value, uses the other two parameters as
+    the first two values.
+
+    Can be overridden to build more complex default domains.
+
+    :param String name: the field's name
+    :param String operator: the operator to use in the field's domain
+    :param facetValue:
+    :type facetValue: openerp.web.search.FacetValue
+    :returns: Array<(String, String, Object)>
+
+.. js:function:: openerp.web.search.Field.value_from(facetValue)
+
+    Extracts a "bare" javascript value from the provided
+    :js:class:`~openerp.web.search.FacetValue`, and returns it.
+
+    The default implementation will simply return the ``value``
+    backbone property of the argument.
+
+    :param facetValue:
+    :type facetValue: openerp.web.search.FacetValue
+    :returns: Object
+
+.. js:attribute:: openerp.web.search.Field.default_operator
+
+    Operator used to build a domain when a field has no ``@operator``
+    or ``@filter_domain``. ``"="`` for
+    :js:class:`~openerp.web.search.Field`
+
+Arbitrary data storage
+----------------------
+
+:js:class:`~openerp.web.search.Facet` and
+:js:class:`~openerp.web.search.FacetValue` objects (and structures)
+provided by your widgets should never be altered by the search view
+(or an other widget). This means you are free to add arbitrary fields
+in these structures if you need to (because you have more complex
+needs than the attributes described in this document).
+
+Ideally this should be avoided, but the possibility remains.
+
+Changes
+-------
+
+.. todo:: merge in changelog instead?
+
+The displaying of the search view was significantly altered from
+OpenERP Web 6.1 to OpenERP Web 7.
+
+As a result, while the external API used to interact with the search
+view does not change many internal details — including the interaction
+between the search view and its widgets — were significantly altered:
+
+Internal operations
++++++++++++++++++++
+
+* :js:func:`openerp.web.SearchView.do_clear` has been removed
+* :js:func:`openerp.web.SearchView.do_toggle_filter` has been removed
+
+Widgets API
++++++++++++
+
+* :js:func:`openerp.web.search.Widget.render` has been removed
+
+* :js:func:`openerp.web.search.Widget.make_id` has been removed
+
+* Search field objects are not openerp widgets anymore, their
+  ``start`` is not generally called
+
+* :js:func:`~openerp.web.search.Input.clear` has been removed since
+  clearing the search view now simply consists of removing all search
+  facets
+
+* :js:func:`~openerp.web.search.Input.get_domain` and
+  :js:func:`~openerp.web.search.Input.get_context` now take a
+  :js:class:`~openerp.web.search.Facet` as parameter, from which it's
+  their job to get whatever value they want
+
+* :js:func:`~openerp.web.search.Input.get_groupby` has been added. It returns
+  an :js:class:`Array` of context-like constructs. By default, it does not do
+  anything in :js:class:`~openerp.web.search.Field` and it returns the various
+  contexts of its enabled filters in
+  :js:class:`~openerp.web.search.FilterGroup`.
+
+Filters
++++++++
+
+* :js:func:`openerp.web.search.Filter.is_enabled` has been removed
+
+* :js:class:`~openerp.web.search.FilterGroup` instances are still
+  rendered (and started) in the "advanced search" drawer.
+
+Fields
+++++++
+
+* ``get_value`` has been replaced by
+  :js:func:`~openerp.web.search.Field.value_from` as it now takes a
+  :js:class:`~openerp.web.search.FacetValue` argument (instead of no
+  argument). It provides a default implementation returning the
+  ``value`` property of its argument.
+
+* The third argument to
+  :js:func:`~openerp.web.search.Field.make_domain` is now a
+  :js:class:`~openerp.web.search.FacetValue` so child classes have all
+  the information they need to derive the "right" resulting domain.
+
+Custom filters
+++++++++++++++
+
+Instead of being an intrinsic part of the search view, custom filters
+are now a special case of filter groups. They are treated specially
+still, but much less so than they used to be.
+
+Many To One
++++++++++++
+
+* Because the autocompletion service is now provided by the search
+  view itself,
+  :js:func:`openerp.web.search.ManyToOneField.setup_autocomplete` has
+  been removed.
+
+Advanced Search
++++++++++++++++
+
+* The advanced search is now a more standard
+  :js:class:`~openerp.web.search.Input` configured to be rendered in
+  the drawer.
+
+* :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` are
+  now standard widgets, with the "right" behaviors (they don't rebind
+  their ``$element`` in ``start()``)
+
+* The ad-hoc optional setting of the openerp field descriptor on a
+  :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` has
+  been removed, the field descriptor is now passed as second argument
+  to the
+  :js:class:`~openerp.web.search.ExtendedSearchProposition.Field`'s
+  constructor, and bound to its
+  :js:attr:`~openerp.web.search.ExtendedSearchProposition.Field.field`.
+
+* Instead of its former domain triplet ``(field, operator, value)``,
+  :js:func:`~openerp.web.search.ExtendedSearchProposition.get_proposition`
+  now returns an object with two fields ``label`` and ``value``,
+  respectively a human-readable version of the proposition and the
+  corresponding domain triplet for the proposition.
+
+.. [#previous]
+
+    the original view was implemented on top of a monkey-patched
+    VisualSearch, but as our needs diverged from VisualSearch's goal
+    this made less and less sense ultimately leading to a clean-room
+    reimplementation
+
+.. [#no_impl]
+
+    In case you are extending the search view with a brand new type of
+    input
+
+.. [#completion]
+
+    Ideally this array should not hold more than about 10 items, but
+    the search view does not put any constraint on this at the
+    moment. Note that this may change.
+
+.. [#facet-field]
+
+    ``field`` does not actually need to be an instance of
+    :js:class:`~openerp.web.search.Input`, nor does it need to be what
+    created the facet, it just needs to provide the three
+    facet-serialization methods
+    :js:func:`~openerp.web.search.Input.get_domain`,
+    :js:func:`~openerp.web.search.Input.get_context` and
+    :js:func:`~openerp.web.search.Input.get_gropuby`, existing
+    :js:class:`~openerp.web.search.Input` subtypes merely provide
+    convenient base implementation for those methods.
+
+    Complex search view inputs (especially those living in the drawer)
+    may prefer using object literals with the right slots returning
+    closed-over values or some other scheme un-bound to an actual
+    :js:class:`~openerp.web.search.Input`, as
+    :js:class:`~openerp.web.search.CustomFilters` and
+    :js:class:`~openerp.web.search.Advanced` do.
+
+.. [#special]
+
+    search view fields may also bundle context data to add to the
+    search context
+
+.. _Backbone:
+    http://documentcloud.github.com/backbone/
+
+.. _Backbone.Collection:
+.. _Backbone collection:
+    http://documentcloud.github.com/backbone/#Collection
+
+.. _Backbone model:
+    http://documentcloud.github.com/backbone/#Model
+
+.. _commit 3fca87101d:
+    https://github.com/documentcloud/visualsearch/commit/3fca87101d
diff --git a/addons/web/doc/widget.rst b/addons/web/doc/widget.rst
new file mode 100644 (file)
index 0000000..ddfe525
--- /dev/null
@@ -0,0 +1,274 @@
+User Interaction: Widget
+========================
+
+This is the base class for all visual components. It corresponds to an MVC
+view. It provides a number of services to handle a section of a page:
+
+* Rendering with QWeb
+
+* Parenting-child relations
+
+* Life-cycle management (including facilitating children destruction when a
+  parent object is removed)
+
+* DOM insertion, via jQuery-powered insertion methods. Insertion targets can
+  be anything the corresponding jQuery method accepts (generally selectors,
+  DOM nodes and jQuery objects):
+
+  :js:func:`~openerp.base.Widget.appendTo`
+    Renders the widget and inserts it as the last child of the target, uses
+    `.appendTo()`_
+
+  :js:func:`~openerp.base.Widget.prependTo`
+    Renders the widget and inserts it as the first child of the target, uses
+    `.prependTo()`_
+
+  :js:func:`~openerp.base.Widget.insertAfter`
+    Renders the widget and inserts it as the preceding sibling of the target,
+    uses `.insertAfter()`_
+
+  :js:func:`~openerp.base.Widget.insertBefore`
+    Renders the widget and inserts it as the following sibling of the target,
+    uses `.insertBefore()`_
+
+* Backbone-compatible shortcuts
+
+DOM Root
+--------
+
+A :js:class:`~openerp.web.Widget` is responsible for a section of the
+page materialized by the DOM root of the widget. The DOM root is
+available via the :js:attr:`~openerp.web.Widget.el` and
+:js:attr:`~openerp.web.Widget.$element` attributes, which are
+respectively the raw DOM Element and the jQuery wrapper around the DOM
+element.
+
+There are two main ways to define and generate this DOM root:
+
+.. js:attribute:: openerp.web.Widget.template
+
+    Should be set to the name of a QWeb template (a
+    :js:class:`String`). If set, the template will be rendered after
+    the widget has been initialized but before it has been
+    started. The root element generated by the template will be set as
+    the DOM root of the widget.
+
+.. js:attribute:: openerp.web.Widget.tagName
+
+    Used if the widget has no template defined. Defaults to ``div``,
+    will be used as the tag name to create the DOM element to set as
+    the widget's DOM root. It is possible to further customize this
+    generated DOM root with the following attributes:
+
+    .. js:attribute:: openerp.web.Widget.id
+
+        Used to generate an ``id`` attribute on the generated DOM
+        root.
+
+    .. js:attribute:: openerp.web.Widget.className
+
+        Used to generate a ``class`` attribute on the generated DOM root.
+
+    .. js:attribute:: openerp.web.Widget.attributes
+
+        Mapping (object literal) of attribute names to attribute
+        values. Each of these k:v pairs will be set as a DOM attribute
+        on the generated DOM root.
+
+    None of these is used in case a template is specified on the widget.
+
+The DOM root can also be defined programmatically by overridding
+
+.. js:function:: openerp.web.Widget.renderElement
+
+    Renders the widget's DOM root and sets it. The default
+    implementation will render a set template or generate an element
+    as described above, and will call
+    :js:func:`~openerp.web.Widget.setElement` on the result.
+
+    Any override to :js:func:`~openerp.web.Widget.renderElement` which
+    does not call its ``_super`` **must** call
+    :js:func:`~openerp.web.Widget.setElement` with whatever it
+    generated or the widget's behavior is undefined.r
+
+    .. note::
+
+        The default :js:func:`~openerp.web.Widget.renderElement` can
+        be called repeatedly, it will *replace* the previous DOM root
+        (using ``replaceWith``). However, this requires that the
+        widget correctly sets and unsets its events (and children
+        widgets). Generally,
+        :js:func:`~openerp.web.Widget.renderElement` should not be
+        called repeatedly unless the widget advertizes this feature.
+
+Accessing DOM content
+~~~~~~~~~~~~~~~~~~~~~
+
+Because a widget is only responsible for the content below its DOM
+root, there is a shortcut for selecting sub-sections of a widget's
+DOM:
+
+.. js:function:: openerp.web.Widget.$(selector)
+
+    Applies the CSS selector specified as parameter to the widget's
+    DOM root.
+
+    .. code-block:: javascript
+
+        this.$(selector);
+
+    is functionally identical to:
+
+    .. code-block:: javascript
+
+        this.$element.find(selector);
+
+    :param String selector: CSS selector
+    :returns: jQuery object
+
+    .. note:: this helper method is compatible with
+              ``Backbone.View.$``
+
+Resetting the DOM root
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. js:function:: openerp.web.Widget.setElement(element)
+
+    Re-sets the widget's DOM root to the provided element, also
+    handles re-setting the various aliases of the DOM root as well as
+    unsetting and re-setting delegated events.
+
+    :param Element element: a DOM element or jQuery object to set as
+                            the widget's DOM root
+
+    .. note:: should be mostly compatible with `Backbone's
+              setElement`_
+
+DOM events handling
+-------------------
+
+A widget will generally need to respond to user action within its
+section of the page. This entails binding events to DOM elements.
+
+To this end, :js:class:`~openerp.web.Widget` provides an shortcut:
+
+.. js:attribute:: openerp.web.Widget.events
+
+    Events are a mapping of ``event selector`` (an event name and a
+    CSS selector separated by a space) to a callback. The callback can
+    be either a method name in the widget or a function. In either
+    case, the ``this`` will be set to the widget.
+
+    The selector is used for jQuery's `event delegation`_, the
+    callback will only be triggered for descendants of the DOM root
+    matching the selector [0]_. If the selector is left out (only an
+    event name is specified), the event will be set directly on the
+    widget's DOM root.
+
+.. js:function:: openerp.web.Widget.delegateEvents
+
+    This method is in charge of binding
+    :js:attr:`~openerp.web.Widget.events` to the DOM. It is
+    automatically called after setting the widget's DOM root.
+
+    It can be overridden to set up more complex events than the
+    :js:attr:`~openerp.web.Widget.events` map allows, but the parent
+    should always be called (or :js:attr:`~openerp.web.Widget.events`
+    won't be handled correctly).
+
+.. js:function:: openerp.web.Widget.undelegateEvents
+
+    This method is in charge of unbinding
+    :js:attr:`~openerp.web.Widget.events` from the DOM root when the
+    widget is destroyed or the DOM root is reset, in order to avoid
+    leaving "phantom" events.
+
+    It should be overridden to un-set any event set in an override of
+    :js:func:`~openerp.web.Widget.delegateEvents`.
+
+.. note:: this behavior should be compatible with `Backbone's
+          delegateEvents`_, apart from not accepting any argument.
+
+Subclassing Widget
+------------------
+
+:js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the
+:js:func:`~openerp.base.Class.extend` method), and provides a number of
+abstract properties and concrete methods (which you may or may not want to
+override). Creating a subclass looks like this:
+
+.. code-block:: javascript
+
+    var MyWidget = openerp.base.Widget.extend({
+        // QWeb template to use when rendering the object
+        template: "MyQWebTemplate",
+
+        init: function(parent) {
+            this._super(parent);
+            // insert code to execute before rendering, for object
+            // initialization
+        },
+        start: function() {
+            this._super();
+            // post-rendering initialization code, at this point
+            // ``this.$element`` has been initialized
+            this.$element.find(".my_button").click(/* an example of event binding * /);
+
+            // if ``start`` is asynchronous, return a promise object so callers
+            // know when the object is done initializing
+            return this.rpc(/* … */)
+        }
+    });
+
+The new class can then be used in the following manner:
+
+.. code-block:: javascript
+
+    // Create the instance
+    var my_widget = new MyWidget(this);
+    // Render and insert into DOM
+    my_widget.appendTo(".some-div");
+
+After these two lines have executed (and any promise returned by ``appendTo``
+has been resolved if needed), the widget is ready to be used.
+
+.. note:: the insertion methods will start the widget themselves, and will
+          return the result of :js:func:`~openerp.base.Widget.start()`.
+
+          If for some reason you do not want to call these methods, you will
+          have to first call :js:func:`~openerp.base.Widget.render()` on the
+          widget, then insert it into your DOM and start it.
+
+If the widget is not needed anymore (because it's transient), simply terminate
+it:
+
+.. code-block:: javascript
+
+    my_widget.destroy();
+
+will unbind all DOM events, remove the widget's content from the DOM and
+destroy all widget data.
+
+.. [0] not all DOM events are compatible with events delegation
+
+.. _.appendTo():
+    http://api.jquery.com/appendTo/
+
+.. _.prependTo():
+    http://api.jquery.com/prependTo/
+
+.. _.insertAfter():
+    http://api.jquery.com/insertAfter/
+
+.. _.insertBefore():
+    http://api.jquery.com/insertBefore/
+
+.. _event delegation:
+    http://api.jquery.com/delegate/
+
+.. _Backbone's setElement:
+    http://backbonejs.org/#View-setElement
+
+.. _Backbone's delegateEvents:
+    http://backbonejs.org/#View-delegateEvents
+
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644 (file)
index c1eff18..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    = -q
-SPHINXBUILD   = sphinx-build
-PAPER         =
-BUILDDIR      = _build
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
-       @echo "Please use \`make <target>' where <target> is one of"
-       @echo "  html       to make standalone HTML files"
-       @echo "  dirhtml    to make HTML files named index.html in directories"
-       @echo "  singlehtml to make a single large HTML file"
-       @echo "  pickle     to make pickle files"
-       @echo "  json       to make JSON files"
-       @echo "  htmlhelp   to make HTML files and a HTML help project"
-       @echo "  qthelp     to make HTML files and a qthelp project"
-       @echo "  devhelp    to make HTML files and a Devhelp project"
-       @echo "  epub       to make an epub"
-       @echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-       @echo "  latexpdf   to make LaTeX files and run them through pdflatex"
-       @echo "  text       to make text files"
-       @echo "  man        to make manual pages"
-       @echo "  texinfo    to make Texinfo files"
-       @echo "  info       to make Texinfo files and run them through makeinfo"
-       @echo "  gettext    to make PO message catalogs"
-       @echo "  changes    to make an overview of all changed/added/deprecated items"
-       @echo "  linkcheck  to check all external links for integrity"
-       @echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
-
-clean:
-       -rm -rf $(BUILDDIR)/*
-
-html:
-       $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-       @echo
-       @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
-       $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-       sed -i '/-99999/d' _build/dirhtml/_static/flasky.css
-       @echo
-       @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
-       $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
-       @echo
-       @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
-       $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-       @echo
-       @echo "Build finished; now you can process the pickle files."
-
-json:
-       $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-       @echo
-       @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
-       $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-       @echo
-       @echo "Build finished; now you can run HTML Help Workshop with the" \
-             ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
-       $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-       @echo
-       @echo "Build finished; now you can run "qcollectiongenerator" with the" \
-             ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-       @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhcp"
-       @echo "To view the help file:"
-       @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhc"
-
-devhelp:
-       $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
-       @echo
-       @echo "Build finished."
-       @echo "To view the help file:"
-       @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation"
-       @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation"
-       @echo "# devhelp"
-
-epub:
-       $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
-       @echo
-       @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo
-       @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-       @echo "Run \`make' in that directory to run these through (pdf)latex" \
-             "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
-       $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-       @echo "Running LaTeX files through pdflatex..."
-       $(MAKE) -C $(BUILDDIR)/latex all-pdf
-       @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
-       $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
-       @echo
-       @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
-       $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
-       @echo
-       @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
-       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-       @echo
-       @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
-       @echo "Run \`make' in that directory to run these through makeinfo" \
-             "(use \`make info' here to do that automatically)."
-
-info:
-       $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
-       @echo "Running Texinfo files through makeinfo..."
-       make -C $(BUILDDIR)/texinfo info
-       @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
-       $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
-       @echo
-       @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
-       $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-       @echo
-       @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
-       $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-       @echo
-       @echo "Link check complete; look for any errors in the above output " \
-             "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
-       $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-       @echo "Testing of doctests in the sources finished, look at the " \
-             "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/doc/_static/openerp.png b/doc/_static/openerp.png
deleted file mode 100644 (file)
index d6dbd9d..0000000
Binary files a/doc/_static/openerp.png and /dev/null differ
diff --git a/doc/_templates/sidebarintro.html b/doc/_templates/sidebarintro.html
deleted file mode 100644 (file)
index ecd5198..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<p class="logo"><a href="http://doc.openerp.com/">
-  <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/>
-</a></p>
-
-<h3>Other Docs</h3>
-<ul>
-  <li><a href="http://doc.openerp.com/trunk/developers">OpenERP Developers Documentation</a></li>
-  <li><a href="http://doc.openerp.com/trunk/developers/server">OpenERP Server Developers Documentation</a></li>
-  <li><a href="http://doc.openerp.com/trunk/users">OpenERP Users Documentation</a></li>
-</ul>
-
-<h3>Useful Links</h3>
-<ul>
-  <li><a href="http://www.openerp.com/">The OpenERP website</a></li>
-  <li><a href="http://python.org/">The Python programming language</a></li>
-</ul>
diff --git a/doc/_templates/sidebarlogo.html b/doc/_templates/sidebarlogo.html
deleted file mode 100644 (file)
index de6e3e5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<p class="logo"><a href="{{ pathto(master_doc) }}">
-  <img class="logo" src="{{ pathto('_static/openerp.png', 1) }}" alt="Logo"/>
-</a></p>
diff --git a/doc/_themes/LICENSE b/doc/_themes/LICENSE
deleted file mode 100644 (file)
index 8daab7e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-Copyright (c) 2010 by Armin Ronacher.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms of the theme, with or
-without modification, are permitted provided that the following conditions
-are met:
-
-* Redistributions of source code must retain the above copyright
-  notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the following
-  disclaimer in the documentation and/or other materials provided
-  with the distribution.
-
-* The names of the contributors may not be used to endorse or
-  promote products derived from this software without specific
-  prior written permission.
-
-We kindly ask you to only use these themes in an unmodified manner just
-for Flask and Flask-related products, not for unrelated projects.  If you
-like the visual style and want to use it for your own projects, please
-consider making some larger changes to the themes (such as changing
-font faces, sizes, colors or margins).
-
-THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
diff --git a/doc/_themes/README b/doc/_themes/README
deleted file mode 100644 (file)
index b3292bd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-Flask Sphinx Styles
-===================
-
-This repository contains sphinx styles for Flask and Flask related
-projects.  To use this style in your Sphinx documentation, follow
-this guide:
-
-1. put this folder as _themes into your docs folder.  Alternatively
-   you can also use git submodules to check out the contents there.
-2. add this to your conf.py:
-
-   sys.path.append(os.path.abspath('_themes'))
-   html_theme_path = ['_themes']
-   html_theme = 'flask'
-
-The following themes exist:
-
-- 'flask' - the standard flask documentation theme for large
-  projects
-- 'flask_small' - small one-page theme.  Intended to be used by
-  very small addon libraries for flask.
-
-The following options exist for the flask_small theme:
-
-   [options]
-   index_logo = ''              filename of a picture in _static
-                                to be used as replacement for the
-                                h1 in the index.rst file.
-   index_logo_height = 120px    height of the index logo
-   github_fork = ''             repository name on github for the
-                                "fork me" badge
diff --git a/doc/_themes/flask/layout.html b/doc/_themes/flask/layout.html
deleted file mode 100644 (file)
index ad08ecc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-{%- extends "basic/layout.html" %}
-{%- block extrahead %}
-  {{ super() }}
-  {% if theme_touch_icon %}
-  <link rel="apple-touch-icon" href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}" />
-  {% endif %}
-  <link media="only screen and (max-device-width: 480px)" href="{{
-    pathto('_static/small_flask.css', 1) }}" type= "text/css" rel="stylesheet" />
-{% endblock %}
-{%- block relbar2 %}{% endblock %}
-{% block header %}
-  {{ super() }}
-  {% if pagename == 'index' %}
-  <div class=indexwrapper>
-  {% endif %}
-{% endblock %}
-{%- block footer %}
-  <div class="footer">
-    &copy; Copyright {{ copyright }}
-    Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> and a modified <a href="https://github.com/mitsuhiko/flask-sphinx-themes">Flask theme</a>.
-  </div>
-  {% if pagename == 'index' %}
-  </div>
-  {% endif %}
-{%- endblock %}
diff --git a/doc/_themes/flask/relations.html b/doc/_themes/flask/relations.html
deleted file mode 100644 (file)
index 3bbcde8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-<h3>Related Topics</h3>
-<ul>
-  <li><a href="{{ pathto(master_doc) }}">Documentation overview</a><ul>
-  {%- for parent in parents %}
-  <li><a href="{{ parent.link|e }}">{{ parent.title }}</a><ul>
-  {%- endfor %}
-    {%- if prev %}
-      <li>Previous: <a href="{{ prev.link|e }}" title="{{ _('previous chapter')
-        }}">{{ prev.title }}</a></li>
-    {%- endif %}
-    {%- if next %}
-      <li>Next: <a href="{{ next.link|e }}" title="{{ _('next chapter')
-        }}">{{ next.title }}</a></li>
-    {%- endif %}
-  {%- for parent in parents %}
-  </ul></li>
-  {%- endfor %}
-  </ul></li>
-</ul>
diff --git a/doc/_themes/flask/static/flasky.css_t b/doc/_themes/flask/static/flasky.css_t
deleted file mode 100644 (file)
index 0280e15..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * flasky.css_t
- * ~~~~~~~~~~~~
- *
- * :copyright: Copyright 2010 by Armin Ronacher.
- * :license: Flask Design License, see LICENSE for details.
- */
-
-{% set page_width = '80em' %}
-{% set sidebar_width = '16em' %}
-@import url("basic.css");
-/* -- page layout ----------------------------------------------------------- */
-body {
-    font-family: 'Georgia', serif;
-    font-size: 15px;
-    background-color: white;
-    color: #000;
-    margin: 0;
-    padding: 0;
-}
-
-div.document {
-    width: {{ page_width }};
-    margin: 30px auto 0 auto;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 {{ sidebar_width }};
-}
-
-div.sphinxsidebar {
-    width: {{ sidebar_width }};
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
-div.body {
-    background-color: #ffffff;
-    color: #3E4349;
-    padding: 0 0px 0 0px;
-}
-
-img.floatingflask {
-    padding: 0 0 10px 10px;
-    float: right;
-}
-div.footer {
-    width: {{ page_width }};
-    margin: 20px auto 30px auto;
-    font-size: 12px;
-    color: #888;
-    text-align: right;
-}
-
-div.footer a {
-    color: #888;
-}
-
-div.related {
-    display: none;
-}
-div.sphinxsidebar a {
-    color: #444;
-    text-decoration: none;
-    border-bottom: 1px dotted #999;
-}
-
-div.sphinxsidebar a:hover {
-    border-bottom: 1px solid #999;
-}
-div.sphinxsidebar {
-    font-size: 12px;
-    line-height: 1.5;
-}
-
-div.sphinxsidebarwrapper {
-    padding: 0px 10px;
-}
-
-div.sphinxsidebarwrapper p.logo {
-    padding: 0 0 20px 0;
-    margin: 0;
-    text-align: center;
-}
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
-    font-family: 'Garamond', 'Georgia', serif;
-    color: #444;
-    font-size: 22px;
-    font-weight: normal;
-    margin: 0 0 5px 0;
-    padding: 0;
-}
-
-div.sphinxsidebar h4 {
-    font-size: 18px;
-}
-div.sphinxsidebar h3 a {
-    color: #444;
-}
-
-div.sphinxsidebar p.logo a,
-div.sphinxsidebar h3 a,
-div.sphinxsidebar p.logo a:hover,
-div.sphinxsidebar h3 a:hover {
-    border: none;
-}
-div.sphinxsidebar p {
-    color: #555;
-    margin: 10px 0;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px 0;
-    padding: 0;
-    color: #000;
-}
-div.sphinxsidebar input {
-    border: 1px solid #ccc;
-    font-family: 'Georgia', serif;
-    font-size: 1em;
-}
-/* -- body styles ----------------------------------------------------------- */
-a {
-    color: #004B6B;
-    text-decoration: underline;
-}
-a:hover {
-    color: #6D4100;
-    text-decoration: underline;
-}
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    margin: 30px 0px 10px 0px;
-    padding: 0;
-}
-
-{% if theme_index_logo %}
-div.indexwrapper h1 {
-    text-indent: -999999px;
-    background: url({{ theme_index_logo }}) no-repeat center center;
-    height: {{ theme_index_logo_height }};
-}
-{% endif %}
-div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-a.headerlink {
-    color: #ddd;
-    padding: 0 4px;
-    text-decoration: none;
-}
-a.headerlink:hover {
-    color: #444;
-    background: #eaeaea;
-}
-div.body p, div.body dd, div.body li {
-    line-height: 1.4em;
-}
-
-div.admonition {
-    background: #fafafa;
-    margin: 20px -30px;
-    padding: 10px 30px;
-    border-top: 1px solid #ccc;
-    border-bottom: 1px solid #ccc;
-}
-
-div.admonition tt.xref, div.admonition a tt {
-    border-bottom: 1px solid #fafafa;
-}
-
-dd div.admonition {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-div.admonition p.admonition-title {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    font-size: 22px;
-    margin: 0 0 10px 0;
-    padding: 0;
-    line-height: 1;
-}
-
-div.admonition p.last {
-    margin-bottom: 0;
-}
-
-div.highlight {
-    background-color: white;
-}
-
-dt:target, .highlight {
-    background: #FAF3E8;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-div.topic {
-    background-color: #eee;
-}
-p.admonition-title {
-    display: inline;
-}
-p.admonition-title:after {
-    content: ":";
-}
-
-pre, tt {
-    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.9em;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname {
-    font-size: 0.95em;
-}
-
-tt.descname {
-    padding-right: 0.08em;
-}
-
-img.screenshot {
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils {
-    border: 1px solid #888;
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #888;
-    padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
-    border: none;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-table.footnote {
-    margin: 15px 0;
-    width: 100%;
-    border: 1px solid #eee;
-    background: #fdfdfd;
-    font-size: 0.9em;
-}
-
-table.footnote + table.footnote {
-    margin-top: -15px;
-    border-top: none;
-}
-
-table.field-list th {
-    padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
-    padding: 0;
-}
-
-table.footnote td.label {
-    width: 0px;
-    padding: 0.3em 0 0.3em 0.5em;
-}
-
-table.footnote td {
-    padding: 0.3em 0.5em;
-}
-
-dl {
-    margin: 0;
-    padding: 0;
-}
-
-dl dd {
-    margin-left: 30px;
-}
-
-blockquote {
-    margin: 0 0 0 30px;
-    padding: 0;
-}
-
-ul, ol {
-    margin: 10px 0 10px 30px;
-    padding: 0;
-}
-pre {
-    background: #eee;
-    padding: 7px 30px;
-    margin: 15px -30px;
-    line-height: 1.3em;
-}
-
-dl pre, blockquote pre, li pre {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-dl dl pre {
-    margin-left: -90px;
-    padding-left: 90px;
-}
-tt {
-    background-color: #ecf0f3;
-    color: #222;
-    /* padding: 1px 2px; */
-}
-
-tt.xref, a tt {
-    background-color: #FBFBFB;
-    border-bottom: 1px solid white;
-}
-
-a.reference {
-    text-decoration: none;
-    border-bottom: 1px dotted #004B6B;
-}
-
-a.reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a.footnote-reference {
-    text-decoration: none;
-    font-size: 0.7em;
-    vertical-align: top;
-    border-bottom: 1px dotted #004B6B;
-}
-
-a.footnote-reference:hover {
-    border-bottom: 1px solid #6D4100;
-}
-
-a:hover tt {
-    background: #EEE;
-}
diff --git a/doc/_themes/flask/static/small_flask.css b/doc/_themes/flask/static/small_flask.css
deleted file mode 100644 (file)
index 1c6df30..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * small_flask.css_t
- * ~~~~~~~~~~~~~~~~~
- *
- * :copyright: Copyright 2010 by Armin Ronacher.
- * :license: Flask Design License, see LICENSE for details.
- */
-
-body {
-    margin: 0;
-    padding: 20px 30px;
-}
-
-div.documentwrapper {
-    float: none;
-    background: white;
-}
-
-div.sphinxsidebar {
-    display: block;
-    float: none;
-    width: 102.5%;
-    margin: 50px -30px -20px -30px;
-    padding: 10px 20px;
-    background: #333;
-    color: white;
-}
-
-div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
-div.sphinxsidebar h3 a {
-    color: white;
-}
-
-div.sphinxsidebar a {
-    color: #aaa;
-}
-
-div.sphinxsidebar p.logo {
-    display: none;
-}
-
-div.document {
-    width: 100%;
-    margin: 0;
-}
-
-div.related {
-    display: block;
-    margin: 0;
-    padding: 10px 0 20px 0;
-}
-
-div.related ul,
-div.related ul li {
-    margin: 0;
-    padding: 0;
-}
-
-div.footer {
-    display: none;
-}
-
-div.bodywrapper {
-    margin: 0;
-}
-
-div.body {
-    min-height: 0;
-    padding: 0;
-}
diff --git a/doc/_themes/flask/theme.conf b/doc/_themes/flask/theme.conf
deleted file mode 100644 (file)
index 18c720f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-[theme]
-inherit = basic
-stylesheet = flasky.css
-pygments_style = flask_theme_support.FlaskyStyle
-
-[options]
-index_logo = ''
-index_logo_height = 120px
-touch_icon = 
diff --git a/doc/_themes/flask_small/layout.html b/doc/_themes/flask_small/layout.html
deleted file mode 100644 (file)
index aa1716a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-{% extends "basic/layout.html" %}
-{% block header %}
-  {{ super() }}
-  {% if pagename == 'index' %}
-  <div class=indexwrapper>
-  {% endif %}
-{% endblock %}
-{% block footer %}
-  {% if pagename == 'index' %}
-  </div>
-  {% endif %}
-{% endblock %}
-{# do not display relbars #}
-{% block relbar1 %}{% endblock %}
-{% block relbar2 %}
-  {% if theme_github_fork %}
-    <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;"
-    src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a>
-  {% endif %}
-{% endblock %}
-{% block sidebar1 %}{% endblock %}
-{% block sidebar2 %}{% endblock %}
diff --git a/doc/_themes/flask_small/static/flasky.css_t b/doc/_themes/flask_small/static/flasky.css_t
deleted file mode 100644 (file)
index fe2141c..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * flasky.css_t
- * ~~~~~~~~~~~~
- *
- * Sphinx stylesheet -- flasky theme based on nature theme.
- *
- * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
- * :license: BSD, see LICENSE for details.
- *
- */
-@import url("basic.css");
-/* -- page layout ----------------------------------------------------------- */
-body {
-    font-family: 'Georgia', serif;
-    font-size: 17px;
-    color: #000;
-    background: white;
-    margin: 0;
-    padding: 0;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 40px auto 0 auto;
-    width: 700px;
-}
-
-hr {
-    border: 1px solid #B1B4B6;
-}
-div.body {
-    background-color: #ffffff;
-    color: #3E4349;
-    padding: 0 30px 30px 30px;
-}
-
-img.floatingflask {
-    padding: 0 0 10px 10px;
-    float: right;
-}
-div.footer {
-    text-align: right;
-    color: #888;
-    padding: 10px;
-    font-size: 14px;
-    width: 650px;
-    margin: 0 auto 40px auto;
-}
-div.footer a {
-    color: #888;
-    text-decoration: underline;
-}
-div.related {
-    line-height: 32px;
-    color: #888;
-}
-
-div.related ul {
-    padding: 0 0 0 10px;
-}
-div.related a {
-    color: #444;
-}
-/* -- body styles ----------------------------------------------------------- */
-a {
-    color: #004B6B;
-    text-decoration: underline;
-}
-a:hover {
-    color: #6D4100;
-    text-decoration: underline;
-}
-
-div.body {
-    padding-bottom: 40px; /* saved for footer */
-}
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    margin: 30px 0px 10px 0px;
-    padding: 0;
-}
-
-{% if theme_index_logo %}
-div.indexwrapper h1 {
-    text-indent: -999999px;
-    background: url({{ theme_index_logo }}) no-repeat center center;
-    height: {{ theme_index_logo_height }};
-}
-{% endif %}
-div.body h2 { font-size: 180%; }
-div.body h3 { font-size: 150%; }
-div.body h4 { font-size: 130%; }
-div.body h5 { font-size: 100%; }
-div.body h6 { font-size: 100%; }
-a.headerlink {
-    color: white;
-    padding: 0 4px;
-    text-decoration: none;
-}
-a.headerlink:hover {
-    color: #444;
-    background: #eaeaea;
-}
-div.body p, div.body dd, div.body li {
-    line-height: 1.4em;
-}
-
-div.admonition {
-    background: #fafafa;
-    margin: 20px -30px;
-    padding: 10px 30px;
-    border-top: 1px solid #ccc;
-    border-bottom: 1px solid #ccc;
-}
-
-div.admonition p.admonition-title {
-    font-family: 'Garamond', 'Georgia', serif;
-    font-weight: normal;
-    font-size: 24px;
-    margin: 0 0 10px 0;
-    padding: 0;
-    line-height: 1;
-}
-
-div.admonition p.last {
-    margin-bottom: 0;
-}
-
-div.highlight{
-    background-color: white;
-}
-
-dt:target, .highlight {
-    background: #FAF3E8;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-div.topic {
-    background-color: #eee;
-}
-div.warning {
-    background-color: #ffe4e4;
-    border: 1px solid #f66;
-}
-p.admonition-title {
-    display: inline;
-}
-p.admonition-title:after {
-    content: ":";
-}
-
-pre, tt {
-    font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
-    font-size: 0.85em;
-}
-
-img.screenshot {
-}
-
-tt.descname, tt.descclassname {
-    font-size: 0.95em;
-}
-
-tt.descname {
-    padding-right: 0.08em;
-}
-
-img.screenshot {
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils {
-    border: 1px solid #888;
-    -moz-box-shadow: 2px 2px 4px #eee;
-    -webkit-box-shadow: 2px 2px 4px #eee;
-    box-shadow: 2px 2px 4px #eee;
-}
-
-table.docutils td, table.docutils th {
-    border: 1px solid #888;
-    padding: 0.25em 0.7em;
-}
-
-table.field-list, table.footnote {
-    border: none;
-    -moz-box-shadow: none;
-    -webkit-box-shadow: none;
-    box-shadow: none;
-}
-
-table.footnote {
-    margin: 15px 0;
-    width: 100%;
-    border: 1px solid #eee;
-}
-
-table.field-list th {
-    padding: 0 0.8em 0 0;
-}
-
-table.field-list td {
-    padding: 0;
-}
-
-table.footnote td {
-    padding: 0.5em;
-}
-
-dl {
-    margin: 0;
-    padding: 0;
-}
-
-dl dd {
-    margin-left: 30px;
-}
-pre {
-    padding: 0;
-    margin: 15px -30px;
-    padding: 8px;
-    line-height: 1.3em;
-    padding: 7px 30px;
-    background: #eee;
-    border-radius: 2px;
-    -moz-border-radius: 2px;
-    -webkit-border-radius: 2px;
-}
-
-dl pre {
-    margin-left: -60px;
-    padding-left: 60px;
-}
-
-tt {
-    background-color: #ecf0f3;
-    color: #222;
-    /* padding: 1px 2px; */
-}
-
-tt.xref, a tt {
-    background-color: #FBFBFB;
-}
-
-a:hover tt {
-    background: #EEE;
-}
diff --git a/doc/_themes/flask_small/theme.conf b/doc/_themes/flask_small/theme.conf
deleted file mode 100644 (file)
index 542b462..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-[theme]
-inherit = basic
-stylesheet = flasky.css
-nosidebar = true
-pygments_style = flask_theme_support.FlaskyStyle
-
-[options]
-index_logo = ''
-index_logo_height = 120px
-github_fork = ''
diff --git a/doc/_themes/flask_theme_support.py b/doc/_themes/flask_theme_support.py
deleted file mode 100644 (file)
index 33f4744..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-# flasky extensions.  flasky pygments style based on tango style
-from pygments.style import Style
-from pygments.token import Keyword, Name, Comment, String, Error, \
-     Number, Operator, Generic, Whitespace, Punctuation, Other, Literal
-
-
-class FlaskyStyle(Style):
-    background_color = "#f8f8f8"
-    default_style = ""
-
-    styles = {
-        # No corresponding class for the following:
-        #Text:                     "", # class:  ''
-        Whitespace:                "underline #f8f8f8",      # class: 'w'
-        Error:                     "#a40000 border:#ef2929", # class: 'err'
-        Other:                     "#000000",                # class 'x'
-
-        Comment:                   "italic #8f5902", # class: 'c'
-        Comment.Preproc:           "noitalic",       # class: 'cp'
-
-        Keyword:                   "bold #004461",   # class: 'k'
-        Keyword.Constant:          "bold #004461",   # class: 'kc'
-        Keyword.Declaration:       "bold #004461",   # class: 'kd'
-        Keyword.Namespace:         "bold #004461",   # class: 'kn'
-        Keyword.Pseudo:            "bold #004461",   # class: 'kp'
-        Keyword.Reserved:          "bold #004461",   # class: 'kr'
-        Keyword.Type:              "bold #004461",   # class: 'kt'
-
-        Operator:                  "#582800",   # class: 'o'
-        Operator.Word:             "bold #004461",   # class: 'ow' - like keywords
-
-        Punctuation:               "bold #000000",   # class: 'p'
-
-        # because special names such as Name.Class, Name.Function, etc.
-        # are not recognized as such later in the parsing, we choose them
-        # to look the same as ordinary variables.
-        Name:                      "#000000",        # class: 'n'
-        Name.Attribute:            "#c4a000",        # class: 'na' - to be revised
-        Name.Builtin:              "#004461",        # class: 'nb'
-        Name.Builtin.Pseudo:       "#3465a4",        # class: 'bp'
-        Name.Class:                "#000000",        # class: 'nc' - to be revised
-        Name.Constant:             "#000000",        # class: 'no' - to be revised
-        Name.Decorator:            "#888",           # class: 'nd' - to be revised
-        Name.Entity:               "#ce5c00",        # class: 'ni'
-        Name.Exception:            "bold #cc0000",   # class: 'ne'
-        Name.Function:             "#000000",        # class: 'nf'
-        Name.Property:             "#000000",        # class: 'py'
-        Name.Label:                "#f57900",        # class: 'nl'
-        Name.Namespace:            "#000000",        # class: 'nn' - to be revised
-        Name.Other:                "#000000",        # class: 'nx'
-        Name.Tag:                  "bold #004461",   # class: 'nt' - like a keyword
-        Name.Variable:             "#000000",        # class: 'nv' - to be revised
-        Name.Variable.Class:       "#000000",        # class: 'vc' - to be revised
-        Name.Variable.Global:      "#000000",        # class: 'vg' - to be revised
-        Name.Variable.Instance:    "#000000",        # class: 'vi' - to be revised
-
-        Number:                    "#990000",        # class: 'm'
-
-        Literal:                   "#000000",        # class: 'l'
-        Literal.Date:              "#000000",        # class: 'ld'
-
-        String:                    "#4e9a06",        # class: 's'
-        String.Backtick:           "#4e9a06",        # class: 'sb'
-        String.Char:               "#4e9a06",        # class: 'sc'
-        String.Doc:                "italic #8f5902", # class: 'sd' - like a comment
-        String.Double:             "#4e9a06",        # class: 's2'
-        String.Escape:             "#4e9a06",        # class: 'se'
-        String.Heredoc:            "#4e9a06",        # class: 'sh'
-        String.Interpol:           "#4e9a06",        # class: 'si'
-        String.Other:              "#4e9a06",        # class: 'sx'
-        String.Regex:              "#4e9a06",        # class: 'sr'
-        String.Single:             "#4e9a06",        # class: 's1'
-        String.Symbol:             "#4e9a06",        # class: 'ss'
-
-        Generic:                   "#000000",        # class: 'g'
-        Generic.Deleted:           "#a40000",        # class: 'gd'
-        Generic.Emph:              "italic #000000", # class: 'ge'
-        Generic.Error:             "#ef2929",        # class: 'gr'
-        Generic.Heading:           "bold #000080",   # class: 'gh'
-        Generic.Inserted:          "#00A000",        # class: 'gi'
-        Generic.Output:            "#888",           # class: 'go'
-        Generic.Prompt:            "#745334",        # class: 'gp'
-        Generic.Strong:            "bold #000000",   # class: 'gs'
-        Generic.Subheading:        "bold #800080",   # class: 'gu'
-        Generic.Traceback:         "bold #a40000",   # class: 'gt'
-    }
diff --git a/doc/addon-structure.txt b/doc/addon-structure.txt
deleted file mode 100644 (file)
index 3815174..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<addon name>
-  +-- __openerp__.py
-  +-- controllers/
-  +-- static/
-       +-- lib/
-       +-- src/
-            +-- css/
-            +-- img/
-            +-- js/
-            +-- xml/
-       +-- test/
-  +-- test/
diff --git a/doc/async.rst b/doc/async.rst
deleted file mode 100644 (file)
index 23b3409..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-Don't stop the world now: asynchronous development and Javascript
-=================================================================
-
-As a language (and runtime), javascript is fundamentally
-single-threaded. This means any blocking request or computation will
-blocks the whole page (and, in older browsers, the software itself
-even preventing users from switching to an other tab): a javascript
-environment can be seen as an event-based runloop where application
-developers have no control over the runloop itself.
-
-As a result, performing long-running synchronous network requests or
-other types of complex and expensive accesses is frowned upon and
-asynchronous APIs are used instead.
-
-Asynchronous code rarely comes naturally, especially for developers
-used to synchronous server-side code (in Python, Java or C#) where the
-code will just block until the deed is gone. This is increased further
-when asynchronous programming is not a first-class concept and is
-instead implemented on top of callbacks-based programming, which is
-the case in javascript.
-
-The goal of this guide is to provide some tools to deal with
-asynchronous systems, and warn against systematic issues or dangers.
-
-Deferreds
----------
-
-Deferreds are a form of `promises`_. OpenERP Web currently uses
-`jQuery's deferred`_, but any `CommonJS Promises/A`_ implementation
-should work.
-
-The core idea of deferreds is that potentially asynchronous methods
-will return a :js:class:`Deferred` object instead of an arbitrary
-value or (most commonly) nothing.
-
-This object can then be used to track the end of the asynchronous
-operation by adding callbacks onto it, either success callbacks or
-error callbacks.
-
-A great advantage of deferreds over simply passing callback functions
-directly to asynchronous methods is the ability to :ref:`compose them
-<deferred-composition>`.
-
-Using deferreds
-~~~~~~~~~~~~~~~
-
-`CommonJS Promises/A`_ deferreds have only one method of importance:
-:js:func:`Deferred.then`. This method is used to attach new callbacks
-to the deferred object.
-
-* the first parameter attaches a success callback, called when the
-  deferred object is successfully resolved and provided with the
-  resolved value(s) for the asynchronous operation.
-
-* the second parameter attaches a failure callback, called when the
-  deferred object is rejected and provided with rejection values
-  (often some sort of error message).
-
-Callbacks attached to deferreds are never "lost": if a callback is
-attached to an already resolved or rejected deferred, the callback
-will be called (or ignored) immediately. A deferred is also only ever
-resolved or rejected once, and is either resolved or rejected: a given
-deferred can not call a single success callback twice, or call both a
-success and a failure callbacks.
-
-:js:func:`~Deferred.then` should be the method you'll use most often
-when interacting with deferred objects (and thus asynchronous APIs).
-
-Building deferreds
-~~~~~~~~~~~~~~~~~~
-
-After using asynchronous APIs may come the time to build them: for
-`mocks`_, to compose deferreds from multiple source in a complex
-manner, in order to let the current operations repaint the screen or
-give other events the time to unfold, ...
-
-This is easy using jQuery's deferred objects.
-
-.. note:: this section is an implementation detail of jQuery Deferred
-          objects, the creation of promises is not part of any
-          standard (even tentative) that I know of. If you are using
-          deferred objects which are not jQuery's, their API may (and
-          often will) be completely different.
-
-Deferreds are created by invoking their constructor [#]_ without any
-argument. This creates a :js:class:`Deferred` instance object with the
-following methods:
-
-:js:func:`Deferred.resolve`
-
-    As its name indicates, this method moves the deferred to the
-    "Resolved" state. It can be provided as many arguments as
-    necessary, these arguments will be provided to any pending success
-    callback.
-
-:js:func:`Deferred.reject`
-
-    Similar to :js:func:`~Deferred.resolve`, but moves the deferred to
-    the "Rejected" state and calls pending failure handlers.
-
-:js:func:`Deferred.promise`
-
-    Creates a readonly view of the deferred object. It is generally a
-    good idea to return a promise view of the deferred to prevent
-    callers from resolving or rejecting the deferred in your stead.
-
-:js:func:`~Deferred.reject` and :js:func:`~Deferred.resolve` are used
-to inform callers that the asynchronous operation has failed (or
-succeeded). These methods should simply be called when the
-asynchronous operation has ended, to notify anybody interested in its
-result(s).
-
-.. _deferred-composition:
-
-Composing deferreds
-~~~~~~~~~~~~~~~~~~~
-
-What we've seen so far is pretty nice, but mostly doable by passing
-functions to other functions (well adding functions post-facto would
-probably be a chore... still, doable).
-
-Deferreds truly shine when code needs to compose asynchronous
-operations in some way or other, as they can be used as a basis for
-such composition.
-
-There are two main forms of compositions over deferred: multiplexing
-and piping/cascading.
-
-Deferred multiplexing
-`````````````````````
-
-The most common reason for multiplexing deferred is simply performing
-2+ asynchronous operations and wanting to wait until all of them are
-done before moving on (and executing more stuff).
-
-The jQuery multiplexing function for promises is :js:func:`when`.
-
-.. note:: the multiplexing behavior of jQuery's :js:func:`when` is an
-          (incompatible, mostly) extension of the behavior defined in
-          `CommonJS Promises/B`_.
-
-This function can take any number of promises [#]_ and will return a
-promise.
-
-This returned promise will be resolved when *all* multiplexed promises
-are resolved, and will be rejected as soon as one of the multiplexed
-promises is rejected (it behaves like Python's ``all()``, but with
-promise objects instead of boolean-ish).
-
-The resolved values of the various promises multiplexed via
-:js:func:`when` are mapped to the arguments of :js:func:`when`'s
-success callback, if they are needed. The resolved values of a promise
-are at the same index in the callback's arguments as the promise in
-the :js:func:`when` call so you will have:
-
-.. code-block:: javascript
-
-    $.when(p0, p1, p2, p3).then(
-            function (results0, results1, results2, results3) {
-        // code
-    });
-
-.. warning::
-
-    in a normal mapping, each parameter to the callback would be an
-    array: each promise is conceptually resolved with an array of 0..n
-    values and these values are passed to :js:func:`when`'s
-    callback. But jQuery treats deferreds resolving a single value
-    specially, and "unwraps" that value.
-
-    For instance, in the code block above if the index of each promise
-    is the number of values it resolves (0 to 3), ``results0`` is an
-    empty array, ``results2`` is an array of 2 elements (a pair) but
-    ``results1`` is the actual value resolved by ``p1``, not an array.
-
-Deferred chaining
-`````````````````
-
-A second useful composition is starting an asynchronous operation as
-the result of an other asynchronous operation, and wanting the result
-of both: :js:func:`Deferred.then` returns the deferred on which it was
-called, so handle e.g. OpenERP's search/read sequence with this would
-require something along the lines of:
-
-.. code-block:: javascript
-
-    var result = $.Deferred();
-    Model.search(condition).then(function (ids) {
-        Model.read(ids, fields).then(function (records) {
-            result.resolve(records);
-        });
-    });
-    return result.promise();
-
-While it doesn't look too bad for trivial code, this quickly gets
-unwieldy.
-
-Instead, jQuery provides a tool to handle this kind of chains:
-:js:func:`Deferred.pipe`.
-
-:js:func:`~Deferred.pipe` has the same signature as
-:js:func:`~Deferred.then` and could be used in the same manner
-provided its return value was not used.
-
-It differs from :js:func:`~Deferred.then` in two ways: it returns a
-new promise object, not the one it was called with, and the return
-values of the callbacks is actually important to it: whichever
-callback is called,
-
-* If the callback is not set (not provided or left to null), the
-  resolution or rejection value(s) is simply forwarded to
-  :js:func:`~Deferred.pipe`'s promise (it's essentially a noop)
-
-* If the callback is set and does not return an observable object (a
-  deferred or a promise), the value it returns (``undefined`` if it
-  does not return anything) will replace the value it was given, e.g.
-
-  .. code-block:: javascript
-
-      promise.pipe(function () {
-          console.log('called');
-      });
-
-  will resolve with the sole value ``undefined``.
-
-* If the callback is set and returns an observable object, that object
-  will be the actual resolution (and result) of the pipe. This means a
-  resolved promise from the failure callback will resolve the pipe,
-  and a failure promise from the success callback will reject the
-  pipe.
-
-  This provides an easy way to chain operation successes, and the
-  previous piece of code can now be rewritten:
-
-  .. code-block:: javascript
-
-      return Model.search(condition).pipe(function (ids) {
-          return Model.read(ids, fields);
-      });
-
-  the result of the whole expression will encode failure if either
-  ``search`` or ``read`` fails (with the right rejection values), and
-  will be resolved with ``read``'s resolution values if the chain
-  executes correctly.
-
-:js:func:`~Deferred.pipe` is also useful to adapt third-party
-promise-based APIs, in order to filter their resolution value counts
-for instance (to take advantage of :js:func:`when` 's special treatment
-of single-value promises).
-
-jQuery.Deferred API
-~~~~~~~~~~~~~~~~~~~
-
-.. js:function:: when(deferreds…)
-
-    :param deferreds: deferred objects to multiplex
-    :returns: a multiplexed deferred
-    :rtype: :js:class:`Deferred`
-
-.. js:class:: Deferred
-
-    .. js:function:: Deferred.then(doneCallback[, failCallback])
-
-        Attaches new callbacks to the resolution or rejection of the
-        deferred object. Callbacks are executed in the order they are
-        attached to the deferred.
-
-        To provide only a failure callback, pass ``null`` as the
-        ``doneCallback``, to provide only a success callback the
-        second argument can just be ignored (and not passed at all).
-
-        :param doneCallback: function called when the deferred is resolved
-        :type doneCallback: Function
-        :param failCallback: function called when the deferred is rejected
-        :type failCallback: Function
-        :returns: the deferred object on which it was called
-        :rtype: :js:class:`Deferred`
-
-    .. js:function:: Deferred.done(doneCallback)
-
-        Attaches a new success callback to the deferred, shortcut for
-        ``deferred.then(doneCallback)``.
-
-        This is a jQuery extension to `CommonJS Promises/A`_ providing
-        little value over calling :js:func:`~Deferred.then` directly,
-        it should be avoided.
-
-        :param doneCallback: function called when the deferred is resolved
-        :type doneCallback: Function
-        :returns: the deferred object on which it was called
-        :rtype: :js:class:`Deferred`
-
-    .. js:function:: Deferred.fail(failCallback)
-
-        Attaches a new failure callback to the deferred, shortcut for
-        ``deferred.then(null, failCallback)``.
-
-        A second jQuery extension to `Promises/A <CommonJS
-        Promises/A>`_. Although it provides more value than
-        :js:func:`~Deferred.done`, it still is not much and should be
-        avoided as well.
-
-        :param failCallback: function called when the deferred is rejected
-        :type failCallback: Function
-        :returns: the deferred object on which it was called
-        :rtype: :js:class:`Deferred`
-
-    .. js:function:: Deferred.promise()
-
-        Returns a read-only view of the deferred object, with all
-        mutators (resolve and reject) methods removed.
-
-    .. js:function:: Deferred.resolve(value…)
-
-        Called to resolve a deferred, any value provided will be
-        passed onto the success handlers of the deferred object.
-
-        Resolving a deferred which has already been resolved or
-        rejected has no effect.
-
-    .. js:function:: Deferred.reject(value…)
-
-        Called to reject (fail) a deferred, any value provided will be
-        passed onto the failure handler of the deferred object.
-
-        Rejecting a deferred which has already been resolved or
-        rejected has no effect.
-
-    .. js:function:: Deferred.pipe(doneFilter[, failFilter])
-
-        Filters the result of a deferred, able to transform a success
-        into failure and a failure into success, or to delay
-        resolution further.
-
-.. [#] or simply calling :js:class:`Deferred` as a function, the
-       result is the same
-
-.. [#] or not-promises, the `CommonJS Promises/B`_ role of
-       :js:func:`when` is to be able to treat values and promises
-       uniformly: :js:func:`when` will pass promises through directly,
-       but non-promise values and objects will be transformed into a
-       resolved promise (resolving themselves with the value itself).
-
-       jQuery's :js:func:`when` keeps this behavior making deferreds
-       easy to build from "static" values, or allowing defensive code
-       where expected promises are wrapped in :js:func:`when` just in
-       case.
-
-.. _promises: http://en.wikipedia.org/wiki/Promise_(programming)
-.. _jQuery's deferred: http://api.jquery.com/category/deferred-object/
-.. _CommonJS Promises/A: http://wiki.commonjs.org/wiki/Promises/A
-.. _CommonJS Promises/B: http://wiki.commonjs.org/wiki/Promises/B
-.. _mocks: http://en.wikipedia.org/wiki/Mock_object
diff --git a/doc/changelog-7.0.rst b/doc/changelog-7.0.rst
deleted file mode 100644 (file)
index 00d0236..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-API changes from OpenERP Web 6.1 to 7.0
-=======================================
-
-DataSet -> Model
-----------------
-
-The 6.1 ``DataSet`` API has been deprecated in favor of the smaller
-and more orthogonal :doc:`Model </rpc>` API, which more closely
-matches the API in OpenERP Web's Python side and in OpenObject addons
-and removes most stateful behavior of DataSet.
-
-Migration guide
-~~~~~~~~~~~~~~~
-
-* Actual arbitrary RPC calls can just be remapped on a
-  :js:class:`~openerp.web.Model` instance:
-
-  .. code-block:: javascript
-
-      dataset.call(method, args)
-
-  or
-
-  .. code-block:: javascript
-
-      dataset.call_and_eval(method, args)
-
-  can be replaced by calls to :js:func:`openerp.web.Model.call`:
-
-  .. code-block:: javascript
-
-      model.call(method, args)
-
-  If callbacks are passed directly to the older methods, they need to
-  be added to the new one via ``.then()``.
-
-  .. note::
-
-      The ``context_index`` and ``domain_index`` features were not
-      ported, context and domain now need to be passed in "in full",
-      they won't be automatically filled with the user's current
-      context.
-
-* Shorcut methods (``name_get``, ``name_search``, ``unlink``,
-  ``write``, ...) should be ported to
-  :js:func:`openerp.web.Model.call`, using the server's original
-  signature. On the other hand, the non-shortcut equivalents can now
-  use keyword arguments (see :js:func:`~openerp.web.Model.call`'s
-  signature for details)
-
-* ``read_slice``, which allowed a single round-trip to perform a
-  search and a read, should be reimplemented via
-  :js:class:`~openerp.web.Query` objects (see:
-  :js:func:`~openerp.web.Model.query`) for clearer and simpler
-  code. ``read_index`` should be replaced by a
-  :js:class:`~openerp.web.Query` as well, combining
-  :js:func:`~openerp.web.Query.offset` and
-  :js:func:`~openerp.web.Query.first`.
-
-Rationale
-~~~~~~~~~
-
-Renaming
-
-    The name *DataSet* exists in the CS community consciousness, and
-    (as its name implies) it's a set of data (often fetched from a
-    database, maybe lazily). OpenERP Web's dataset behaves very
-    differently as it does not store (much) data (only a bunch of ids
-    and just enough state to break things). The name "Model" matches
-    the one used on the Python side for the task of building an RPC
-    proxy to OpenERP objects.
-
-API simplification
-
-    ``DataSet`` has a number of methods which serve as little more
-    than shortcuts, or are there due to domain and context evaluation
-    issues in 6.1.
-
-    The shortcuts really add little value, and OpenERP Web 6.2 embeds
-    a restricted Python evaluator (in javascript) meaning most of the
-    context and domain parsing & evaluation can be moved to the
-    javascript code and does not require cooperative RPC bridging.
-
-DataGroup -> also Model
------------------------
-
-Alongside the deprecation of ``DataSet`` for
-:js:class:`~openerp.web.Model`, OpenERP Web 7.0 also deprecates
-``DataGroup`` and its subtypes in favor of a single method on
-:js:class:`~openerp.web.Query`:
-:js:func:`~openerp.web.Query.group_by`.
-
-Migration guide
-~~~~~~~~~~~~~~~
-
-Rationale
-~~~~~~~~~
-
-While the ``DataGroup`` API worked (mostly), it is quite odd and
-alien-looking, a bit too Smalltalk-inspired (behaves like a
-self-contained flow-control structure for reasons which may or may not
-have been good).
-
-Because it is heavily related to ``DataSet`` (as it *yields*
-``DataSet`` objects), deprecating ``DataSet`` automatically deprecates
-``DataGroup`` (if we want to stay consistent), which is a good time to
-make the API more imperative and look more like what most developers
-are used to.
diff --git a/doc/conf.py b/doc/conf.py
deleted file mode 100644 (file)
index 83fc969..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# OpenERP Technical Documentation configuration file, created by
-# sphinx-quickstart on Fri Feb 17 16:14:06 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append(os.path.abspath('_themes'))
-sys.path.insert(0, os.path.abspath('../addons'))
-sys.path.insert(0, os.path.abspath('..'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'OpenERP Web Developers Documentation'
-copyright = u'2012, OpenERP s.a.'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '7.0'
-# The full version, including alpha/beta/rc tags.
-release = '7.0'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  See the documentation for
-# a list of builtin themes.
-html_theme = 'flask'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = ['_themes']
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-html_sidebars = {
-    'index':    ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'],
-    '**':       ['sidebarlogo.html', 'localtoc.html', 'relations.html',
-                 'sourcelink.html', 'searchbox.html']
-}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'openerp-web-doc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'openerp-web-doc.tex', u'OpenERP Web Developers Documentation',
-   u'OpenERP s.a.', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'openerp-web-doc', u'OpenERP Web Developers Documentation',
-     [u'OpenERP s.a.'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output ------------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-#  dir menu entry, description, category)
-texinfo_documents = [
-  ('index', 'OpenERPWebDocumentation', u'OpenERP Web Developers Documentation',
-   u'OpenERP s.a.', 'OpenERPWebDocumentation', 'Developers documentation for the openerp-web project.',
-   'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-todo_include_todos = True
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {
-    'python': ('http://docs.python.org/', None),
-    'openerpserver': ('http://doc.openerp.com/trunk/developers/server', None),
-    'openerpdev': ('http://doc.openerp.com/trunk/developers', None),
-}
diff --git a/doc/form-notes.rst b/doc/form-notes.rst
deleted file mode 100644 (file)
index 98d4a4d..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-Notes on the usage of the Form View as a sub-widget
-===================================================
-
-Undocumented stuff
-------------------
-
-* ``initial_mode`` *option* defines the starting mode of the form
-  view, one of ``view`` and ``edit`` (?). Default value is ``view``
-  (non-editable form).
-
-* ``embedded_view`` *attribute* has to be set separately when
-  providing a view directly, no option available for that usage.
-
-  * View arch **must** contain node with
-    ``@class="oe_form_container"``, otherwise everything will break
-    without any info
-
-  * Root element of view arch not being ``form`` may or may not work
-    correctly, no idea.
-
-  * Freeform views => ``@version="7.0"``
-
-* Form is not entirely loaded (some widgets may not appear) unless
-  ``on_record_loaded`` is called (or ``do_show``, which itself calls
-  ``on_record_loaded``).
-
-* "Empty" form => ``on_button_new`` (...), or manually call
-  ``default_get`` + ``on_record_loaded``
-
-* Form fields default to width: 100%, padding, !important margin, can
-  be reached via ``.oe_form_field``
-
-* Form *will* render buttons and a pager, offers options to locate
-  both outside of form itself (``$buttons`` and ``$pager``), providing
-  empty jquery objects (``$()``) seems to stop displaying both but not
-  sure if there are deleterious side-effects.
-
-  Other options:
-
-  * Pass in ``$(document.createDocumentFragment)`` to ensure it's a
-    DOM-compatible tree completely outside of the actual DOM.
-
-  * ???
-
-* readonly fields probably don't have a background, beware if need of
-  overlay
-
-  * What is the difference between ``readonly`` and
-    ``effective_readonly``?
-
-* No facilities for DOM events handling/delegations e.g. handling
-  keyup/keydown/keypress from a form fields into the form's user.
-
-  * Also no way to reverse from a DOM node (e.g. DOMEvent#target) back to a
-    form view field easily
diff --git a/doc/guides/client-action.rst b/doc/guides/client-action.rst
deleted file mode 100644 (file)
index 30f0c7e..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-.. highlight:: javascript
-
-Creating a new client action
-============================
-
-Client actions are the client-side version of OpenERP's "Server
-Actions": instead of allowing for semi-arbitrary code to be executed
-in the server, they allow for execution of client-customized code.
-
-On the server side, a client action is an action of type
-``ir.actions.client``, which has (at most) two properties: a mandatory
-``tag``, which is an arbitrary string by which the client will
-identify the action, and an optional ``params`` which is simply a map
-of keys and values sent to the client as-is (this way, client actions
-can be made generic and reused in multiple contexts).
-
-General Structure
------------------
-
-In the OpenERP Web code, a client action only requires two pieces of
-information:
-
-* Mapping the action's ``tag`` to an object
-
-* Providing said object. Two different types of objects can be mapped
-  to a client action:
-
-  * An OpenERP Web widget, which must inherit from
-    :js:class:`openerp.web.Widget`
-
-  * A regular javascript function
-
-The major difference is in the lifecycle of these:
-
-* if the client action maps to a function, the function will simply be
-  called when executing the action. The function can have no further
-  interaction with the Web Client itself, although it can return an
-  action which will be executed after it.
-
-* if, on the other hand, the client action maps to a
-  :js:class:`~openerp.web.Widget`, that
-  :js:class:`~openerp.web.Widget` will be instantiated and added to
-  the web client's canvas, with the usual
-  :js:class:`~openerp.web.Widget` lifecycle (essentially, it will
-  either take over the content area of the client or it will be
-  integrated within a dialog).
-
-For example, to create a client action displaying a ``res.widget``
-object::
-
-    // Registers the object 'openerp.web_dashboard.Widget' to the client
-    // action tag 'board.home.widgets'
-    instance.web.client_actions.add(
-        'board.home.widgets', 'openerp.web_dashboard.Widget');
-    instance.web_dashboard.Widget = instance.web.Widget.extend({
-        template: 'HomeWidget'
-    });
-
-At this point, the generic :js:class:`~openerp.web.Widget` lifecycle
-takes over, the template is rendered, inserted in the client DOM,
-bound on the object's ``$el`` property and the object is started.
-
-If the client action takes parameters, these parameters are passed in as a
-second positional parameter to the constructor::
-
-    init: function (parent, params) {
-        // execute the Widget's init
-        this._super(parent);
-        // board.home.widgets only takes a single param, the identifier of the
-        // res.widget object it should display. Store it for later
-        this.widget_id = params.widget_id;
-    }
-
-More complex initialization (DOM manipulations, RPC requests, ...)
-should be performed in the :js:func:`~openerp.web.Widget.start()`
-method.
-
-.. note::
-
-    As required by :js:class:`~openerp.web.Widget`'s contract, if
-    :js:func:`~openerp.web.Widget.start()` executes any asynchronous
-    code it should return a ``$.Deferred`` so callers know when it's
-    ready for interaction.
-
-    Although generally speaking client actions are not really
-    interacted with.
-
-.. code-block:: javascript
-
-    start: function () {
-        return $.when(
-            this._super(),
-            // Simply read the res.widget object this action should display
-            new instance.web.Model('res.widget').call(
-                'read', [[this.widget_id], ['title']])
-                .then(this.proxy('on_widget_loaded'));
-    }
-
-The client action can then behave exactly as it wishes to within its
-root (``this.$el``). In this case, it performs further renderings once
-its widget's content is retrieved::
-
-    on_widget_loaded: function (widgets) {
-        var widget = widgets[0];
-        var url = _.sprintf(
-            '/web_dashboard/widgets/content?session_id=%s&widget_id=%d',
-            this.session.session_id, widget.id);
-        this.$el.html(QWeb.render('HomeWidget.content', {
-            widget: widget,
-            url: url
-        }));
-    }
diff --git a/doc/index.rst b/doc/index.rst
deleted file mode 100644 (file)
index 6a0d8de..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-.. OpenERP Web documentation master file, created by
-   sphinx-quickstart on Fri Mar 18 16:31:55 2011.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Welcome to OpenERP Web's documentation!
-=======================================
-
-Contents:
-
-.. toctree::
-    :maxdepth: 1
-
-    changelog-7.0
-
-    async
-    rpc
-
-    widget
-    search-view
-
-    list-view
-    form-notes
-
-    guides/client-action
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/doc/list-view.rst b/doc/list-view.rst
deleted file mode 100644 (file)
index b7cdc1c..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-List View
-=========
-
-Style Hooks
------------
-
-The list view provides a few style hook classes for re-styling of list views in
-various situations:
-
-``.oe_list``
-
-    The root element of the list view, styling rules should be rooted
-    on that class.
-
-``table.oe_list_content``
-
-    The root table for the listview, accessory components may be
-    generated or added outside this section, this is the list view
-    "proper".
-
-``.oe_list_buttons``
-
-    The action buttons array for the list view, with its sub-elements
-
-    ``.oe_list_add``
-
-        The default "Create"/"Add" button of the list view
-
-    ``.oe_alternative``
-
-        The "alternative choice" for the list view, by default text
-        along the lines of "or import" with a link.
-
-``.oe_list_field_cell``
-
-    The cell (``td``) for a given field of the list view, cells which
-    are *not* fields (e.g. name of a group, or number of items in a
-    group) will not have this class. The field cell can be further
-    specified:
-
-    ``.oe_number``
-
-        Numeric cell types (integer and float)
-
-    ``.oe_button``
-
-        Action button (``button`` tag in the view) inside the cell
-
-    ``.oe_readonly``
-
-        Readonly field cell
-
-    ``.oe_list_field_$type``
-
-        Additional class for the precise type of the cell, ``$type``
-        is the field's @widget if there is one, otherwise it's the
-        field's type.
-
-``.oe_list_record_selector``
-
-    Selector cells
-
-Editable list view
-++++++++++++++++++
-
-The editable list view module adds a few supplementary style hook
-classes, for edition situations:
-
-``.oe_list_editable``
-
-    Added to the ``.oe_list`` when the list is editable (however that
-    was done). The class may be removed on-the-fly if the list becomes
-    non-editable.
-
-``.oe_editing``
-
-    Added to both ``.oe_list`` and ``.oe_list_button`` (as the
-    buttons may be outside of the list view) when a row of the list is
-    currently being edited.
-
-``tr.oe_edition``
-
-    Class set on the row being edited itself. Note that the edition
-    form is *not* contained within the row, this allows for styling or
-    modifying the row while it's being edited separately. Mostly for
-    fields which can not be edited (e.g. read-only fields).
-
-Columns display customization
------------------------------
-
-The list view provides a registry to
-:js:class:`openerp.web.list.Column` objects allowing for the
-customization of a column's display (e.g. so that a binary field is
-rendered as a link to the binary file directly in the list view).
-
-The registry is ``instance.web.list.columns``, the keys are of the
-form ``tag.type`` where ``tag`` can be ``field`` or ``button``, and
-``type`` can be either the field's type or the field's ``@widget`` (in
-the view).
-
-Most of the time, you'll want to define a ``tag.widget`` key
-(e.g. ``field.progressbar``).
-
-.. js:class:: openerp.web.list.Column(id, tag, attrs)
-
-    .. js:function:: openerp.web.list.Column.format(record_data, options)
-
-        Top-level formatting method, returns an empty string if the
-        column is invisible (unless the ``process_modifiers=false``
-        option is provided); returns ``options.value_if_empty`` or an
-        empty string if there is no value in the record for the
-        column.
-
-        Otherwise calls :js:func:`~openerp.web.list.Column._format`
-        and returns its result.
-
-        This method only needs to be overridden if the column has no
-        concept of values (and needs to bypass that check), for a
-        button for instance.
-
-        Otherwise, custom columns should generally override
-        :js:func:`~openerp.web.list.Column._format` instead.
-
-        :returns: String
-
-    .. js:function:: openerp.web.list.Column._format(record_data, options)
-
-        Never called directly, called if the column is visible and has
-        a value.
-
-        The default implementation calls
-        :js:func:`~openerp.web.format_value` and htmlescapes the
-        result (via ``_.escape``).
-
-        Note that the implementation of
-        :js:func:`~openerp.web.list.Column._format` *must* escape the
-        data provided to it, its output will *not* be escaped by
-        :js:func:`~openerp.web.list.Column.format`.
-
-        :returns: String
-
-Editable list view
-------------------
-
-List view edition is an extension to the base listview providing the
-capability of inline record edition by delegating to an embedded form
-view.
-
-Editability status
-++++++++++++++++++
-
-The editability status of a list view can be queried through the
-:js:func:`~openerp.web.ListView.editable` method, will return a falsy
-value if the listview is not currently editable.
-
-The editability status is based on three flags:
-
-``tree/@editable``
-
-    If present, can be either ``"top"`` or ``"bottom"``. Either will
-    make the list view editable, with new records being respectively
-    created at the top or at the bottom of the view.
-
-``context.set_editable``
-
-    Boolean flag extracted from a search context (during the
-    :js:func:`~openerp.web.ListView.do_search`` handler), ``true``
-    will make the view editable (from the top), ``false`` or the
-    absence of the flag is a noop.
-
-``defaults.editable``
-
-    Like ``tree/@editable``, one of absent (``null``)), ``"top"`` or
-    ``"bottom"``, fallback for the list view if none of the previous
-    two flags are set.
-
-These three flags can only *make* a listview editable, they can *not*
-override a previously set flag. To do that, a listview user should
-instead cancel :ref:`the edit:before event <listview-edit-before>`.
-
-The editable list view module adds a number of methods to the list
-view, on top of implementing the :js:class:`EditorDelegate` protocol:
-
-Interaction Methods
-+++++++++++++++++++
-
-.. js:function:: openerp.web.ListView.ensure_saved
-
-    Attempts to resolve the pending edition, if any, by saving the
-    edited row's current state.
-
-    :returns: delegate resolving to all editions having been saved, or
-              rejected if a pending edition could not be saved
-              (e.g. validation failure)
-
-.. js:function:: openerp.web.ListView.start_edition([record][, options])
-
-    Starts editing the provided record inline, through an overlay form
-    view of editable fields in the record.
-
-    If no record is provided, creates a new one according to the
-    editability configuration of the list view.
-
-    This method resolves any pending edition when invoked, before
-    starting a new edition.
-
-    :param record: record to edit, or null to create a new record
-    :type record: :js:class:`~openerp.web.list.Record`
-    :param EditOptions options:
-    :returns: delegate to the form used for the edition
-
-.. js:function:: openerp.web.ListView.save_edition
-
-    Resolves the pending edition.
-
-    :returns: delegate to the save being completed, resolves to an
-              object with two attributes ``created`` (flag indicating
-              whether the saved record was just created or was
-              updated) and ``record`` the reloaded record having been
-              edited.
-
-.. js:function:: openerp.web.ListView.cancel_edition([force=false])
-
-    Cancels pending edition, cleans up the list view in case of
-    creation (removes the empty record being created).
-
-    :param Boolean force: doesn't check if the user has added any
-                          data, discards the edition unconditionally
-
-Utility Methods
-+++++++++++++++
-
-.. js:function:: openerp.web.ListView.get_cells_for(row)
-
-    Extracts the cells from a listview row, and puts them in a
-    {fieldname: cell} mapping for analysis and manipulation.
-
-    :param jQuery row:
-    :rtype: Object
-
-.. js:function:: openerp.web.ListView.with_event(event_name, event, action[, args][, trigger_params])
-
-    Executes ``action`` in the context of the view's editor,
-    bracketing it with cancellable event signals.
-
-    :param String event_name: base name for the bracketing event, will
-                              be postfixed by ``:before`` and
-                              ``:after`` before being called
-                              (respectively before and after
-                              ``action`` is executed)
-    :param Object event: object passed to the ``:before`` event
-                         handlers.
-    :param Function action: function called with the view's editor as
-                            its ``this``. May return a deferred.
-    :param Array args: arguments passed to ``action``
-    :param Array trigger_params: arguments passed to the ``:after``
-                                 event handler alongside the results
-                                 of ``action``
-
-Behavioral Customizations
-+++++++++++++++++++++++++
-
-.. js:function:: openerp.web.ListView.handle_onwrite(record)
-
-    Implements the handling of the ``onwrite`` listview attribute:
-    calls the RPC methods specified by ``@onwrite``, and if that
-    method returns an array of ids loads or reloads the records
-    corresponding to those ids.
-
-    :param record: record being written having triggered the
-                   ``onwrite`` callback
-    :type record: openerp.web.list.Record
-    :returns: deferred to all reloadings being done
-
-Events
-++++++
-
-For simpler interactions by/with external users of the listview, the
-view provides a number of dedicated events to its lifecycle.
-
-.. note:: if an event is defined as *cancellable*, it means its first
-          parameter is an object on which the ``cancel`` attribute can
-          be set. If the ``cancel`` attribute is set, the view will
-          abort its current behavior as soon as possible, and rollback
-          any state modification.
-
-          Generally speaking, an event should only be cancelled (by
-          setting the ``cancel`` flag to ``true``), uncancelling an
-          event is undefined as event handlers are executed on a
-          first-come-first-serve basis and later handlers may
-          re-cancel an uncancelled event.
-
-.. _listview-edit-before:
-
-``edit:before`` *cancellable*
-
-    Invoked before the list view starts editing a record.
-
-    Provided with an event object with a single property ``record``,
-    holding the attributes of the record being edited (``record`` is
-    empty *but not null* for a new record)
-
-``edit:after``
-
-    Invoked after the list view has gone into an edition state,
-    provided with the attributes of the record being edited (see
-    ``edit:before``) as first parameter and the form used for the
-    edition as second parameter.
-
-``save:before`` *cancellable*
-
-    Invoked right before saving a pending edition, provided with an
-    event object holding the listview's editor (``editor``) and the
-    edition form (``form``)
-
-``save:after``
-
-    Invoked after a save has been completed
-
-``cancel:before`` *cancellable*
-
-    Invoked before cancelling a pending edition, provided with the
-    same information as ``save:before``.
-
-``cancel:after``
-
-    Invoked after a pending edition has been cancelled.
-
-DOM events
-++++++++++
-
-The list view has grown hooks for the ``keyup`` event on its edition
-form (during edition): any such event bubbling out of the edition form
-will be forwarded to a method ``keyup_EVENTNAME``, where ``EVENTNAME``
-is the name of the key in ``$.ui.keyCode``.
-
-The method will also get the event object (originally passed to the
-``keyup`` handler) as its sole parameter.
-
-The base editable list view has handlers for the ``ENTER`` and
-``ESCAPE`` keys.
-
-Editor
-------
-
-The list-edition modules does not generally interact with the embedded
-formview, delegating instead to its
-:js:class:`~openerp.web.list.Editor`.
-
-.. js:class:: openerp.web.list.Editor(parent[, options])
-
-    The editor object provides a more convenient interface to form
-    views, and simplifies the usage of form views for semi-arbitrary
-    edition of stuff.
-
-    However, the editor does *not* task itself with being internally
-    consistent at this point: calling
-    e.g. :js:func:`~openerp.web.list.Editor.edit` multiple times in a
-    row without saving or cancelling each edit is undefined.
-
-    :param parent:
-    :type parent: :js:class:`~openerp.web.Widget`
-    :param EditorOptions options:
-
-    .. js:function:: openerp.web.list.Editor.is_editing([record_state])
-
-        Indicates whether the editor is currently in the process of
-        providing edition for a record.
-
-        Can be filtered by the state of the record being edited
-        (whether it's a record being *created* or a record being
-        *altered*), in which case it asserts both that an edition is
-        underway and that the record being edited respectively does
-        not yet exist in the database or already exists there.
-
-        :param record_state: state of the record being edited.
-                             Either ``"new"`` or ``"edit"``.
-        :type record_state: String
-        :rtype: Boolean
-
-    .. js:function:: openerp.web.list.Editor.edit(record, configureField[, options])
-
-        Loads the provided record into the internal form view and
-        displays the form view.
-
-        Will also attempt to focus the first visible field of the form
-        view.
-
-        :param Object record: record to load into the form view
-                              (key:value mapping similar to the result
-                              of a ``read``)
-        :param configureField: function called with each field of the
-                               form view right after the form is
-                               displayed, lets whoever called this
-                               method do some last-minute
-                               configuration of form fields.
-        :type configureField: Function<String, openerp.web.form.Field>
-        :param EditOptions options:
-        :returns: jQuery delegate to the form object
-
-    .. js:function:: openerp.web.list.Editor.save
-
-        Attempts to save the internal form, then hide it
-
-        :returns: delegate to the record under edition (with ``id``
-                  added for a creation). The record is not updated
-                  from when it was passed in, aside from the ``id``
-                  attribute.
-
-    .. js:function:: openerp.web.list.Editor.cancel([force=false])
-
-        Attemps to cancel the edition of the internal form, then hide
-        the form
-
-        :param Boolean force: unconditionally cancels the edition of
-                              the internal form, even if the user has
-                              already entered data in it.
-        :returns: delegate to the record under edition
-
-.. js:class:: EditorOptions
-
-    .. js:attribute:: EditorOptions.formView
-
-        Form view (sub)-class to instantiate and delegate edition to.
-
-        By default, :js:class:`~openerp.web.FormView`
-
-    .. js:attribute:: EditorOptions.delegate
-
-        Object used to get various bits of information about how to
-        display stuff.
-
-        By default, uses the editor's parent widget. See
-        :js:class:`EditorDelegate` for the methods and attributes to
-        provide.
-
-.. js:class:: EditorDelegate
-
-    Informal protocol defining the methods and attributes expected of
-    the :js:class:`~openerp.web.list.Editor`'s delegate.
-
-    .. js:attribute:: EditorDelegate.dataset
-
-        The dataset passed to the form view to synchronize the form
-        view and the outer widget.
-
-    .. js:function:: EditorDelegate.edition_view(editor)
-
-        Called by the :js:class:`~openerp.web.list.Editor` object to
-        get a form view (JSON) to pass along to the form view it
-        created.
-
-        The result should be a valid form view, see :doc:`Form Notes
-        <form-notes>` for various peculiarities of the form view
-        format.
-
-        :param editor: editor object asking for the view
-        :type editor: :js:class:`~openerp.web.list.Editor`
-        :returns: form view
-        :rtype: Object
-
-    .. js:function:: EditorDelegate.prepends_on_create
-
-        By default, the :js:class:`~openerp.web.list.Editor` will
-        append the ids of newly created records to the
-        :js:attr:`EditorDelegate.dataset`. If this method returns
-        ``true``, it will prepend these ids instead.
-
-        :returns: whether new records should be prepended to the
-                  dataset (instead of appended)
-        :rtype: Boolean
-
-
-.. js:class:: EditOptions
-
-    Options object optionally passed into a method starting an edition
-    to configure its setup and behavior
-
-    .. js:attribute:: focus_field
-
-        Name of the field to set focus on after setting up the edition
-        of the record.
-
-        If this option is not provided, or the requested field can not
-        be focused (invisible, readonly or not in the view), the first
-        visible non-readonly field is focused.
-
-Changes from 6.1
-----------------
-
-* The editable listview behavior has been rewritten pretty much from
-  scratch, any code touching on editability will have to be modified
-
-  * The overloading of :js:class:`~openerp.web.ListView.Groups` and
-    :js:class:`~openerp.web.ListView.List` for editability has been
-    drastically simplified, and most of the behavior has been moved to
-    the list view itself. Only
-    :js:func:`~openerp.web.ListView.List.row_clicked` is still
-    overridden.
-
-  * A new method ``get_row_for(record) -> jQuery(tr) | null`` has been
-    added to both ListView.List and ListView.Group, it can be called
-    from the list view to get the table row matching a record (if such
-    a row exists).
-
-* :js:func:`~openerp.web.ListView.do_button_action`'s core behavior
-  has been split away to
-  :js:func:`~openerp.web.ListView.handle_button`. This allows bypassing
-  overrides of :js:func:`~openerp.web.ListView.do_button_action` in a
-  parent class.
-
-  Ideally, :js:func:`~openerp.web.ListView.handle_button` should not be
-  overridden.
-
-* Modifiers handling has been improved (all modifiers information
-  should now be available through :js:func:`~Column.modifiers_for`,
-  not just ``invisible``)
-
-* Changed some handling of the list view's record: a record may now
-  have no id, and the listview will handle that correctly (for new
-  records being created) as well as correctly handle the ``id`` being
-  set.
-
-* Extended the internal collections structure of the list view with
-  `#find`_, `#succ`_ and `#pred`_.
-
-.. _#find: http://underscorejs.org/#find
-
-.. _#succ: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:succ
-
-.. _#pred: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:pred
diff --git a/doc/make.bat b/doc/make.bat
deleted file mode 100644 (file)
index 3e72cad..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-@ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
-       set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
-       set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
-       :help
-       echo.Please use `make ^<target^>` where ^<target^> is one of
-       echo.  html       to make standalone HTML files
-       echo.  dirhtml    to make HTML files named index.html in directories
-       echo.  singlehtml to make a single large HTML file
-       echo.  pickle     to make pickle files
-       echo.  json       to make JSON files
-       echo.  htmlhelp   to make HTML files and a HTML help project
-       echo.  qthelp     to make HTML files and a qthelp project
-       echo.  devhelp    to make HTML files and a Devhelp project
-       echo.  epub       to make an epub
-       echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
-       echo.  text       to make text files
-       echo.  man        to make manual pages
-       echo.  changes    to make an overview over all changed/added/deprecated items
-       echo.  linkcheck  to check all external links for integrity
-       echo.  doctest    to run all doctests embedded in the documentation if enabled
-       goto end
-)
-
-if "%1" == "clean" (
-       for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
-       del /q /s %BUILDDIR%\*
-       goto end
-)
-
-if "%1" == "html" (
-       %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The HTML pages are in %BUILDDIR%/html.
-       goto end
-)
-
-if "%1" == "dirhtml" (
-       %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
-       goto end
-)
-
-if "%1" == "singlehtml" (
-       %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
-       goto end
-)
-
-if "%1" == "pickle" (
-       %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can process the pickle files.
-       goto end
-)
-
-if "%1" == "json" (
-       %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can process the JSON files.
-       goto end
-)
-
-if "%1" == "htmlhelp" (
-       %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
-       goto end
-)
-
-if "%1" == "qthelp" (
-       %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
-       echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenERPWeb.qhcp
-       echo.To view the help file:
-       echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenERPWeb.ghc
-       goto end
-)
-
-if "%1" == "devhelp" (
-       %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished.
-       goto end
-)
-
-if "%1" == "epub" (
-       %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The epub file is in %BUILDDIR%/epub.
-       goto end
-)
-
-if "%1" == "latex" (
-       %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
-       goto end
-)
-
-if "%1" == "text" (
-       %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The text files are in %BUILDDIR%/text.
-       goto end
-)
-
-if "%1" == "man" (
-       %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Build finished. The manual pages are in %BUILDDIR%/man.
-       goto end
-)
-
-if "%1" == "changes" (
-       %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.The overview file is in %BUILDDIR%/changes.
-       goto end
-)
-
-if "%1" == "linkcheck" (
-       %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
-       goto end
-)
-
-if "%1" == "doctest" (
-       %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
-       if errorlevel 1 exit /b 1
-       echo.
-       echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
-       goto end
-)
-
-:end
diff --git a/doc/rpc.rst b/doc/rpc.rst
deleted file mode 100644 (file)
index 4787978..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-Outside the box: network interactions
-=====================================
-
-Building static displays is all nice and good and allows for neat
-effects (and sometimes you're given data to display from third parties
-so you don't have to make any effort), but a point generally comes
-where you'll want to talk to the world and make some network requests.
-
-OpenERP Web provides two primary APIs to handle this, a low-level
-JSON-RPC based API communicating with the Python section of OpenERP
-Web (and of your addon, if you have a Python part) and a high-level
-API above that allowing your code to talk directly to the OpenERP
-server, using familiar-looking calls.
-
-All networking APIs are :doc:`asynchronous </async>`. As a result, all
-of them will return :js:class:`Deferred` objects (whether they resolve
-those with values or not). Understanding how those work before before
-moving on is probably necessary.
-
-High-level API: calling into OpenERP models
--------------------------------------------
-
-Access to OpenERP object methods (made available through XML-RPC from
-the server) is done via the :js:class:`openerp.web.Model` class. This
-class maps onto the OpenERP server objects via two primary methods,
-:js:func:`~openerp.web.Model.call` and
-:js:func:`~openerp.web.Model.query`.
-
-:js:func:`~openerp.web.Model.call` is a direct mapping to the
-corresponding method of the OpenERP server object. Its usage is
-similar to that of the OpenERP Model API, with three differences:
-
-* The interface is :doc:`asynchronous </async>`, so instead of
-  returning results directly RPC method calls will return
-  :js:class:`Deferred` instances, which will themselves resolve to the
-  result of the matching RPC call.
-
-* Because ECMAScript 3/Javascript 1.5 doesnt feature any equivalent to
-  ``__getattr__`` or ``method_missing``, there needs to be an explicit
-  method to dispatch RPC methods.
-
-* No notion of pooler, the model proxy is instantiated where needed,
-  not fetched from an other (somewhat global) object
-
-.. code-block:: javascript
-
-    var Users = new Model('res.users');
-
-    Users.call('change_password', ['oldpassword', 'newpassword'],
-                      {context: some_context}).then(function (result) {
-        // do something with change_password result
-    });
-
-:js:func:`~openerp.web.Model.query` is a shortcut for a builder-style
-interface to searches (``search`` + ``read`` in OpenERP RPC terms). It
-returns a :js:class:`~openerp.web.Query` object which is immutable but
-allows building new :js:class:`~openerp.web.Query` instances from the
-first one, adding new properties or modifiying the parent object's:
-
-.. code-block:: javascript
-
-    Users.query(['name', 'login', 'user_email', 'signature'])
-         .filter([['active', '=', true], ['company_id', '=', main_company]])
-         .limit(15)
-         .all().then(function (users) {
-        // do work with users records
-    });
-
-The query is only actually performed when calling one of the query
-serialization methods, :js:func:`~openerp.web.Query.all` and
-:js:func:`~openerp.web.Query.first`. These methods will perform a new
-RPC call every time they are called.
-
-For that reason, it's actually possible to keep "intermediate" queries
-around and use them differently/add new specifications on them.
-
-.. js:class:: openerp.web.Model(name)
-
-    .. js:attribute:: openerp.web.Model.name
-
-        name of the OpenERP model this object is bound to
-
-    .. js:function:: openerp.web.Model.call(method[, args][, kwargs])
-
-         Calls the ``method`` method of the current model, with the
-         provided positional and keyword arguments.
-
-         :param String method: method to call over rpc on the
-                               :js:attr:`~openerp.web.Model.name`
-         :param Array<> args: positional arguments to pass to the
-                              method, optional
-         :param Object<> kwargs: keyword arguments to pass to the
-                                 method, optional
-         :rtype: Deferred<>         
-
-    .. js:function:: openerp.web.Model.query(fields)
-
-         :param Array<String> fields: list of fields to fetch during
-                                      the search
-         :returns: a :js:class:`~openerp.web.Query` object
-                   representing the search to perform
-
-.. js:class:: openerp.web.Query(fields)
-
-    The first set of methods is the "fetching" methods. They perform
-    RPC queries using the internal data of the object they're called
-    on.
-
-    .. js:function:: openerp.web.Query.all()
-
-        Fetches the result of the current
-        :js:class:`~openerp.web.Query` object's search.
-
-        :rtype: Deferred<Array<>>
-
-    .. js:function:: openerp.web.Query.first()
-
-       Fetches the **first** result of the current
-       :js:class:`~openerp.web.Query`, or ``null`` if the current
-       :js:class:`~openerp.web.Query` does have any result.
-
-       :rtype: Deferred<Object | null>
-
-    .. js:function:: openerp.web.Query.count()
-
-       Fetches the number of records the current
-       :js:class:`~openerp.web.Query` would retrieve.
-
-       :rtype: Deferred<Number>
-
-    .. js:function:: openerp.web.Query.group_by(grouping...)
-
-       Fetches the groups for the query, using the first specified
-       grouping parameter
-
-       :param Array<String> grouping: Lists the levels of grouping
-                                      asked of the server. Grouping
-                                      can actually be an array or
-                                      varargs.
-       :rtype: Deferred<Array<openerp.web.QueryGroup>> | null
-
-    The second set of methods is the "mutator" methods, they create a
-    **new** :js:class:`~openerp.web.Query` object with the relevant
-    (internal) attribute either augmented or replaced.
-
-    .. js:function:: openerp.web.Query.context(ctx)
-
-       Adds the provided ``ctx`` to the query, on top of any existing
-       context
-
-    .. js:function:: openerp.web.Query.filter(domain)
-
-       Adds the provided domain to the query, this domain is
-       ``AND``-ed to the existing query domain.
-
-    .. js:function:: opeenrp.web.Query.offset(offset)
-
-       Sets the provided offset on the query. The new offset
-       *replaces* the old one.
-
-    .. js:function:: openerp.web.Query.limit(limit)
-
-       Sets the provided limit on the query. The new limit *replaces*
-       the old one.
-
-    .. js:function:: openerp.web.Query.order_by(fields…)
-
-       Overrides the model's natural order with the provided field
-       specifications. Behaves much like Django's `QuerySet.order_by
-       <https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by>`_:
-
-       * Takes 1..n field names, in order of most to least importance
-         (the first field is the first sorting key). Fields are
-         provided as strings.
-
-       * A field specifies an ascending order, unless it is prefixed
-         with the minus sign "``-``" in which case the field is used
-         in the descending order
-
-       Divergences from Django's sorting include a lack of random sort
-       (``?`` field) and the inability to "drill down" into relations
-       for sorting.
-
-Aggregation (grouping)
-~~~~~~~~~~~~~~~~~~~~~~
-
-OpenERP has powerful grouping capacities, but they are kind-of strange
-in that they're recursive, and level n+1 relies on data provided
-directly by the grouping at level n. As a result, while ``read_group``
-works it's not a very intuitive API.
-
-OpenERP Web 7.0 eschews direct calls to ``read_group`` in favor of
-calling a method of :js:class:`~openerp.web.Query`, `much in the way
-it is one in SQLAlchemy
-<http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.group_by>`_ [#]_:
-
-.. code-block:: javascript
-
-    some_query.group_by(['field1', 'field2']).then(function (groups) {
-        // do things with the fetched groups
-    });
-
-This method is asynchronous when provided with 1..n fields (to group
-on) as argument, but it can also be called without any field (empty
-fields collection or nothing at all). In this case, instead of
-returning a Deferred object it will return ``null``.
-
-When grouping criterion come from a third-party and may or may not
-list fields (e.g. could be an empty list), this provides two ways to
-test the presence of actual subgroups (versus the need to perform a
-regular query for records):
-
-* A check on ``group_by``'s result and two completely separate code
-  paths
-
-  .. code-block:: javascript
-
-      var groups;
-      if (groups = some_query.group_by(gby)) {
-          groups.then(function (gs) {
-              // groups
-          });
-      }
-      // no groups
-
-* Or a more coherent code path using :js:func:`when`'s ability to
-  coerce values into deferreds:
-
-  .. code-block:: javascript
-
-      $.when(some_query.group_by(gby)).then(function (groups) {
-          if (!groups) {
-              // No grouping
-          } else {
-              // grouping, even if there are no groups (groups
-              // itself could be an empty array)
-          }
-      });
-
-The result of a (successful) :js:func:`~openerp.web.Query.group_by` is
-an array of :js:class:`~openerp.web.QueryGroup`.
-
-Low-level API: RPC calls to Python side
----------------------------------------
-
-While the previous section is great for calling core OpenERP code
-(models code), it does not work if you want to call the Python side of
-OpenERP Web.
-
-For this, a lower-level API exists on on
-:js:class:`~openerp.web.Connection` objects (usually available through
-``openerp.connection``): the ``rpc`` method.
-
-This method simply takes an absolute path (which is the combination of
-the Python controller's ``_cp_path`` attribute and the name of the
-method you want to call) and a mapping of attributes to values (applied
-as keyword arguments on the Python method [#]_). This function fetches
-the return value of the Python methods, converted to JSON.
-
-For instance, to call the ``eval_domain_and_context`` of the
-:class:`~web.controllers.main.Session` controller:
-
-.. code-block:: javascript
-
-    openerp.connection.rpc('/web/session/eval_domain_and_context', {
-        domains: ds,
-        contexts: cs
-    }).then(function (result) {
-        // handle result
-    });
-
-.. [#] with a small twist: SQLAlchemy's ``orm.query.Query.group_by``
-       is not terminal, it returns a query which can still be altered.
-
-.. [#] except for ``context``, which is extracted and stored in the
-       request object itself.
diff --git a/doc/search-view.rst b/doc/search-view.rst
deleted file mode 100644 (file)
index 16a91c5..0000000
+++ /dev/null
@@ -1,549 +0,0 @@
-Search View
-===========
-
-OpenERP Web 7.0 implements a unified facets-based search view instead
-of the previous form-like search view (composed of buttons and
-multiple fields). The goal for this change is twofold:
-
-* Avoid the common issue of users confusing the search view with a
-  form view and trying to create their records through it (or entering
-  all their data, hitting the ``Create`` button expecting their record
-  to be created and losing everything).
-
-* Improve the looks and behaviors of the view, and the fit within
-  OpenERP Web's new design.
-
-The internal structure of the faceted search is inspired by
-`VisualSearch <http://documentcloud.github.com/visualsearch/>`_
-[#previous]_.
-
-As does VisualSearch, the new search view is based on `Backbone`_ and
-makes significant use of Backbone's models and collections (OpenERP
-Web's widgets make a good replacement for Backbone's own views). As a
-result, understanding the implementation details of the OpenERP Web 7
-search view also requires a basic understanding of Backbone's models,
-collections and events.
-
-.. note::
-
-    This document may mention *fetching* data. This is a shortcut for
-    "returning a :js:class:`Deferred` to [whatever is being
-    fetched]". Unless further noted, the function or method may opt to
-    return nothing by fetching ``null`` (which can easily be done by
-    returning ``$.when(null)``, which simply wraps the ``null`` in a
-    Deferred).
-
-Working with the search view: creating new inputs
--------------------------------------------------
-
-The primary component of search views, as with all other OpenERP
-views, are inputs. The search view has two types of inputs — filters
-and fields — but only one is easly customizable: fields.
-
-The mapping from OpenERP field types (and widgets) to search view
-objects is stored in the ``openerp.web.search.fields``
-:js:class:`~openerp.web.Registry` where new field types and widgets
-can be added.
-
-Search view inputs have four main roles:
-
-Loading defaults
-++++++++++++++++
-
-Once the search view has initialized all its inputs, it will call
-:js:func:`~openerp.web.search.Input.facet_for_defaults` on each input,
-passing it a mapping (a javascript object) of ``name:value`` extracted
-from the action's context.
-
-This method should fetch a :js:class:`~openerp.web.search.Facet` (or
-an equivalent object) for the field's default value if applicable (if
-a default value for the field is found in the ``defaults`` mapping).
-
-A default implementation is provided which checks if ``defaults``
-contains a non-falsy value for the field's ``@name`` and calls
-:js:func:`openerp.web.search.Input.facet_for` with that value.
-
-There is no default implementation of
-:js:func:`openerp.web.search.Input.facet_for` [#no_impl]_, but
-:js:class:`openerp.web.search.Field` provides one, which uses the
-value as-is to fetch a :js:class:`~openerp.web.search.Facet`.
-
-Providing completions
-+++++++++++++++++++++
-
-An important component of the new search view is the auto-completion
-pane, and the task of providing completion items is delegated to
-inputs through the :js:func:`~openerp.web.search.Input.complete`
-method.
-
-This method should take a single argument (the string being typed by
-the user) and should fetch an ``Array`` of possible completions
-[#completion]_.
-
-A default implementation is provided which fetches nothing.
-
-A completion item is a javascript object with two keys (technically it
-can have any number of keys, but only these two will be used by the
-search view):
-
-``label``
-
-    The string which will be displayed in the completion pane. It may
-    be formatted using HTML (inline only), as a result if ``value`` is
-    interpolated into it it *must* be escaped. ``_.escape`` can be
-    used for this.
-
-``facet``
-
-    Either a :js:class:`~openerp.web.search.Facet` object or (more
-    commonly) the corresponding attributes object. This is the facet
-    which will be inserted into the search query if the completion
-    item is selected by the user.
-
-If the ``facet`` is not provided (not present, ``null``, ``undefined``
-or any other falsy value), the completion item will not be selectable
-and will act as a section title of sort (the ``label`` will be
-formatted differently). If an input *may* fetch multiple completion
-items, it *should* prefix those with a section title using its own
-name. This has no technical consequence but is clearer for users.
-
-Providing drawer/supplementary UI
-+++++++++++++++++++++++++++++++++
-
-For some inputs (fields or not), interaction via autocompletion may be
-awkward or even impossible.
-
-These may opt to being rendered in a "drawer" as well or instead. In
-that case, they will undergo the normal widget lifecycle and be
-rendered inside the drawer.
-
-.. Found no good type-based way to handle this, since there is no MI
-   (so no type-tagging) and it's possible for both Field and non-Field
-   input to be put into the drawer, for whatever reason (e.g. some
-   sort of auto-detector completion item for date widgets, but a
-   second more usual calendar widget in the drawer for more
-   obvious/precise interactions)
-
-Any input can note its desire to be rendered in the drawer by
-returning a truthy value from
-:js:func:`~openerp.web.search.Input.in_drawer`.
-
-By default, :js:func:`~openerp.web.search.Input.in_drawer` returns the
-value of :js:attr:`~openerp.web.search.Input._in_drawer`, which is
-``false``. The behavior can be toggled either by redefining the
-attribute to ``true`` (either on the class or on the input), or by
-overriding :js:func:`~openerp.web.search.Input.in_drawer` itself.
-
-The input will be rendered in the full width of the drawer, it will be
-started only once (per view).
-
-.. todo:: drawer API (if a widget wants to close the drawer in some
-          way), part of the low-level SearchView API/interactions?
-
-
-.. todo:: handle filters and filter groups via a "driver" input which
-          dynamically collects, lays out and renders filters? =>
-          exercises drawer thingies
-
-Converting from facet objects
-+++++++++++++++++++++++++++++
-
-Ultimately, the point of the search view is to allow searching. In
-OpenERP this is done via :ref:`domains <openerpserver:domains>`. On
-the other hand, the OpenERP Web 7 search view's state is modelled
-after a collection of :js:class:`~openerp.web.search.Facet`, and each
-field of a search view may have special requirements when it comes to
-the domains it produces [#special]_.
-
-So there needs to be some way of mapping
-:js:class:`~openerp.web.search.Facet` objects to OpenERP search data.
-
-This is done via an input's
-:js:func:`~openerp.web.search.Input.get_domain` and
-:js:func:`~openerp.web.search.Input.get_context`. Each takes a
-:js:class:`~openerp.web.search.Facet` and returns whatever it's
-supposed to generate (a domain or a context, respectively). Either can
-return ``null`` if the current value does not map to a domain or
-context, and can throw an :js:class:`~openerp.web.search.Invalid`
-exception if the value is not valid at all for the field.
-
-.. note::
-
-    The :js:class:`~openerp.web.search.Facet` object can have any
-    number of values (from 1 upwards)
-
-.. note::
-
-    There is a third conversion method,
-    :js:func:`~openerp.web.search.Input.get_groupby`, which returns an
-    ``Array`` of groupby domains rather than a single context. At this
-    point, it is only implemented on (and used by) filters.
-
-Programmatic interactions: internal model
------------------------------------------
-
-This new searchview is built around an instance of
-:js:class:`~openerp.web.search.SearchQuery` available as
-:js:attr:`openerp.web.SearchView.query`.
-
-The query is a `backbone collection`_ of
-:js:class:`~openerp.web.search.Facet` objects, which can be interacted
-with directly by external objects or search view controls
-(e.g. widgets displayed in the drawer).
-
-.. js:class:: openerp.web.search.SearchQuery
-
-    The current search query of the search view, provides convenience
-    behaviors for manipulating :js:class:`~openerp.web.search.Facet`
-    on top of the usual `backbone collection`_ methods.
-
-    The query ensures all of its facets contain at least one
-    :js:class:`~openerp.web.search.FacetValue` instance. Otherwise,
-    the facet is automatically removed from the query.
-
-    .. js:function:: openerp.web.search.SearchQuery.add(values, options)
-
-        Overridden from the base ``add`` method so that adding a facet
-        which is *already* in the collection will merge the value of
-        the new facet into the old one rather than add a second facet
-        with different values.
-
-        :param values: facet, facet attributes or array thereof
-        :returns: the collection itself
-
-    .. js:function:: openerp.web.search.SearchQuery.toggle(value, options)
-
-        Convenience method for toggling facet values in a query:
-        removes the values (through the facet itself) if they are
-        present, adds them if they are not. If the facet itself is not
-        in the collection, adds it automatically.
-
-        A toggling is atomic: only one change event will be triggered
-        on the facet regardless of the number of values added to or
-        removed from the facet (if the facet already exists), and the
-        facet is only removed from the query if it has no value *at
-        the end* of the toggling.
-
-        :param value: facet or facet attributes
-        :returns: the collection
-
-.. js:class:: openerp.web.search.Facet
-
-    A `backbone model`_ representing a single facet of the current
-    research. May map to a search field, or to a more complex or
-    fuzzier input (e.g. a custom filter or an advanced search).
-
-    .. js:attribute:: category
-
-        The displayed name of the facet, as a ``String``. This is a
-        backbone model attribute.
-
-    .. js:attribute:: field
-
-        The :js:class:`~openerp.web.search.Input` instance which
-        originally created the facet [#facet-field]_, used to delegate
-        some operations (such as serializing the facet's values to
-        domains and contexts). This is a backbone model attribute.
-
-    .. js:attribute:: values
-
-        :js:class:`~openerp.web.search.FacetValues` as a javascript
-        attribute, stores all the values for the facet and helps
-        propagate their events to the facet. Is also available as a
-        backbone attribute (via ``#get`` and ``#set``) in which cases
-        it serializes to and deserializes from javascript arrays (via
-        ``Collection#toJSON`` and ``Collection#reset``).
-
-    .. js:attribute:: [icon]
-
-        optional, a single ASCII letter (a-z or A-Z) mapping to the
-        bundled mnmliconsRegular icon font.
-
-        When a facet with an ``icon`` attribute is rendered, the icon
-        is displayed (in the icon font) in the first section of the
-        facet instead of the ``category``.
-
-        By default, only filters make use of this facility.
-
-.. js:class:: openerp.web.search.FacetValues
-
-    `Backbone collection`_ of
-    :js:class:`~openerp.web.search.FacetValue` instances.
-
-.. js:class:: openerp.web.search.FacetValue
-
-    `Backbone model`_ representing a single value within a facet,
-    represents a pair of (displayed name, logical value).
-
-    .. js:attribute:: label
-
-        Backbone model attribute storing the "displayable"
-        representation of the value, visually output to the
-        user. Must be a string.
-
-    .. js:attribute:: value
-
-        Backbone model attribute storing the logical/internal value
-        (of itself), will be used by
-        :js:class:`~openerp.web.search.Input` to serialize to domains
-        and contexts.
-
-        Can be of any type.
-
-Field services
---------------
-
-:js:class:`~openerp.web.search.Field` provides a default
-implementation of :js:func:`~openerp.web.search.Input.get_domain` and
-:js:func:`~openerp.web.search.Input.get_context` taking care of most
-of the peculiarities pertaining to OpenERP's handling of fields in
-search views. It also provides finer hooks to let developers of new
-fields and widgets customize the behavior they want without
-necessarily having to reimplement all of
-:js:func:`~openerp.web.search.Input.get_domain` or
-:js:func:`~openerp.web.search.Input.get_context`:
-
-.. js:function:: openerp.web.search.Field.get_context(facet)
-
-    If the field has no ``@context``, simply returns
-    ``null``. Otherwise, calls
-    :js:func:`~openerp.web.search.Field.value_from` once for each
-    :js:class:`~openerp.web.search.FacetValue` of the current
-    :js:class:`~openerp.web.search.Facet` (in order to extract the
-    basic javascript object from the
-    :js:class:`~openerp.web.search.FacetValue` then evaluates
-    ``@context`` with each of these values set as ``self``, and
-    returns the union of all these contexts.
-
-    :param facet:
-    :type facet: openerp.web.search.Facet
-    :returns: a context (literal or compound)
-
-.. js:function:: openerp.web.search.Field.get_domain(facet)
-
-    If the field has no ``@filter_domain``, calls
-    :js:func:`~openerp.web.search.Field.make_domain` once with each
-    :js:class:`~openerp.web.search.FacetValue` of the current
-    :js:class:`~openerp.web.search.Facet` as well as the field's
-    ``@name`` and either its ``@operator`` or
-    :js:attr:`~openerp.web.search.Field.default_operator`.
-
-    If the field has an ``@filter_value``, calls
-    :js:func:`~openerp.web.search.Field.value_from` once per
-    :js:class:`~openerp.web.search.FacetValue` and evaluates
-    ``@filter_value`` with each of these values set as ``self``.
-
-    In either case, "ors" all of the resulting domains (using ``|``)
-    if there is more than one
-    :js:class:`~openerp.web.search.FacetValue` and returns the union
-    of the result.
-
-    :param facet:
-    :type facet: openerp.web.search.Facet
-    :returns: a domain (literal or compound)
-
-.. js:function:: openerp.web.search.Field.make_domain(name, operator, facetValue)
-
-    Builds a literal domain from the provided data. Calls
-    :js:func:`~openerp.web.search.Field.value_from` on the
-    :js:class:`~openerp.web.search.FacetValue` and evaluates and sets
-    it as the domain's third value, uses the other two parameters as
-    the first two values.
-
-    Can be overridden to build more complex default domains.
-
-    :param String name: the field's name
-    :param String operator: the operator to use in the field's domain
-    :param facetValue:
-    :type facetValue: openerp.web.search.FacetValue
-    :returns: Array<(String, String, Object)>
-
-.. js:function:: openerp.web.search.Field.value_from(facetValue)
-
-    Extracts a "bare" javascript value from the provided
-    :js:class:`~openerp.web.search.FacetValue`, and returns it.
-
-    The default implementation will simply return the ``value``
-    backbone property of the argument.
-
-    :param facetValue:
-    :type facetValue: openerp.web.search.FacetValue
-    :returns: Object
-
-.. js:attribute:: openerp.web.search.Field.default_operator
-
-    Operator used to build a domain when a field has no ``@operator``
-    or ``@filter_domain``. ``"="`` for
-    :js:class:`~openerp.web.search.Field`
-
-Arbitrary data storage
-----------------------
-
-:js:class:`~openerp.web.search.Facet` and
-:js:class:`~openerp.web.search.FacetValue` objects (and structures)
-provided by your widgets should never be altered by the search view
-(or an other widget). This means you are free to add arbitrary fields
-in these structures if you need to (because you have more complex
-needs than the attributes described in this document).
-
-Ideally this should be avoided, but the possibility remains.
-
-Changes
--------
-
-.. todo:: merge in changelog instead?
-
-The displaying of the search view was significantly altered from
-OpenERP Web 6.1 to OpenERP Web 7.
-
-As a result, while the external API used to interact with the search
-view does not change many internal details — including the interaction
-between the search view and its widgets — were significantly altered:
-
-Internal operations
-+++++++++++++++++++
-
-* :js:func:`openerp.web.SearchView.do_clear` has been removed
-* :js:func:`openerp.web.SearchView.do_toggle_filter` has been removed
-
-Widgets API
-+++++++++++
-
-* :js:func:`openerp.web.search.Widget.render` has been removed
-
-* :js:func:`openerp.web.search.Widget.make_id` has been removed
-
-* Search field objects are not openerp widgets anymore, their
-  ``start`` is not generally called
-
-* :js:func:`~openerp.web.search.Input.clear` has been removed since
-  clearing the search view now simply consists of removing all search
-  facets
-
-* :js:func:`~openerp.web.search.Input.get_domain` and
-  :js:func:`~openerp.web.search.Input.get_context` now take a
-  :js:class:`~openerp.web.search.Facet` as parameter, from which it's
-  their job to get whatever value they want
-
-* :js:func:`~openerp.web.search.Input.get_groupby` has been added. It returns
-  an :js:class:`Array` of context-like constructs. By default, it does not do
-  anything in :js:class:`~openerp.web.search.Field` and it returns the various
-  contexts of its enabled filters in
-  :js:class:`~openerp.web.search.FilterGroup`.
-
-Filters
-+++++++
-
-* :js:func:`openerp.web.search.Filter.is_enabled` has been removed
-
-* :js:class:`~openerp.web.search.FilterGroup` instances are still
-  rendered (and started) in the "advanced search" drawer.
-
-Fields
-++++++
-
-* ``get_value`` has been replaced by
-  :js:func:`~openerp.web.search.Field.value_from` as it now takes a
-  :js:class:`~openerp.web.search.FacetValue` argument (instead of no
-  argument). It provides a default implementation returning the
-  ``value`` property of its argument.
-
-* The third argument to
-  :js:func:`~openerp.web.search.Field.make_domain` is now a
-  :js:class:`~openerp.web.search.FacetValue` so child classes have all
-  the information they need to derive the "right" resulting domain.
-
-Custom filters
-++++++++++++++
-
-Instead of being an intrinsic part of the search view, custom filters
-are now a special case of filter groups. They are treated specially
-still, but much less so than they used to be.
-
-Many To One
-+++++++++++
-
-* Because the autocompletion service is now provided by the search
-  view itself,
-  :js:func:`openerp.web.search.ManyToOneField.setup_autocomplete` has
-  been removed.
-
-Advanced Search
-+++++++++++++++
-
-* The advanced search is now a more standard
-  :js:class:`~openerp.web.search.Input` configured to be rendered in
-  the drawer.
-
-* :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` are
-  now standard widgets, with the "right" behaviors (they don't rebind
-  their ``$element`` in ``start()``)
-
-* The ad-hoc optional setting of the openerp field descriptor on a
-  :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` has
-  been removed, the field descriptor is now passed as second argument
-  to the
-  :js:class:`~openerp.web.search.ExtendedSearchProposition.Field`'s
-  constructor, and bound to its
-  :js:attr:`~openerp.web.search.ExtendedSearchProposition.Field.field`.
-
-* Instead of its former domain triplet ``(field, operator, value)``,
-  :js:func:`~openerp.web.search.ExtendedSearchProposition.get_proposition`
-  now returns an object with two fields ``label`` and ``value``,
-  respectively a human-readable version of the proposition and the
-  corresponding domain triplet for the proposition.
-
-.. [#previous]
-
-    the original view was implemented on top of a monkey-patched
-    VisualSearch, but as our needs diverged from VisualSearch's goal
-    this made less and less sense ultimately leading to a clean-room
-    reimplementation
-
-.. [#no_impl]
-
-    In case you are extending the search view with a brand new type of
-    input
-
-.. [#completion]
-
-    Ideally this array should not hold more than about 10 items, but
-    the search view does not put any constraint on this at the
-    moment. Note that this may change.
-
-.. [#facet-field]
-
-    ``field`` does not actually need to be an instance of
-    :js:class:`~openerp.web.search.Input`, nor does it need to be what
-    created the facet, it just needs to provide the three
-    facet-serialization methods
-    :js:func:`~openerp.web.search.Input.get_domain`,
-    :js:func:`~openerp.web.search.Input.get_context` and
-    :js:func:`~openerp.web.search.Input.get_gropuby`, existing
-    :js:class:`~openerp.web.search.Input` subtypes merely provide
-    convenient base implementation for those methods.
-
-    Complex search view inputs (especially those living in the drawer)
-    may prefer using object literals with the right slots returning
-    closed-over values or some other scheme un-bound to an actual
-    :js:class:`~openerp.web.search.Input`, as
-    :js:class:`~openerp.web.search.CustomFilters` and
-    :js:class:`~openerp.web.search.Advanced` do.
-
-.. [#special]
-
-    search view fields may also bundle context data to add to the
-    search context
-
-.. _Backbone:
-    http://documentcloud.github.com/backbone/
-
-.. _Backbone.Collection:
-.. _Backbone collection:
-    http://documentcloud.github.com/backbone/#Collection
-
-.. _Backbone model:
-    http://documentcloud.github.com/backbone/#Model
-
-.. _commit 3fca87101d:
-    https://github.com/documentcloud/visualsearch/commit/3fca87101d
diff --git a/doc/widget.rst b/doc/widget.rst
deleted file mode 100644 (file)
index ddfe525..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-User Interaction: Widget
-========================
-
-This is the base class for all visual components. It corresponds to an MVC
-view. It provides a number of services to handle a section of a page:
-
-* Rendering with QWeb
-
-* Parenting-child relations
-
-* Life-cycle management (including facilitating children destruction when a
-  parent object is removed)
-
-* DOM insertion, via jQuery-powered insertion methods. Insertion targets can
-  be anything the corresponding jQuery method accepts (generally selectors,
-  DOM nodes and jQuery objects):
-
-  :js:func:`~openerp.base.Widget.appendTo`
-    Renders the widget and inserts it as the last child of the target, uses
-    `.appendTo()`_
-
-  :js:func:`~openerp.base.Widget.prependTo`
-    Renders the widget and inserts it as the first child of the target, uses
-    `.prependTo()`_
-
-  :js:func:`~openerp.base.Widget.insertAfter`
-    Renders the widget and inserts it as the preceding sibling of the target,
-    uses `.insertAfter()`_
-
-  :js:func:`~openerp.base.Widget.insertBefore`
-    Renders the widget and inserts it as the following sibling of the target,
-    uses `.insertBefore()`_
-
-* Backbone-compatible shortcuts
-
-DOM Root
---------
-
-A :js:class:`~openerp.web.Widget` is responsible for a section of the
-page materialized by the DOM root of the widget. The DOM root is
-available via the :js:attr:`~openerp.web.Widget.el` and
-:js:attr:`~openerp.web.Widget.$element` attributes, which are
-respectively the raw DOM Element and the jQuery wrapper around the DOM
-element.
-
-There are two main ways to define and generate this DOM root:
-
-.. js:attribute:: openerp.web.Widget.template
-
-    Should be set to the name of a QWeb template (a
-    :js:class:`String`). If set, the template will be rendered after
-    the widget has been initialized but before it has been
-    started. The root element generated by the template will be set as
-    the DOM root of the widget.
-
-.. js:attribute:: openerp.web.Widget.tagName
-
-    Used if the widget has no template defined. Defaults to ``div``,
-    will be used as the tag name to create the DOM element to set as
-    the widget's DOM root. It is possible to further customize this
-    generated DOM root with the following attributes:
-
-    .. js:attribute:: openerp.web.Widget.id
-
-        Used to generate an ``id`` attribute on the generated DOM
-        root.
-
-    .. js:attribute:: openerp.web.Widget.className
-
-        Used to generate a ``class`` attribute on the generated DOM root.
-
-    .. js:attribute:: openerp.web.Widget.attributes
-
-        Mapping (object literal) of attribute names to attribute
-        values. Each of these k:v pairs will be set as a DOM attribute
-        on the generated DOM root.
-
-    None of these is used in case a template is specified on the widget.
-
-The DOM root can also be defined programmatically by overridding
-
-.. js:function:: openerp.web.Widget.renderElement
-
-    Renders the widget's DOM root and sets it. The default
-    implementation will render a set template or generate an element
-    as described above, and will call
-    :js:func:`~openerp.web.Widget.setElement` on the result.
-
-    Any override to :js:func:`~openerp.web.Widget.renderElement` which
-    does not call its ``_super`` **must** call
-    :js:func:`~openerp.web.Widget.setElement` with whatever it
-    generated or the widget's behavior is undefined.r
-
-    .. note::
-
-        The default :js:func:`~openerp.web.Widget.renderElement` can
-        be called repeatedly, it will *replace* the previous DOM root
-        (using ``replaceWith``). However, this requires that the
-        widget correctly sets and unsets its events (and children
-        widgets). Generally,
-        :js:func:`~openerp.web.Widget.renderElement` should not be
-        called repeatedly unless the widget advertizes this feature.
-
-Accessing DOM content
-~~~~~~~~~~~~~~~~~~~~~
-
-Because a widget is only responsible for the content below its DOM
-root, there is a shortcut for selecting sub-sections of a widget's
-DOM:
-
-.. js:function:: openerp.web.Widget.$(selector)
-
-    Applies the CSS selector specified as parameter to the widget's
-    DOM root.
-
-    .. code-block:: javascript
-
-        this.$(selector);
-
-    is functionally identical to:
-
-    .. code-block:: javascript
-
-        this.$element.find(selector);
-
-    :param String selector: CSS selector
-    :returns: jQuery object
-
-    .. note:: this helper method is compatible with
-              ``Backbone.View.$``
-
-Resetting the DOM root
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. js:function:: openerp.web.Widget.setElement(element)
-
-    Re-sets the widget's DOM root to the provided element, also
-    handles re-setting the various aliases of the DOM root as well as
-    unsetting and re-setting delegated events.
-
-    :param Element element: a DOM element or jQuery object to set as
-                            the widget's DOM root
-
-    .. note:: should be mostly compatible with `Backbone's
-              setElement`_
-
-DOM events handling
--------------------
-
-A widget will generally need to respond to user action within its
-section of the page. This entails binding events to DOM elements.
-
-To this end, :js:class:`~openerp.web.Widget` provides an shortcut:
-
-.. js:attribute:: openerp.web.Widget.events
-
-    Events are a mapping of ``event selector`` (an event name and a
-    CSS selector separated by a space) to a callback. The callback can
-    be either a method name in the widget or a function. In either
-    case, the ``this`` will be set to the widget.
-
-    The selector is used for jQuery's `event delegation`_, the
-    callback will only be triggered for descendants of the DOM root
-    matching the selector [0]_. If the selector is left out (only an
-    event name is specified), the event will be set directly on the
-    widget's DOM root.
-
-.. js:function:: openerp.web.Widget.delegateEvents
-
-    This method is in charge of binding
-    :js:attr:`~openerp.web.Widget.events` to the DOM. It is
-    automatically called after setting the widget's DOM root.
-
-    It can be overridden to set up more complex events than the
-    :js:attr:`~openerp.web.Widget.events` map allows, but the parent
-    should always be called (or :js:attr:`~openerp.web.Widget.events`
-    won't be handled correctly).
-
-.. js:function:: openerp.web.Widget.undelegateEvents
-
-    This method is in charge of unbinding
-    :js:attr:`~openerp.web.Widget.events` from the DOM root when the
-    widget is destroyed or the DOM root is reset, in order to avoid
-    leaving "phantom" events.
-
-    It should be overridden to un-set any event set in an override of
-    :js:func:`~openerp.web.Widget.delegateEvents`.
-
-.. note:: this behavior should be compatible with `Backbone's
-          delegateEvents`_, apart from not accepting any argument.
-
-Subclassing Widget
-------------------
-
-:js:class:`~openerp.base.Widget` is subclassed in the standard manner (via the
-:js:func:`~openerp.base.Class.extend` method), and provides a number of
-abstract properties and concrete methods (which you may or may not want to
-override). Creating a subclass looks like this:
-
-.. code-block:: javascript
-
-    var MyWidget = openerp.base.Widget.extend({
-        // QWeb template to use when rendering the object
-        template: "MyQWebTemplate",
-
-        init: function(parent) {
-            this._super(parent);
-            // insert code to execute before rendering, for object
-            // initialization
-        },
-        start: function() {
-            this._super();
-            // post-rendering initialization code, at this point
-            // ``this.$element`` has been initialized
-            this.$element.find(".my_button").click(/* an example of event binding * /);
-
-            // if ``start`` is asynchronous, return a promise object so callers
-            // know when the object is done initializing
-            return this.rpc(/* … */)
-        }
-    });
-
-The new class can then be used in the following manner:
-
-.. code-block:: javascript
-
-    // Create the instance
-    var my_widget = new MyWidget(this);
-    // Render and insert into DOM
-    my_widget.appendTo(".some-div");
-
-After these two lines have executed (and any promise returned by ``appendTo``
-has been resolved if needed), the widget is ready to be used.
-
-.. note:: the insertion methods will start the widget themselves, and will
-          return the result of :js:func:`~openerp.base.Widget.start()`.
-
-          If for some reason you do not want to call these methods, you will
-          have to first call :js:func:`~openerp.base.Widget.render()` on the
-          widget, then insert it into your DOM and start it.
-
-If the widget is not needed anymore (because it's transient), simply terminate
-it:
-
-.. code-block:: javascript
-
-    my_widget.destroy();
-
-will unbind all DOM events, remove the widget's content from the DOM and
-destroy all widget data.
-
-.. [0] not all DOM events are compatible with events delegation
-
-.. _.appendTo():
-    http://api.jquery.com/appendTo/
-
-.. _.prependTo():
-    http://api.jquery.com/prependTo/
-
-.. _.insertAfter():
-    http://api.jquery.com/insertAfter/
-
-.. _.insertBefore():
-    http://api.jquery.com/insertBefore/
-
-.. _event delegation:
-    http://api.jquery.com/delegate/
-
-.. _Backbone's setElement:
-    http://backbonejs.org/#View-setElement
-
-.. _Backbone's delegateEvents:
-    http://backbonejs.org/#View-delegateEvents
-
diff --git a/logging.json b/logging.json
deleted file mode 100644 (file)
index 1f982a6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-    "version": 1,
-    "formatters": {
-        "simple": {
-            "format": "[%(asctime)s] %(levelname)s:%(name)s:%(message)s"
-        }
-    },
-    "handlers": {
-        "console": {
-            "class": "logging.StreamHandler",
-            "level": "DEBUG",
-            "formatter": "simple",
-            "stream": "ext://sys.stdout"
-        }
-    },
-    "loggers": {
-        "web": {
-        },
-        "web.common.openerplib": {
-            "level": "INFO"
-        }
-    },
-    "root": {
-        "level": "DEBUG",
-        "handlers": ["console"]
-    }
-}
diff --git a/openerp-web b/openerp-web
deleted file mode 100755 (executable)
index 7e536a9..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-#!/usr/bin/env python
-import json
-import logging
-import logging.config
-import optparse
-import os
-import sys
-import tempfile
-
-import werkzeug.serving
-import werkzeug.contrib.fixers
-
-optparser = optparse.OptionParser()
-optparser.add_option("-s", "--session-path", dest="session_storage",
-                     default=os.path.join(tempfile.gettempdir(), "oe-sessions"),
-                     help="Directory used for session storage", metavar="DIR")
-optparser.add_option("--server-host", dest="server_host",
-                     default='127.0.0.1', help="OpenERP server hostname", metavar="HOST")
-optparser.add_option("--server-port", dest="server_port", default=8069,
-                     help="OpenERP server port", type="int", metavar="NUMBER")
-optparser.add_option("--db-filter", dest="dbfilter", default='.*',
-                     help="Filter listed databases", metavar="REGEXP")
-optparser.add_option('--addons-path', dest='addons_path', default=[], action='append',
-                    help="Path to addons directory", metavar="PATH")
-optparser.add_option('--load', dest='server_wide_modules', default=['web'], action='append',
-                    help="Load an additional module before login (by default only 'web' is loaded)", metavar="MODULE")
-
-server_options = optparse.OptionGroup(optparser, "Server configuration")
-server_options.add_option("-p", "--port", dest="socket_port", default=8002,
-                          help="listening port", type="int", metavar="NUMBER")
-server_options.add_option('--reloader', dest='reloader',
-                          default=False, action='store_true',
-                          help="Reload application when python files change")
-server_options.add_option('--no-serve-static', dest='serve_static',
-                          default=True, action='store_false',
-                          help="Do not serve static files via this server")
-server_options.add_option('--multi-threaded', dest='threaded',
-                          default=False, action='store_true',
-                          help="Spawn one thread per HTTP request")
-server_options.add_option('--proxy-mode', dest='proxy_mode',
-                          default=False, action='store_true',
-                          help="Enable correct behavior when behind a reverse proxy")
-optparser.add_option_group(server_options)
-
-logging_opts = optparse.OptionGroup(optparser, "Logging")
-logging_opts.add_option("--log-level", dest="log_level", type="choice",
-                        default='debug', help="Global logging level", metavar="LOG_LEVEL",
-                        choices=['debug', 'info', 'warning', 'error', 'critical'])
-logging_opts.add_option("--log-config", dest="log_config", default=os.path.join(os.path.dirname(__file__), "logging.json"),
-                        help="Logging configuration file", metavar="FILE")
-optparser.add_option_group(logging_opts)
-
-testing_opts = optparse.OptionGroup(optparser, "Testing")
-testing_opts.add_option('--test-mode', dest='test_mode',
-                        action='store_true', default=False,
-                        help="Starts test mode, which provides a few"
-                             " (utterly unsafe) APIs for testing purposes and"
-                             " sets up a special connector which always raises"
-                             " errors on tentative server access. These errors"
-                             " serialize RPC query information (service,"
-                             " method, arguments list) in the fault_code"
-                             " attribute of the error object returned to the"
-                             " client. This lets javascript code assert the" \
-                             " XMLRPC consequences of its queries.")
-optparser.add_option_group(testing_opts)
-
-if __name__ == "__main__":
-    (options, args) = optparser.parse_args(sys.argv[1:])
-
-    if not options.addons_path:
-        path_root = os.path.dirname(os.path.abspath(__file__))
-        path_addons = os.path.join(path_root, 'addons')
-        if os.path.exists(path_addons):
-            options.addons_path.append(path_addons)
-
-    options.addons_path = [
-        path[:-1] if path[-1] in r'\/' else path
-        for path in options.addons_path
-        if os.path.exists(path)
-    ]
-
-    for path_addons in options.addons_path:
-        if path_addons not in sys.path:
-            sys.path.insert(0, path_addons)
-
-    try:
-        import web.common.http
-    except ImportError:
-        optparser.error('Error Importing base web module. Check correctness of --addons-path.')
-
-    options.backend =  'xmlrpc'
-    os.environ["TZ"] = "UTC"
-
-    if options.test_mode:
-        import web.test_support
-        import web.test_support.controllers
-        options.connector = web.test_support.TestConnector()
-        logging.getLogger('werkzeug').setLevel(logging.WARNING)
-
-    if sys.version_info >= (2, 7) and os.path.exists(options.log_config):
-        with open(options.log_config) as file:
-            dct = json.load(file)
-        logging.config.dictConfig(dct)
-        logging.getLogger().setLevel(getattr(logging, options.log_level.upper()))
-    else:
-        logging.basicConfig(level=getattr(logging, options.log_level.upper()))
-
-    app = web.common.http.Root(options)
-
-    if options.proxy_mode:
-        app = werkzeug.contrib.fixers.ProxyFix(app)
-
-    werkzeug.serving.run_simple(
-        '0.0.0.0', options.socket_port, app,
-        use_reloader=options.reloader, threaded=options.threaded)
-
diff --git a/openerp-web.cfg b/openerp-web.cfg
deleted file mode 100644 (file)
index 424d1a8..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[global]
-
-
diff --git a/setup.py b/setup.py
deleted file mode 100755 (executable)
index 18d3410..0000000
--- a/setup.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#!/usr/bin/env python
-# -*- 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 glob, os, re, setuptools, sys
-from os.path import join, isfile
-
-# List all data files
-def data():
-    files = []
-    for root, dirnames, filenames in os.walk('openerp'):
-        for filename in filenames:
-            if not re.match(r'.*(\.pyc|\.pyo|\~)$',filename):
-                files.append(os.path.join(root, filename))
-    d = {}
-    for v in files:
-        k=os.path.dirname(v)
-        if k in d:
-            d[k].append(v)
-        else:
-            d[k]=[v]
-    r = d.items()
-    if os.name == 'nt':
-        r.append(("Microsoft.VC90.CRT", glob.glob('C:\Microsoft.VC90.CRT\*.*')))
-
-    import babel
-    r.append(("localedata",
-              glob.glob(os.path.join(os.path.dirname(babel.__file__), "localedata" , '*'))))
-
-    return r
-
-def gen_manifest():
-    file_list="\n".join(data())
-    open('MANIFEST','w').write(file_list)
-
-if os.name == 'nt':
-    sys.path.append("C:\Microsoft.VC90.CRT")
-
-def py2exe_options():
-    if os.name == 'nt':
-        import py2exe
-        return {
-            "console" : [ { "script": "openerp-server", "icon_resources": [(1, join("install","openerp-icon.ico"))], }],
-            'options' : {
-                "py2exe": {
-                    "skip_archive": 1,
-                    "optimize": 2,
-                    "dist_dir": 'dist',
-                    "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber", "vobject", "xml", "xml.dom", "yaml", ],
-                    "excludes" : ["Tkconstants","Tkinter","tcl"],
-                }
-            }
-        }
-    else:
-        return {}
-
-execfile(join(os.path.dirname(__file__), 'openerp', 'release.py'))
-
-setuptools.setup(
-      name             = 'openerp',
-      version          = version,
-      description      = description,
-      long_description = long_desc,
-      url              = url,
-      author           = author,
-      author_email     = author_email,
-      classifiers      = filter(None, classifiers.split("\n")),
-      license          = license,
-      scripts          = ['openerp-server'],
-      data_files       = data(),
-      packages         = setuptools.find_packages(),
-      dependency_links = ['http://download.gna.org/pychart/'],
-      #include_package_data = True,
-      install_requires = [
-          'pychart',
-          'babel',
-          'docutils',
-          'feedparser',
-          'gdata',
-          'lxml < 3',
-          'mako',
-          'psutil',
-          'psycopg2',
-          'pydot',
-          'python-dateutil < 2',
-          'python-ldap',
-          'python-openid',
-          'pytz',
-          'pywebdav',
-          'pyyaml',
-          'reportlab',
-          'simplejson',
-          'vatnumber',
-          'vobject',
-          'werkzeug',
-          'xlwt',
-          'zsi',
-      ],
-      extras_require = {
-          'SSL' : ['pyopenssl'],
-      },
-      **py2exe_options()
-)
-
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: